/* $Id: log.cc,v 1.8 2003/09/27 21:31:04 atterer Exp $ -*- C++ -*- __ _ |_) /| Copyright (C) 2003 | richard@ | \/¯| Richard Atterer | atterer.net ¯ '` ¯ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2. See the file COPYING for details. Logfile / debugging output */ #include #include #include #include //______________________________________________________________________ /* Static head of linked list of Logger objects in different compilation units. Traversed e.g. to enable/disable specific units' messages with the --debug command line switch. */ Logger* Logger::list = 0; Logger msg("general"); Logger::Logger(const char* unitName, bool enabled) : unitNameVal(unitName), unitNameLen(strlen(unitName)), enabledVal(enabled), next(list) { list = this; } bool Logger::setEnabled(const char* unitName, bool enable) { Logger* l = list; if (unitName == 0) { // Change all loggers while (l != 0) { l->enabledVal = enable; l = l->next; } return true; } // Only change matching Loggers bool result = false; // Not found while (l != 0) { if (strcmp(unitName, l->unitNameVal) == 0) { l->enabledVal = enable; result = true; } l = l->next; } return result; } void Logger::defaultPut(const string& unitName, unsigned char unitNameLen, const char* format, int args, const Subst arg[]) { cerr << unitName << ':'; if (unitNameLen < 15) cerr << " " + unitNameLen; cerr << Subst::subst(format, args, arg) << endl; } Logger::OutputFunction* Logger::output = &defaultPut; //______________________________________________________________________ /* The value of the --debug cmd line option is either missing (empty) or a comma-separated list of words (we also allow spaces for the fun of it). Each word can be preceded by a '~' for negation (i.e. disable debug messages rather than enable them). The word is the name of a compilation unit, or one of the special values "all" or "help". */ void Logger::scanOptions(const string& s, const char* binName) { unsigned i = 0; string word; bool enable; unsigned len = s.length(); while (i < len) { word.erase(); enable = true; while ((s[i] == '~' || s[i] == ' ') && i < len) { if (s[i] == '~') enable = !enable; ++i; } while (s[i] != ' ' && s[i] != ',' && i < len) { word += s[i]; ++i; } while ((s[i] == ',' || s[i] == ' ') && i < len) ++i; if (word == "all") { // Argument "all" - all units Logger::setEnabled(0, enable); } else if (word != "help") { // Other word - the name of a unit // Do not fail if unit not found - some units are only there with DEBUG if (!Logger::setEnabled(word.c_str(), enable)) { cerr << subst(_("%1: Unit `%2' not found while scanning --debug " "argument"), binName, word) << endl; throw Cleanup(3); } } else { // Argument "help" - print list of units Logger* l = Logger::enumerate(); cerr << _( "By default, debug output is disabled except for `assert'. Argument\n" "to --debug is a comma-separated list of unit names, or `all' for\n" "all units. Just `--debug' is equivalent to`--debug=all'. Output for\n" "the listed units is enabled, precede a name with `~' to disable it.\n" "Registered units:"); while (l != 0) { cerr << ' ' << l->name(); l = Logger::enumerate(l); } cerr << endl; throw Cleanup(3); } } }