~ubuntu-branches/debian/sid/antpm/sid

« back to all changes in this revision

Viewing changes to .pc/02-try-fixing-FTBFS-under-hurd-i386-kfreebsd-amd64-kfre/src/Log.hpp

  • Committer: Package Import Robot
  • Author(s): Christian Perrier, RALOVICH, Kristof
  • Date: 2014-04-08 06:57:24 UTC
  • Revision ID: package-import@ubuntu.com-20140408065724-01zptgrvkpc9o9e5
Tags: 1.16-2
* Team upload

[ RALOVICH, Kristof ]
* fix kFreebsd,Hurd FTBFS
* don't provide garmin-ant-downloader package for now
* rename garmin-ant-downloader to antpm-garmin-ant-downloader
* build antpm-dbg package too

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; coding: utf-8-unix -*-
 
2
// ***** BEGIN LICENSE BLOCK *****
 
3
//////////////////////////////////////////////////////////////////////////
 
4
// Copyright (c) 2011-2014 RALOVICH, Kristóf                            //
 
5
//                                                                      //
 
6
// This program is free software; you can redistribute it and/or modify //
 
7
// it under the terms of the GNU General Public License as published by //
 
8
// the Free Software Foundation; either version 3 of the License, or    //
 
9
// (at your option) any later version.                                  //
 
10
//                                                                      //
 
11
// This program is distributed in the hope that it will be useful,      //
 
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of       //
 
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        //
 
14
// GNU General Public License for more details.                         //
 
15
//                                                                      //
 
16
//////////////////////////////////////////////////////////////////////////
 
17
// ***** END LICENSE BLOCK *****
 
18
 
 
19
#pragma once
 
20
 
 
21
#include "LazySingleton.hpp"
 
22
#include <cstdarg>
 
23
#include <fstream>
 
24
#include <list>
 
25
#include <memory>
 
26
#include <ostream>
 
27
#include <sstream>
 
28
#ifdef _MSC_VER
 
29
# include <crtdbg.h>
 
30
# include <io.h>
 
31
#endif
 
32
#ifdef __linux__
 
33
# include <unistd.h>
 
34
#endif
 
35
#include <iostream>
 
36
#include <ctime>
 
37
 
 
38
 
 
39
namespace antpm
 
