This file is indexed.

/usr/include/hpptools/logger.hpp is in libhpptools-dev 1.1.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/// @author    Matei David, Ontario Institute for Cancer Research
/// @version   1.0
/// @date      2013-2015
/// @copyright MIT Public License
///
/// Logger mechanism.
///
/// Properties:
/// - thread-safe, non-garbled output (uses c++11's thread_local)
/// - customizable ostream sink. by default, uses std::clog
///
/// Exports:
/// - "LOG" macro (takes 1, 2, or 3 arguments, see below)
/// - "logger" namespace
/// - "logger::level" enum
/// - "logger::Logger" class
///
/// To use:
/// - In source code, use:
///
///     LOG(info) << "hello" << endl;
///     // or 
///     LOG("main", info) << "hello" << endl;
///     // or 
///     LOG("main", info, sink_os) << "hello" << endl;
///
///   Here, "main" is the facility (a string) and info is the message level.
///   Note that "logger" is a macro which knows how to look up the name info
///   inside logger namespace. The macro introduces C++ code equivalent to:
///
///     if (...message should be ignored...) then; else sink_os
///
///   NOTE: As with assert(), the code in the output stream following the
///   LOG() macro will ***not be executed*** if the log level of the
///   facility is higher than the level of the message.
///
/// - To set the default log level (for unspecified facilities):
///
///     logger::Logger::set_default_level(logger::Logger::level_from_string(s));
///
/// - To set the log level for the "main" facility:
///
///     logger::Logger::set_facility_level("main", logger::Logger::level_from_string(s));
///
/// - To parse a log facility level setting in the form "[<facility>:]<level>":
///
///     logger::Logger::set_level_from_option("alt:debug1", &cerr);
///
/// - By using these functions, one can set log levels using command-line
///   parameters and achieve dynamic log level settings without recompiling.

#ifndef __LOGGER_HPP
#define __LOGGER_HPP

#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <iostream>
#include <mutex>

namespace logger
{

// log levels
enum level
{
    error = 0,
    warning,
    info,
    debug,
    debug1,
    debug2
};

class Logger
    : public std::ostringstream
{
public:
    // Constructor: initialize buffer.
    Logger(const std::string& facility, level msg_level,
           const std::string& file_name, unsigned line_num, const std::string& func_name,
           std::ostream& os = std::clog)
        : _os_p(&os)
    {
        *this << "= " << facility << "." << int(msg_level)
              << " " << file_name << ":" << line_num
              << " " << func_name << " ";
    }
    // Destructor: dump buffer to output.
    ~Logger()
    {
        _os_p->write(this->str().c_str(), this->str().size());
    }
    // Produce l-value for output chaining.
    std::ostream& l_value() { return *this; }

    // static methods for setting and getting facility log levels.
    static level get_default_level()
    {
        return default_level();
    }
    static void set_default_level(level l)
    {
        static std::mutex m;
        std::lock_guard< std::mutex > lg(m);
        default_level() = l;
    }
    static void set_default_level(int l)
    {
        set_default_level(get_level(l));
    }
    static void set_default_level(const std::string& s)
    {
        set_default_level(get_level(s));
    }
    static level get_facility_level(const std::string& facility)
    {
        return (facility_level_map().count(facility) > 0?
                facility_level_map().at(facility) : get_default_level());
    }
    static void set_facility_level(const std::string& facility, level l)
    {
        static std::mutex m;
        std::lock_guard< std::mutex > lg(m);
        facility_level_map()[facility] = l;
    }
    static void set_facility_level(const std::string& facility, int l)
    {
        set_facility_level(facility, get_level(l));
    }
    static void set_facility_level(const std::string& facility, const std::string& s)
    {
        set_facility_level(facility, get_level(s));
    }
    // static methods for setting log levels from command-line options
    static void set_level_from_option(const std::string& l, std::ostream* os_p = nullptr)
    {
        size_t i = l.find(':');
        if (i == std::string::npos)
        {
            set_default_level(l);
            if (os_p)
            {
                (*os_p) << "set default log level to: "
                        << static_cast< int >(Logger::get_default_level()) << std::endl;
            }
        }
        else
        {
            set_facility_level(l.substr(0, i), l.substr(i + 1));
            if (os_p)
            {
                (*os_p) << "set log level of '" << l.substr(0, i) << "' to: "
                        << static_cast< int >(Logger::get_facility_level(l.substr(0, i))) << std::endl;
            }
        }
    }
    static void set_levels_from_options(const std::vector< std::string >& v, std::ostream* os_p = nullptr)
    {
        for (const auto& l : v)
        {
            set_level_from_option(l, os_p);
        }
    }
    // public static utility functions (used by LOG macro)
    static level get_level(level l) { return l; }
    static level get_level(int i) { return static_cast< level >(i); }
    static level get_level(const std::string& s) { return level_from_string(s); }
    // public static member (used by LOG macro)
    static level& thread_local_last_level()
    {
        static thread_local level _last_level = error;
        return _last_level;
    }
private:
    // sink for this Logger object
    std::ostream* _os_p;

    // private static data members
    static level& default_level()
    {
        static level _default_level = error;
        return _default_level;
    }
    static std::map< std::string, level >& facility_level_map()
    {
        static std::map< std::string, level > _facility_level_map;
        return _facility_level_map;
    }
    // private static utility functions
    static level level_from_string(const std::string& s)
    {
        std::istringstream iss(s + "\n");
        int tmp_int = -1;
        iss >> tmp_int;
        if (iss.good())
        {
            return level(tmp_int);
        }
        else
        {
            if (s == "error") return logger::error;
            else if (s == "warning") return logger::warning;
            else if (s == "info") return logger::info;
            else if (s == "debug") return logger::debug;
            else if (s == "debug1") return logger::debug1;
            else if (s == "debug2") return logger::debug2;
            else
            {
                std::cerr << "could not parse log level: " << s << "\n";
                std::exit(1);
            }
        }
    }
}; // class Logger

} //namespace logger

