FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
logger.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2008 by the FIFE team *
3  * http://www.fifengine.de *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library 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 GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <algorithm>
24 #include <iomanip>
25 #include <fstream>
26 
27 // 3rd party library includes
28 #include <SDL.h>
29 
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 // #include "guichan_addon/console.h"
35 #include "modules.h"
36 #include "logger.h"
37 #include "util/base/exception.h"
38 
39 // define the module info relationships structure here, begin
40 struct ModuleInfo {
41  logmodule_t module;
42  logmodule_t parent;
43  std::string name;
44 };
45 MODULE_INFO_RELATIONSHIPS
46 // end
47 
48 namespace FIFE {
49  LogManager* LogManager::m_instance = NULL;
50 
51  Logger::Logger(logmodule_t module):
52  m_module(module) {
53  }
54 
56  }
57 
58  void Logger::log(LogManager::LogLevel level, const std::string& msg) {
59  LogManager::instance()->log(level, m_module, msg);
60  }
61 
62  void Logger::log(LogManager::LogLevel level, const LMsg& msg) {
63  LogManager::instance()->log(level, m_module, msg.str);
64  }
65 
67  if (!m_instance) {
68  m_instance = new LogManager();
69  }
70  return m_instance;
71  }
72 
74  delete m_instance;
75  }
76 
77 
78  void LogManager::log(LogLevel level, logmodule_t module, const std::string& msg) {
79  if (level < m_level) {
80  return;
81  }
82  if (!isVisible(module)) {
83  return;
84  }
85  std::string lvlstr = "";
86  switch (level) {
87  case LEVEL_DEBUG: lvlstr = "dbg";
88  break;
89 
90  case LEVEL_LOG: lvlstr = "log";
91  break;
92 
93  case LEVEL_WARN: lvlstr = "warn";
94  break;
95 
96  case LEVEL_ERROR: lvlstr = "error";
97  break;
98 
99  case LEVEL_PANIC: lvlstr = "panic";
100  break;
101 
102  default: lvlstr = "error";
103  break;
104  }
105  if (m_logtoprompt) {
106  std::cout << moduleInfos[module].name << ": " << lvlstr << ": " << msg << std::endl;
107  }
108  if (m_logtofile) {
109  *m_logfile << moduleInfos[module].name << ": " << lvlstr << ": " << msg << std::endl;
110  }
111  if (level == LEVEL_PANIC) {
112  abort();
113  }
114  }
115 
117  m_level = level;
118  }
119 
121  return m_level;
122  }
123 
124  void LogManager::addVisibleModule(logmodule_t module) {
125  validateModule(module);
126  int ind = static_cast<int>(module);
127  m_modules[ind] = true;
128  if (moduleInfos[ind].parent != LM_CORE) {
129  addVisibleModule(moduleInfos[ind].parent);
130  }
131  }
132 
133  void LogManager::removeVisibleModule(logmodule_t module) {
134  validateModule(module);
135  m_modules[module] = false;
136  }
137 
139  for (int i = 0; i < LM_MODULE_MAX; i++) {
140  m_modules[i] = false;
141  }
142  }
143 
144  void LogManager::setLogToPrompt(bool log_to_promt) {
145  m_logtoprompt = log_to_promt;
146  }
147 
149  return m_logtoprompt;
150  }
151 
152  void LogManager::setLogToFile(bool logtofile) {
153  if(logtofile){
154  m_logfile = new std::ofstream("fife.log");
155  }
156  else {
157  if (m_logfile){
158  delete m_logfile;
159  }
160  }
161  m_logtofile = logtofile;
162  }
163 
165  return m_logtofile;
166  }
167 
168  bool LogManager::isVisible(logmodule_t module) {
169  if (!m_modules[module]) {
170  return false;
171  }
172  if (moduleInfos[module].parent != LM_CORE) {
173  return isVisible(moduleInfos[module].parent);
174  }
175  return true;
176  }
177 
178  LogManager::LogManager():
179  m_level(LEVEL_DEBUG),
180  module_check_stack(),
181  m_logtofile(false),
182  m_logtoprompt(false) {
183  validateModuleDescription(LM_CORE);
184  m_logfile = 0;
186  }
187 
188  void LogManager::validateModule(logmodule_t m) {
189  if ((m <= LM_CORE) || (m >= LM_MODULE_MAX)) {
190  std::cout << "Invalid module received in LogManager: " << m << ", aborting\n";
191  abort();
192  }
193  }
194 
195  void LogManager::validateModuleDescription(logmodule_t module) {
196  if (module == LM_CORE) {
197  for (int m = static_cast<int>(LM_CORE)+1; m < static_cast<int>(LM_MODULE_MAX); m++) {
198  if (moduleInfos[m].module != static_cast<logmodule_t>(m)) {
199  std::ostringstream stream;
200  stream << m;
201  std::string msg = "Log module definition ids do not match in index ";
202  msg += stream.str();
203  std::cout << msg << std::endl;
204  throw InvalidFormat(msg);
205  }
206  module_check_stack.clear();
207  validateModuleDescription(static_cast<logmodule_t>(m));
208  }
209  } else {
210  module_check_stack.push_back(module);
211  if (count(module_check_stack.begin(), module_check_stack.end(), module) > 1) {
212  throw InvalidFormat("Log module definition hierachy contains cycles");
213  }
214  }
215  }
216 
217  std::string LogManager::getModuleName(logmodule_t module) {
218  return moduleInfos[module].name;
219  }
220 }