40
{
 
41
  enum LogLevel
 
42
  {
 
43
    LOG_RAW,             //< dont insert any prefix
 
44
    LOG_ERR,             //< runtime error
 
45
    LOG_WARN,            //< suppressable runtime error
 
46
    LOG_INF,             //< runtime information
 
47
    LOG_DBG,             //< debug info, mainly for developers
 
48
    LOG_DBG2,            //< more debug info
 
49
    LOG_DBG3             //< even more debug info (function trace, )
 
50
  };
 
51
 
 
52
#ifndef NDEBUG
 
53
# define psoLogMaxLogLevel antpm::LOG_DBG3
 
54
#else
 
55
# define psoLogMaxLogLevel antpm::LOG_DBG3
 
56
#endif
 
57
 
 
58
  inline
 
59
  const char*
 
60
  logLevelToString(const LogLevel& level)
 
61
  {
 
62
    switch(level)
 
63
    {
 
64
      case LOG_RAW:             return "";
 
65
      case LOG_ERR:             return "ERROR: ";
 
66
      case LOG_WARN:            return "WW: ";
 
67
      case LOG_INF:             return "II: ";
 
68
      case LOG_DBG:             return "DBG: ";
 
69
      case LOG_DBG2:            return "DBG: ";
 
70
      case LOG_DBG3:            return "DBG: ";
 
71
      default:                  return 0;
 
72
    }
 
73
  }
 
74
 
 
75
  inline
 
76
  std::ostream&
 
77
  operator<< (std::ostream& left, const LogLevel level)
 
78
  {
 
79
    return left << logLevelToString(level);
 
80
  }
 
81
  
 
82
  extern const std::string getVersionString();
 
83
 
 
84
 
 
85
  /**
 
86
   * Encapsulates a series of C++ style (<<) writes to a log in a
 
87
   * transactional manner.
 
88
   */
 
89
  template <typename T>
 
90
  class LogLine
 
91
  {
 
92
  public:
 
93
    inline LogLine(const LogLevel& level = LOG_INF) : _level(level) {}
 
94
    inline virtual             ~LogLine()           { T::instance()->print(_level, _oss.str()); }
 
95
    inline std::ostringstream& get()                { return _oss; }
 
96
  private:
 
97
    LogLine(const LogLine&);
 
98
    LogLine& operator= (const LogLine&);
 
99
  protected:
 
100
    const LogLevel     _level;
 
101
    std::ostringstream _oss;
 
102
  };
 
103
 
 
104
  /**
 
105
   *
 
106
   */
 
107
  class Log
 
108
    : public ClassInstantiator<Log>
 
109
    , public LazySingleton<Log, Log>
 
110
  {
 
111
  protected:
 
112
    inline Log(const char* logFileName = NULL);
 
113
  public:
 
114
    inline virtual ~Log();
 
115
 
 
116
#ifdef __GNUC__
 
117
    inline virtual int lprintf2(const LogLevel level,
 
118
                                const char* format,
 
119
                                ...) __attribute__ ((format (printf, 3, 4)));
 
120
#else // !__GNUC__
 
121
    inline virtual int lprintf2(const LogLevel level,
 
122
                                const char* format,
 
123
                                ...);
 
124
#endif // !__GNUC__
 
125
    inline virtual int vlprintf(const LogLevel level,
 
126
                                const char* format,
 
127
                                ::va_list args);
 
128
    inline virtual int print(const LogLevel level, const std::string& msg);
 
129
 
 
130
    inline virtual void addSink(std::ostream& os);
 
131
    inline virtual void delSink(std::ostream& os);
 
132
 
 
133
    inline virtual const LogLevel& getLogReportingLevel() const;
 
134
    inline virtual void            setLogReportingLevel(const LogLevel& logReportingLevel);
 
135
  protected:
 
136
    inline int writeStreams(const std::string& s);
 
137
  /**
 
138
   * getTimeStamp()
 
139
   */
 
140
  inline
 
141
  const std::string
 
142
  getTimeStamp()
 
143
  {
 
144
    ::time_t ltime;
 
145
    ::time(&ltime);
 
146
    char tmp[26];
 
147
    tmp[25] = '\0';
 
148
#ifdef _MSC_VER
 
149
    ::ctime_s(tmp, 26, &ltime);
 
150
#else
 
151
    ::ctime_r(&ltime, tmp);
 
152
#endif
 
153
    return std::string(tmp);
 
154
  }
 
155
  protected:
 
156
    typedef std::list<std::ostream*> SinkList;
 
157
    std::ofstream _ofs;
 
158
    SinkList      _sinks;
 
159
    LogLevel      _logReportingLevel;
 
160
 
 
161
 
 
162
    friend class antpm::ClassInstantiator<Log>;
 
163
  };
 
164
 
 
165
  Log::Log(const char* logFileName)
 
166
    : _logReportingLevel(psoLogMaxLogLevel)
 
167
  {
 
168
    std::ios_base::sync_with_stdio(false);
 
169
 
 
170
    if(!logFileName)
 
171
    {
 
172
      return;
 
173
    }
 
174
 
 
175
    // rotate previous log file
 
176
    if(::access(logFileName, 0x00) != -1)
 
177
    {
 
178
      std::string old = std::string(logFileName) + std::string(".old");
 
179
      ::remove(old.c_str());
 
180
      ::rename(logFileName, old.c_str());
 
181
    }
 
182
 
 
183
    _ofs.open(logFileName, std::ios::out | std::ios::trunc);
 
184
    if(!_ofs.is_open())
 
185
    {
 
186
      std::cerr << LOG_ERR << __FUNCTION__ << ": Unable to open log file \""
 
187
                << logFileName << "\" at " << getTimeStamp() << std::endl;
 
188
    }
 
189
    else
 
190
    {
 
191
      addSink(_ofs);
 
192
 
 
193
      std::string ts(getTimeStamp());
 
194
      this->lprintf2(LOG_INF,
 
195
                     "%s(): Log file \"%s\" opened at %s",
 
196
                     __FUNCTION__,
 
197
                     logFileName,
 
198
                     ts.c_str());
 
199
      std::string v(antpm::getVersionString());
 
200
      this->lprintf2(LOG_INF,
 
201
                     "%s\n",
 
202
                     v.c_str());
 
203
      this->lprintf2(LOG_RAW, "logging level: %d\n", this->_logReportingLevel);
 
204
    }
 
205
  }
 
206
 
 
207
  Log::~Log()
 
208
  {
 
209
    if(_ofs.is_open())
 
210
    {
 
211
      this->lprintf2(LOG_INF,
 
212
                     "%s(): Closing log file at %s",
 
213
                     __FUNCTION__,
 
214
                     getTimeStamp().c_str());
 
215
    }
 
216
  }
 
217
 
 
218
  int
 
219
  Log::lprintf2(const LogLevel level,
 
220
                const char* format,
 
221
                ...)
 
222
  {
 
223
    va_list args;
 
224
    va_start(args, format);
 
225
    int chars = this->vlprintf(level,
 
226
                               format,
 
227
                               args);
 
228
    va_end(args);
 
229
    return chars;
 
230
  }
 
231
 
 
232
  int
 
233
  Log::vlprintf(const LogLevel level,
 
234
                const char* format,
 
235
                ::va_list args)
 
236
  {
 
237
    std::string s(logLevelToString(level));
 
238
 
 
239
    char msg[1023+1];
 
240
    msg[1023] = '\0';
 
241
    vsnprintf(msg,
 
242
              1024,
 
243
              format,
 
244
              args);
 
245
    s.append(msg);
 
246
 
 
247
#ifdef __PSO_BUILD_WIN__
 
248
    _RPT0(_CRT_WARN, s.c_str());
 
249
#endif
 
250
 
 
251
    return writeStreams(s);
 
252
  }
 
253
 
 
254
  int
 
255
  Log::print(const LogLevel level, const std::string& msg)
 
256
  {
 
257
    const std::string s(std::string(logLevelToString(level)) + msg);
 
258
 
 
259
#ifdef _MSC_VER
 
260
    _RPT0(_CRT_WARN, s.c_str());
 
261
#endif
 
262
 
 
263
    return writeStreams(s);
 
264
  }
 
265
 
 
266
  void
 
267
  Log::addSink(std::ostream& os)
 
268
  {
 
269
    _sinks.push_back(&os);
 
270
    _sinks.unique();
 
271
  }
 
272
 
 
273
  void
 
274
  Log::delSink(std::ostream& os)
 
275
  {
 
276
    _sinks.remove(&os);
 
277
  }
 
278
 
 
279
  const LogLevel&
 
280
  Log::getLogReportingLevel() const
 
281
  {
 
282
    return _logReportingLevel;
 
283
  }
 
284
 
 
285
  void
 
286
  Log::setLogReportingLevel(const LogLevel& logReportingLevel)
 
287
  {
 
288
    _logReportingLevel = logReportingLevel;
 
289
    this->lprintf2(LOG_RAW, "logging level: %d\n", this->_logReportingLevel);
 
290
  }
 
291
 
 
292
  int
 
293
  Log::writeStreams(const std::string& s)
 
294
  {
 
295
//     static int c = 0;
 
296
//     c++;
 
297
//     if(!(c % 8))
 
298
//     {
 
299
//       c = 0;
 
300
//     }
 
301
    for(SinkList::iterator i = _sinks.begin(); i != _sinks.end(); i++)
 
302
    {
 
303
      (*i)->write(s.c_str(), s.length());
 
304
//       if(!c)
 
305
//       {
 
306
      (*i)->flush();
 
307
//       }
 
308
    }
 
309
 
 
310
    return (int)s.length();
 
311
  }
 
312
 
 
313
//  template<>
 
314
//  inline
 
315
//  Log*
 
316
//  ClassInstantiator<Log>::instantiate()
 
317
//  {
 
318
//    return new Log("antpm.txt");
 
319
//  }
 
320
 
 
321
//  template<>
 
322
//  template<>
 
323
//  inline
 
324
//  Log*
 
325
//  ClassInstantiator<Log>::instantiate<const char*>(const char* p1)
 
326
//  {
 
327
//    return new Log(p1);
 
328
//  }
 
329
 
 
330
  /**
 
331
   * Start a log line.
 
332
   */
 
333
#ifdef _MSC_VER
 
334
#define lprintf(level, format, ...)                                 \
 
335
  if(level > psoLogMaxLogLevel)                                     \
 
336
  {}                                                                \
 
337
  else if(level > antpm::Log::instance()->getLogReportingLevel())     \
 
338
  {}                                                                \
 
339
  else antpm::Log::instance()->lprintf2(level, format, __VA_ARGS__)
 
340
#else // GCC
 
341
#define lprintf(level, format, ...)                                 \
 
342
  if(level > psoLogMaxLogLevel)                                     \
 
343
  {}                                                                \
 
344
  else if(level > antpm::Log::instance()->getLogReportingLevel())     \
 
345
  {}                                                                \
 
346
  else antpm::Log::instance()->lprintf2(level, format, ##__VA_ARGS__)
 
347
#endif
 
348
 
 
349
#define LOG(level)                                             \
 
350
  if(level > psoLogMaxLogLevel)                                   \
 
351
  {}                                                              \
 
352
  else if(level > antpm::Log::instance()->getLogReportingLevel())   \
 
353
  {}                                                              \
 
354
  else antpm::LogLine<antpm::Log>(level).get()
 
355
 
 
356
  /**
 
357
   * Start a log line beginning with the name of the calling function.
 
358
   */
 
359
#define LOGT(level)                                              \
 
360
  if(level > psoLogMaxLogLevel)                                     \
 
361
  {}                                                                \
 
362
  else if(level > antpm::Log::instance()->getLogReportingLevel())     \
 
363
  {}                                                                \
 
364
  else antpm::LogLine<antpm::Log>(level).get()                          \
 
365
         << __FILE__ << ":" << __LINE__ << " "                      \
 
366
         << __FUNCTION__ << "(): "
 
367
 
 
368
//#define logt(level) psoLogt(level)
 
369
 
 
370
//#define log(level) psoLog(level)
 
371
 
 
372
}