src/loader.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2003 - 2004 Anselm R. Garbe <anselmg at t-online.de>
00002 // See ../LICENSE.txt for license details.
00003 //
00004 // $Id: loader.cpp 7 2007-05-24 11:03:53Z eg1981 $
00005 
00006 extern "C" {
00007 #include <sys/stat.h>
00008 #include <sys/types.h>
00009 }
00010 
00011 #include <fstream>
00012 #include <iostream>
00013 #include <sstream>
00014 
00015 #include "loader.h"
00016 #include "util.h"
00017 
00018 Loader::Loader() {
00019 }
00020 
00021 Loader::~Loader() {
00022 }
00023 
00024 bool Loader::load(MSettings *settings, string path,
00025                   bool suppressWarning, bool caseSensitive)
00026 {
00027 
00028     ifstream is(path.c_str());
00029 
00030     if (!is) {
00031         if (!suppressWarning) {
00032             cerr << "ncwm[W " << Util::timestamp()
00033                 << "]: cannot open/read configuration file '"
00034                 << path << "', skipping" << endl;
00035         }
00036         return false;
00037     }
00038 
00039     string key = "";
00040     string value = "";
00041     string buf = "";
00042     bool comment = false;
00043     bool ignoreWhitespaces = true;
00044     bool escape = false; // provides using {#, ", =, \n} characters
00045     int c;
00046 
00047     while (!is.eof()) {
00048 
00049         c = is.get();
00050 
00051         switch (c) {
00052         case ' ':
00053         case '\t':
00054             if (!comment && !ignoreWhitespaces) {
00055                 buf += c;
00056             }
00057             escape = false;
00058             break;
00059         case '"': // toggle ignore whitespace/or escape this character
00060             if (!comment) {
00061                 if (escape) {
00062                     buf += c;
00063                 }
00064                 else {
00065                     ignoreWhitespaces = !ignoreWhitespaces;
00066                 }
00067             }
00068             escape = false;
00069             break;
00070         case '\\': // escape
00071             if (!comment) {
00072                 if (escape) {
00073                     buf += c;
00074                     escape = false;
00075                 }
00076                 else {
00077                     escape = true;
00078                 }
00079             }
00080             break;
00081         case '#': // comment
00082             if (escape) {
00083                 buf += c;
00084             }
00085             else {
00086                 comment = true;
00087             }
00088             escape = false;
00089             break;
00090         case '=':
00091             if (!comment) {
00092                 if (escape) {
00093                     buf += c;
00094                 }
00095                 else {
00096                     key = buf;
00097                     buf = "";
00098                 }
00099             }
00100             escape = false;
00101             break;
00102         case '\n':
00103 
00104 #define ENDLINE \
00105             if (!escape) { \
00106                 comment = false; \
00107                 ignoreWhitespaces = true; \
00108                 value = buf; \
00109                 if ((key != "") && (value != "")) { \
00110                     value = buf; \
00111                     if (caseSensitive) { \
00112                         (*settings)[key] = value; \
00113                     } \
00114                     else { \
00115                         (*settings)[Util::lowerCase(key)] = value; \
00116                     } \
00117                 } \
00118                 buf = key = value = ""; \
00119             } \
00120             escape = false; \
00121             break; \
00122             
00123             ENDLINE
00124         case EOF :
00125             ENDLINE
00126         default:
00127             if (!comment) {
00128                 buf += c;
00129             }
00130             escape = false;
00131             break;
00132         }
00133     }
00134     is.close();
00135 
00136     return true;
00137 }
00138 
00139 bool Loader::saveSettings(MSettings *settings, string path) {
00140 
00141     ostringstream content; 
00142 
00143     for (MSettings::iterator it = settings->begin();
00144             it != settings->end(); it++)
00145     {
00146         string value = Util::encodeEscapes((*it).second);
00147         if (Util::containsWhitespaces(value)) {
00148             content << (*it).first << "=\"" << value << "\"" << endl;
00149         }
00150         else {
00151             content << (*it).first << "=" << value << endl;
00152         }
00153     }
00154 
00155     return saveFile(path, content.str());
00156 }
00157 
00158 bool Loader::saveFile(string path, string content) {
00159 
00160     string dir = Util::canonicalDir(path);
00161     if (!Util::exists(dir.c_str())) {
00162 
00163         mode_t mode = umask(0);
00164         mode = (mode ^ (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IWUSR | S_IXUSR;
00165         if (mkdir(dir.c_str(), mode) != 0) {
00166             cerr << "ncwm[W " << Util::timestamp()
00167                 << "]: cannot create non-existing directory '"
00168                 << dir << "', skipping" << endl;
00169         }
00170     }
00171 
00172     ofstream os(path.c_str());
00173 
00174     if (!os) {
00175         cerr << "ncwm[W " << Util::timestamp()
00176              << "]: cannot open/write configuration file '"
00177              << path << "', skipping" << endl;
00178         return false;
00179     }
00180 
00181     os << content;
00182     os.close();
00183 
00184     return true;
00185 
00186 }
00187 
00188 void Loader::print(MSettings *settings) {
00189 
00190     MSettings::iterator it = settings->begin();
00191     while (it != settings->end()) {
00192         cout << (*it).first << "=" << (*it).second << endl;
00193         it++;
00194     }
00195 }

Generated on Thu May 24 15:19:32 2007 for ncwm by  doxygen 1.5.1