text: /*
   * SimpleConfigurator.cpp
   *
   * Copyright 2001, Glen Scott. All rights reserved.
   *
   * See the COPYING file for the terms of usage and distribution.
   */
  #include "PortabilityImpl.hh"
  
  #ifdef LOG4CPP_HAVE_UNISTD_H
  #include <unistd.h>
  #endif
  #ifdef LOG4CPP_HAVE_IO_H
  #    include <io.h>
  #endif
  
  #include <stdio.h>
  #include <iostream>
  #include <string>
  #include <fstream>
  #include <stdio.h>
  
  #include <log4cpp/Category.hh>
  #include <log4cpp/Appender.hh>
  #include <log4cpp/OstreamAppender.hh>
  #include <log4cpp/FileAppender.hh>
  #include <log4cpp/RollingFileAppender.hh>
  #include <log4cpp/DailyRollingFileAppender.hh>
  #include <log4cpp/Layout.hh>
  #include <log4cpp/BasicLayout.hh>
  #include <log4cpp/SimpleLayout.hh>
  #include <log4cpp/Priority.hh>
  #include <log4cpp/NDC.hh>
  #include <log4cpp/PatternLayout.hh>
  #include <log4cpp/SimpleConfigurator.hh>
  #if LOG4CPP_HAVE_SYSLOG
  #include <log4cpp/SyslogAppender.hh>
  #endif
  #ifndef LOG4CPP_DISABLE_REMOTE_SYSLOG
  #include <log4cpp/RemoteSyslogAppender.hh>
  #endif
  #ifdef WIN32
  #include <log4cpp/NTEventLogAppender.hh>
  #endif
  
  namespace log4cpp {
  
      void SimpleConfigurator::configure(const std::string& initFileName) {
          std::ifstream initFile(initFileName.c_str());
          
          if (!initFile) {
              throw ConfigureFailure(std::string("Config File ") + initFileName + " does not exist or is unreadable");
          }
          
          configure(initFile);
      }
            
      void SimpleConfigurator::configure(std::istream& initFile) {
          std::string nextCommand;
          std::string categoryName;
          
          while (initFile >> nextCommand) {
              /* skip comment lines */
              if (nextCommand[0] == '#') {
                  std::string dummy;
                  std::getline(initFile, dummy);
                  continue;
              }
              /* stop on missing categoryName */
              if (!(initFile >> categoryName))
                  break;
  
              log4cpp::Category& category =
                  (categoryName.compare("root") == 0) ?
                  log4cpp::Category::getRoot() :
                  log4cpp::Category::getInstance(categoryName);
              
              if (nextCommand.compare("appender") == 0) {
                  std::string layout;
                  std::string appenderName;
                  
                  if (initFile >> layout >> appenderName) {
                      log4cpp::Appender* appender;
                      if (appenderName.compare("file") == 0) {
                          std::string logFileName;
                          if (!(initFile >> logFileName)) {
                              throw ConfigureFailure("Missing filename for log file logging configuration file for category: " + categoryName);
                          }
                          appender = new log4cpp::FileAppender(categoryName, logFileName);
                      }
                      else if (appenderName.compare("rolling") == 0) {
                          std::string logFileName;
                          size_t maxFileSize;
                          unsigned int maxBackupIndex=1;
                          if (!(initFile >> logFileName)) {
                              throw ConfigureFailure("Missing filename for log file logging configuration file for category: " + categoryName);
                          }
                          if (!(initFile >> maxFileSize)) {
                              throw ConfigureFailure("Missing maximum size for log file logging configuration file for category: " + categoryName);
                          }
                          if (!(initFile >> maxBackupIndex)) {
                              throw ConfigureFailure("Missing maximum backup index for log file logging configuration file for category: " + categoryName);
                          }
                          appender = new log4cpp::RollingFileAppender(categoryName, logFileName, maxFileSize, maxBackupIndex);
                      }
                      else if (appenderName.compare("dailyrolling") == 0) {
                          std::string logFileName;
                          unsigned int maxKeepDays=1;
                          if (!(initFile >> logFileName)) {
                              throw ConfigureFailure("Missing filename for log file logging configuration file for category: " + categoryName);
                          }
                          if (!(initFile >> maxKeepDays)) {
                              throw ConfigureFailure("Missing maximum keep days for log file logging configuration file for category: " + categoryName);
                          }
                          appender = new log4cpp::DailyRollingFileAppender(categoryName, logFileName, maxKeepDays);
                      }
                      else if (appenderName.compare("console") == 0) {
                          appender =
                              new log4cpp::OstreamAppender(categoryName, &std::cout);
                      }
                      else if (appenderName.compare("stdout") == 0) {
                          appender =
                              new log4cpp::FileAppender(categoryName, ::dup(fileno(stdout)));
                      }
                      else if (appenderName.compare("stderr") == 0) {
                          appender =
                              new log4cpp::FileAppender(categoryName, ::dup(fileno(stderr)));
                      }
  #if LOG4CPP_HAVE_SYSLOG
                      else if (appenderName.compare("syslog") == 0) {
                          std::string syslogName;
                          int facility;
                          if (!(initFile >> syslogName)) {
                              throw ConfigureFailure("Missing syslogname for SysLogAppender for category: " + categoryName);
                          }
                          if (!(initFile >> facility)) {
                              facility = LOG_USER;
                          } else {
                              // * 8
                              facility *= 8;
                          }
                          appender =
                              new log4cpp::SyslogAppender(categoryName, syslogName, facility);
                      } 
  #endif
  #if defined(WIN32)
                      else if (appenderName.compare("nteventlog") == 0) {
                          std::string source;
                          if (!(initFile >> source)) {
                              throw ConfigureFailure("Missing source for NTEventLogAppender for category: " + categoryName);
                          }
                          appender =
                              new log4cpp::NTEventLogAppender(categoryName, source);
                      } 
  #endif
  #if !defined(LOG4CPP_DISABLE_REMOTE_SYSLOG)
                      else if (appenderName.compare("remotesyslog") == 0) {
                          std::string syslogName;
                          std::string relayer;
                          int facility;
                          int portNumber;
                          if (!(initFile >> syslogName)) {
                              throw ConfigureFailure("Missing syslogname for SysLogAppender for category: " + categoryName);
                          }
                          if (!(initFile >> relayer)) {
                              throw ConfigureFailure("Missing syslog host for SysLogAppender for category: " + categoryName);
                          }
                          if (!(initFile >> facility)) {
                              facility = LOG_USER;
                          }
                          if (!(initFile >> portNumber)) {
                              portNumber = 514;
                          }
                          appender =
                              new log4cpp::RemoteSyslogAppender(categoryName, syslogName, relayer, facility, portNumber);
                      }
  #endif // LOG4CPP_DISABLE_REMOTE_SYSLOG
                      else {
                          throw ConfigureFailure("Invalid appender name (" +
                                                 appenderName +
                                                 ") in logging configuration file for category: " +
                                                 categoryName);
                      }
                      if (layout.compare("basic") == 0)
                          appender->setLayout(new log4cpp::BasicLayout());
                      else if (layout.compare("simple") == 0)
                          appender->setLayout(new log4cpp::SimpleLayout());
                      else if (layout.compare("pattern") == 0) {
                          log4cpp::PatternLayout *layout =
                              new log4cpp::PatternLayout();
  			initFile >> std::ws; // skip whitespace
                          char pattern[1000];
                          initFile.getline(pattern, 1000);
                          layout->setConversionPattern(std::string(pattern));
  			appender->setLayout(layout);
                      }
                      else {
                          throw ConfigureFailure("Invalid layout (" + layout +
                                                 ") in logging configuration file for category: " +
                                                 categoryName);
                      }
                      category.addAppender(appender);
                  }
              }
              else if (nextCommand.compare("priority") == 0) {
                  std::string priority;
                  if (!(initFile >> priority)) {
                      throw ConfigureFailure("Missing priority in logging configuration file for category: " + categoryName);
                  }
                  
                  try {
                      category.setPriority(log4cpp::Priority::getPriorityValue(priority));
                  } catch(std::invalid_argument) {
                      throw ConfigureFailure("Invalid priority ("+priority+") in logging configuration file for category: "+categoryName);
                  }
              }
              else if (nextCommand.compare("category") == 0) {
                  /*
                    This command means we should "refer" to the category
                    (in order to have it created). We've already done this
                    in common setup code for all commands.
                  */
              }
              else {
                  throw ConfigureFailure("Invalid format in logging configuration file. Command: " + nextCommand);
              }
          }
      }
  }
  
  
  
  