00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00092
00093
00094
00095
00096
00097
00098
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
00150
00151
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
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
00173
00174
00175
00176 fname=input_filename;
00177 #endif
00178 }
00179
00180 return read_abs_config_file(fname, root);
00181 }
00182
00183
00184
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;
00194
00195 std::ifstream ifile;
00196 try {
00197 U7open(ifile, filename.c_str(), true);
00198 }
00199 catch(exult_exception &) {
00200
00201 return false;
00202 }
00203
00204 if(ifile.fail())
00205 return false;
00206
00207 string sbuf, line;
00208
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;
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