Configuration.cc

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2000-2002  The Exult Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #  include <config.h>
00021 #endif
00022 
00023 #include "common_types.h"
00024 #include "Configuration.h"
00025 #include "exceptions.h"
00026 #include "utils.h"
00027 
00028 #ifndef ALPHA_LINUX_CXX
00029 #  include <cassert>
00030 #  include <cstdio>
00031 #endif
00032 #include <stdio.h>
00033 #include <iostream>
00034 #include <fstream>
00035 #ifdef HAVE_SSTREAM
00036 #include <sstream>
00037 #endif
00038 
00039 #ifndef UNDER_CE
00040 using std::atoi;
00041 using std::cerr;
00042 using std::endl;
00043 using std::string;
00044 using std::ostream;
00045 #endif
00046 
00047 // isspace could be a macro
00048 #ifndef UNDER_CE
00049 #ifndef isspace
00050 using std::isspace;
00051 #endif
00052 #endif
00053 
00054 #define TRACE_CONF 0
00055 
00056 #if TRACE_CONF
00057   #define CTRACE(X) cerr << X << endl
00058 #else
00059   #define CTRACE(X)
00060 #endif
00061 
00062 void  Configuration::value(const string &key, string &ret,const char *defaultvalue) const
00063 {
00064   const XMLnode *sub=xmltree->subtree(key);
00065   if(sub)
00066     ret = sub->value();
00067   else
00068     ret = defaultvalue;
00069 }
00070 
00071 void  Configuration::value(const string &key,bool &ret,bool defaultvalue) const
00072 {
00073   const XMLnode *sub=xmltree->subtree(key);
00074   if(sub)
00075     ret = (to_uppercase(sub->value()) == "YES");
00076   else
00077     ret = defaultvalue;
00078 }
00079 
00080 void  Configuration::value(const string &key,int &ret,int defaultvalue) const
00081 {
00082   const XMLnode *sub=xmltree->subtree(key);
00083   if(sub)
00084     ret = atoi(sub->value().c_str());
00085   else
00086     ret = defaultvalue;
00087 }
00088 
00089 void  Configuration::set(const string &key, const string &value, bool write_out)
00090 {
00091   // Break k up into '/' separated elements.
00092   // start advancing walk, one element at a time, creating nodes
00093   // as needed.
00094   // At the end of that, walk is the target node, and we
00095   // can set the value.
00096 
00097   // We must also properly encode the value before writing it out.
00098   // Must remember that.
00099 
00100   xmltree->xmlassign(key,value);
00101   if(write_out)
00102     write_back();
00103 }
00104 
00105 void  Configuration::set(const char *key, const char *value, bool write_out)
00106 {
00107   string  k(key), v(value);
00108   set(k, v, write_out);
00109 }
00110 
00111 void  Configuration::set(const char *key, const string &value, bool write_out)
00112 {
00113   string  k(key);
00114   set(k, value, write_out);
00115 }
00116 
00117 void  Configuration::set(const char *key, int value,bool write_out)
00118 {
00119   string  k(key),v;
00120   char  buf[32];
00121 
00122   snprintf(buf,32,"%d",value);
00123   v=buf;
00124   set(k,v,write_out);
00125 }
00126 
00127 
00128 bool  Configuration::read_config_string(const string &s)
00129 {
00130   string  sbuf(s);
00131   size_t  nn=0;
00132   while(isspace(s[nn])) ++nn;
00133   
00134   assert(s[nn]=='<');
00135   ++nn;
00136   
00137   xmltree->xmlparse(sbuf,nn);
00138   is_file=false;
00139   return true;
00140 }
00141 
00142 bool  Configuration::read_config_file(const string &input_filename, const string &root)
00143 {
00144   string fname;
00145 
00146   CTRACE("Configuration::read_config_file");
00147   
00148   fname=input_filename;
00149   // Don't frob the filename if it starts with a dot and
00150   // a slash.
00151   // Or if it's not a relative path.
00152   if((fname.find("./")!=0) && (fname[0]!='/'))
00153   {
00154 #if ((defined XWIN) || (defined BEOS) || (defined MACOSX))
00155     const char *f1=getenv("HOME");
00156     if(f1)
00157     {
00158       // User has a home directory
00159       fname=f1;
00160 #if defined(BEOS)
00161       fname+="/config/settings/";
00162 #elif defined(MACOSX)
00163       fname+="/Library/Preferences/";
00164 #else
00165       fname+="/.";
00166 #endif
00167       fname+=input_filename;
00168     }
00169     else
00170       fname=input_filename;
00171 #else
00172     // Probably something to do with determining the username
00173     // and generating a filename in their personal setup area.
00174 
00175     // For now, just read file from current directory
00176     fname=input_filename;
00177 #endif
00178   }
00179 
00180   return read_abs_config_file(fname, root);
00181 }
00182 
00183 
00184 // read config from file, without pre-processing the filename
00185 bool Configuration::read_abs_config_file(const string &input_filename, const string &root)
00186 {
00187   filename = input_filename;
00188 
00189   CTRACE("Configuration::read_abs_config_file");
00190 
00191   clear(root);
00192 
00193   is_file=true; // set to file, even if file not found
00194 
00195   std::ifstream ifile;
00196   try {
00197      U7open(ifile, filename.c_str(), true);
00198   }
00199   catch(exult_exception &) {
00200     // configuration file not found
00201     return false;
00202   }
00203 
00204   if(ifile.fail())
00205     return false;
00206 
00207   string  sbuf, line;
00208   // copies the entire contents of the input file into sbuf
00209   getline(ifile, line);
00210   while (ifile.good())
00211   {
00212       sbuf += line + "\n";
00213       getline(ifile, line);
00214   }
00215   
00216   ifile.close();
00217   
00218   CTRACE("Configuration::read_config_file - file read");
00219   
00220   read_config_string(sbuf);
00221   
00222   is_file=true;
00223   return true;
00224 }
00225 
00226 
00227 string  Configuration::dump(void)
00228 {
00229   return xmltree->dump();
00230 }
00231 
00232 ostream &Configuration::dump(ostream &o, const string &indentstr)
00233 {
00234   xmltree->dump(o, indentstr);
00235   return o;
00236 }
00237 
00238 void Configuration::write_back(void)
00239 {
00240   if(!is_file)
00241     return; // Don't write back if not from a file
00242   
00243   std::ofstream ofile;
00244   try {
00245   U7open(ofile, filename.c_str(), true);
00246   } catch (const file_open_exception &)
00247   {
00248     std::perror("Failed to write configuration file");
00249     return;
00250   }
00251   if(ofile.fail())
00252   {
00253     std::perror("Failed to write configuration file");
00254     return;
00255   }
00256   ofile << dump() << endl;
00257   ofile.close();
00258 }
00259 
00260 
00261 std::vector<string> Configuration::listkeys(const string &key, bool longformat)
00262 {
00263   std::vector<string> vs;
00264   const XMLnode *sub=xmltree->subtree(key);
00265   if(sub)
00266     sub->listkeys(key,vs,longformat);
00267   
00268   return vs;
00269 }
00270 
00271 std::vector<string> Configuration::listkeys(const char *key, bool longformat)
00272 {
00273   string s(key);
00274   return listkeys(s,longformat);
00275 }
00276 
00277 void Configuration::clear(const string &new_root)
00278 {
00279   CTRACE("Configuration::clear");
00280   
00281   if(xmltree!=0)
00282     delete xmltree;
00283   CTRACE("Configuration::clear - xmltree deleted");
00284   if(new_root.size())
00285     rootname=new_root;
00286   CTRACE("Configuration::clear - new root specified");
00287   xmltree = new XMLnode(rootname);
00288   CTRACE("Configuration::clear - fin");
00289 }
00290 
00291 void Configuration::getsubkeys(KeyTypeList &ktl, const string &basekey)
00292 {
00293   xmltree->searchpairs(ktl, basekey, string(), 0);
00294 }
00295 
00296 
00297 
00298 
00299 

Generated on Mon Jul 9 14:42:44 2007 for ExultEngine by  doxygen 1.5.1