#define __FILENAME__ (std::string(__FILE__).find('/') != std::string::npos? std::string(__FILE__).substr(std::string(__FILE__).rfind('/') + 1) : std::string(__FILE__))

/**
 * LOG macro
 *
 * Synopsis:
 *   LOG(facility, level_spec, sink) << message
 *   LOG(facility, level_spec) << message
 *   LOG(level_spec) << message
 *
 *   `facility`   : string
 *   `level_spec` : integer, string, or logger level
 *   `sink`       : sink ostream
 * 
 * Log to `facility` at logger level `level_spec` and dump output to `sink`.
 * If sink is omitted, it defaults to std::clog.
 * If `facility` is omitted (logger has single argument), the macro LOG_FACILITY
 * is used instead, defaulting to "main".
 */

#define __LOG_3(facility, level_spec, sink)                                   \
    { using namespace logger; logger::Logger::thread_local_last_level() = logger::Logger::get_level(level_spec); } \
    if (logger::Logger::thread_local_last_level() > logger::Logger::get_facility_level(facility)) ; \
    else logger::Logger(facility, logger::Logger::thread_local_last_level(), __FILENAME__, __LINE__, __func__, sink).l_value()

#define __LOG_2(facility, level_spec)                                   \
    { using namespace logger; logger::Logger::thread_local_last_level() = logger::Logger::get_level(level_spec); } \
    if (logger::Logger::thread_local_last_level() > logger::Logger::get_facility_level(facility)) ; \
    else logger::Logger(facility, logger::Logger::thread_local_last_level(), __FILENAME__, __LINE__, __func__).l_value()

#define __LOG_1(level_spec) \
    __LOG_2(LOG_FACILITY, level_spec)

// we need 2-level indirection in order to trigger expansion after token pasting
// http://stackoverflow.com/questions/1597007/creating-c-macro-with-and-line-token-concatenation-with-positioning-macr
// http://stackoverflow.com/a/11763196/717706
#ifdef WIN32
#define __EXPAND(...) __VA_ARGS__
#define __LOG_aux2(N, ...) __EXPAND(__LOG_ ## N (__VA_ARGS__))
#else
#define __LOG_aux2(N, ...) __LOG_ ## N (__VA_ARGS__)
#endif

#define __LOG_aux1(N, ...) __LOG_aux2(N, __VA_ARGS__)

#define __NARGS_AUX(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) _9

#ifdef WIN32
#define __NARGS(...) __EXPAND(__NARGS_AUX(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0))
#else
#define __NARGS(...) __NARGS_AUX(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0)
#endif

#ifndef LOG_FACILITY
#define LOG_FACILITY "main"
#endif

#define LOG(...) __LOG_aux1(__NARGS(__VA_ARGS__), __VA_ARGS__)

#endif

#ifdef SAMPLE_LOGGER

/*

Compile:

g++ -std=c++11 -D SAMPLE_LOGGER -x c++ logger.hpp -o sample-logger

Run:
./sample-logger info
./sample-logger info alt:debug1

*/

using namespace std;

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        cerr << "Use: " << argv[0] << " <log_level_setting> ..." << endl
             << "The program sends 5 log messages with decreasing priority (0=highest, 4=lowest)" << endl
             << "to 2 facilities \"main\" and \"alt\". Command-line arguments are interpreted as" << endl
             << "log facility level settings in the form [<facility>:]<level>." << endl;
        return EXIT_FAILURE;
    }
    for (int i = 1; i < argc; ++i)
    {
        cerr << "processing argument [" << argv[i] << "]" << endl;
        logger::Logger::set_level_from_option(argv[i], &cerr);
    }
    const vector< string > level_name{ "error", "warning", "info", "debug", "debug1", "debug2" };
    for (int l = 0; l < 5; ++l)
    {
        LOG(level_name[l]) << "message at level " << l << " (" << level_name[l]
                           << ") for facility main" << endl;
        LOG("alt", l) << "message at level " << l << " (" << level_name[l]
                      << ") for facility alt" << endl;
    }
}

#endif