mifluz

Configuration.cc

Go to the documentation of this file.
00001 //
00002 // Configuration.cc
00003 //
00004 // Configuration: This class provides an object lookup table. Each object 
00005 // in the Configuration is indexed with a string. The objects 
00006 // can be returned by mentioning their string index. Values may
00007 // include files with `/path/to/file` or other configuration
00008 // variables with ${variable}
00009 //
00010 // Part of the ht://Dig package <http://www.htdig.org/>
00011 // Copyright (c) 1999, 2000, 2001 The ht://Dig Group
00012 // For copyright details, see the file COPYING in your distribution
00013 // or the GNU General Public License version 2 or later 
00014 // <http://www.gnu.org/copyleft/gpl.html>
00015 //
00016 // $Id: Configuration_8cc-source.html,v 1.1 2008年06月08日 10:12:52 sebdiaz Exp $
00017 //
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #include "config.h"
00021 #endif /* HAVE_CONFIG_H */
00022 
00023 #include <stdio.h>
00024 #include "Configuration.h"
00025 #include "htString.h"
00026 #include "ParsedString.h"
00027 
00028 #include <stdlib.h>
00029 #include <ctype.h>
00030 #include <locale.h>
00031 
00032 
00033 //*********************************************************************
00034 // Configuration::Configuration()
00035 //
00036 Configuration::Configuration()
00037 {
00038 separators = String("=:");
00039 allow_multiple = 0;
00040 }
00041 
00042 Configuration::Configuration(const Configuration& other) : Object()
00043 {
00044 separators = other.separators;
00045 allow_multiple = other.allow_multiple;
00046 
00047 DictionaryCursor cursor;
00048 const char* key;
00049 for(other.dcGlobalVars.Start_Get(cursor); (key = other.dcGlobalVars.Get_Next(cursor));) {
00050 Add(key, other[key]);
00051 }
00052 }
00053 
00054 //*********************************************************************
00055 // void Configuration::NameValueSeparators(char *s)
00056 //
00057 void Configuration::NameValueSeparators(const String& s)
00058 {
00059 separators = s;
00060 }
00061 
00062 
00063 //*********************************************************************
00064 // Add an entry to the configuration table.
00065 //
00066 void Configuration::Add(const String& str_arg)
00067 {
00068 const char* str = str_arg;
00069 String name, value;
00070 
00071 while (str && *str)
00072 {
00073 while (isspace(*str))
00074 str++;
00075 name = 0;
00076 if (!isalpha(*str))
00077 break;
00078 // Some isalnum() implementations don't allow all the letters that
00079 // isalpha() does, e.g. accented ones. They're not POSIX.2 compliant
00080 // but we won't punish them with an infinite loop...
00081 if (!isalnum(*str))
00082 break;
00083 while (isalnum(*str) || *str == '-' || *str == '_')
00084 name << *str++;
00085 
00086 name.lowercase();
00087 
00088 //
00089 // We have the name. Let's see if we will get a value
00090 //
00091 while (isspace(*str))
00092 str++;
00093 if (!*str)
00094 {
00095 //
00096 // End of string. We need to store the name as a boolean TRUE
00097 //
00098 Add(name, "true");
00099 return;
00100 }
00101 
00102 if (!strchr((char*)separators, *str))
00103 {
00104 //
00105 // We are now at a new name. The previous one needs to be set
00106 // to boolean TRUE
00107 //
00108 Add(name, "true");
00109 continue;
00110 }
00111 
00112 //
00113 // We now need to deal with the value
00114 //
00115 str++; // Skip the separator
00116 while (isspace(*str))
00117 str++;
00118 if (!*str)
00119 {
00120 //
00121 // End of string reached. The value must be blank
00122 //
00123 Add(name, "");
00124 break;
00125 }
00126 value = 0;
00127 if (*str == '"')
00128 {
00129 //
00130 // Ah! A quoted value. This should be easy to deal with...
00131 // (Just kidding!)
00132 //
00133 str++;
00134 while (*str && *str != '"')
00135 {
00136 value << *str++;
00137 }
00138 Add(name, value);
00139 if (*str == '"')
00140 str++;
00141 continue;
00142 }
00143 else if (*str == '\'')
00144 {
00145 // A single quoted value.
00146 str++;
00147 while (*str && *str != '\'')
00148 {
00149 value << *str++;
00150 }
00151 Add(name, value);
00152 if (*str == '\'')
00153 str++;
00154 continue;
00155 }
00156 else
00157 {
00158 //
00159 // A non-quoted string. This string will terminate at the
00160 // next blank
00161 //
00162 while (*str && !isspace(*str))
00163 {
00164 value << *str++;
00165 }
00166 Add(name, value);
00167 continue;
00168 }
00169 }
00170 }
00171 
00172 
00173 //*********************************************************************
00174 // Add an entry to the configuration table, without allowing variable
00175 // or file expansion of the value.
00176 //
00177 void Configuration::Add(const String& name, const String& value)
00178 {
00179 String escaped;
00180 const char *s = value.get();
00181 while (*s)
00182 {
00183 if (strchr("$`\\", *s))
00184 escaped << '\\';
00185 escaped << *s++;
00186 }
00187 ParsedString *ps = new ParsedString(escaped);
00188 dcGlobalVars.Add(name, ps);
00189 }
00190 
00191 
00192 //*********************************************************************
00193 // Add an entry to the configuration table, allowing parsing for variable
00194 // or file expansion of the value.
00195 //
00196 void Configuration::AddParsed(const String& name, const String& value)
00197 {
00198 ParsedString *ps = new ParsedString(value);
00199 if (strcasecmp(name, "locale") == 0)
00200 {
00201 String str(setlocale(LC_ALL, ps->get(dcGlobalVars)));
00202 ps->set(str);
00203 
00204 //
00205 // Set time format to standard to avoid sending If-Modified-Since
00206 // http headers in native format which http servers can't
00207 // understand
00208 //
00209 setlocale(LC_TIME, "C");
00210 }
00211 dcGlobalVars.Add(name, ps);
00212 }
00213 
00214 
00215 //*********************************************************************
00216 // Remove an entry from both the hash table and from the list of keys.
00217 //
00218 int Configuration::Remove(const String& name)
00219 {
00220 return dcGlobalVars.Remove(name);
00221 }
00222 
00223 
00224 //*********************************************************************
00225 // char *Configuration::Find(const char *name) const
00226 // Retrieve a variable from the configuration database. This variable
00227 // will be parsed and a new String object will be returned.
00228 //
00229 const String Configuration::Find(const String& name) const
00230 {
00231 ParsedString *ps = (ParsedString *) dcGlobalVars[name];
00232 if (ps)
00233 {
00234 return ps->get(dcGlobalVars);
00235 }
00236 else
00237 {
00238 #ifdef DEBUG_CONFIGURATION
00239 fprintf (stderr, "Could not find configuration option %s\n", (const char*)name);
00240 #endif
00241 return 0;
00242 }
00243 }
00244 
00245 //*********************************************************************
00246 Object *Configuration::Get_Object(char *name) {
00247 return dcGlobalVars[name];
00248 }
00249 
00250 
00251 //*********************************************************************
00252 //
00253 int Configuration::Value(const String& name, int default_value) const
00254 {
00255 return Find(name).as_integer(default_value);
00256 }
00257 
00258 
00259 //*********************************************************************
00260 //
00261 double Configuration::Double(const String& name, double default_value) const
00262 {
00263 return Find(name).as_double(default_value);
00264 }
00265 
00266 
00267 //*********************************************************************
00268 // int Configuration::Boolean(char *name, int default_value)
00269 //
00270 int Configuration::Boolean(const String& name, int default_value) const
00271 {
00272 int value = default_value;
00273 const String s = Find(name);
00274 if (s[0])
00275 {
00276 if (s.nocase_compare("true") == 0 ||
00277 s.nocase_compare("yes") == 0 ||
00278 s.nocase_compare("1") == 0)
00279 value = 1;
00280 else if (s.nocase_compare("false") == 0 ||
00281 s.nocase_compare("no") == 0 ||
00282 s.nocase_compare("0") == 0)
00283 value = 0;
00284 }
00285 
00286 return value;
00287 }
00288 
00289 
00290 //*********************************************************************
00291 //
00292 const String Configuration::operator[](const String& name) const
00293 {
00294 return Find(name);
00295 }
00296 
00297 
00298 //*********************************************************************
00299 //
00300 int Configuration::Read(const String& filename)
00301 {
00302 FILE* in = fopen((const char*)filename, "r");
00303 
00304 if(!in) {
00305 fprintf(stderr, "Configuration::Read: cannot open %s for reading : ", (const char*)filename);
00306 perror("");
00307 return NOTOK;
00308 }
00309 
00310 #define CONFIG_BUFFER_SIZE (50*1024) 
00311 //
00312 // Make the line buffer large so that we can read long lists of start
00313 // URLs.
00314 //
00315 char buffer[CONFIG_BUFFER_SIZE + 1];
00316 char *current;
00317 String line;
00318 String name;
00319 char *value;
00320 int len;
00321 while (fgets(buffer, CONFIG_BUFFER_SIZE, in))
00322 {
00323 line << buffer;
00324 line.chop("\r\n");
00325 if (line.last() == '\\')
00326 {
00327 line.chop(1);
00328 continue; // Append the next line to this one
00329 }
00330 
00331 current = line.get();
00332 if (*current == '#' || *current == '0円')
00333 {
00334 line = 0;
00335 continue; // Comments and blank lines are skipped
00336 }
00337 
00338 name = strtok(current, ": =\t");
00339 value = strtok(0, "\r\n");
00340 if (!value)
00341 value = ""; // Blank value
00342 
00343 //
00344 // Skip any whitespace before the actual text
00345 //
00346 while (*value == ' ' || *value == '\t')
00347 value++;
00348 len = strlen(value) - 1;
00349 //
00350 // Skip any whitespace after the actual text
00351 //
00352 while (value[len] == ' ' || value[len] == '\t')
00353 {
00354 value[len] = '0円';
00355 len--;
00356 }
00357 
00358 if (strcasecmp((char*)name, "include") == 0)
00359 {
00360 ParsedString ps(value);
00361 String str(ps.get(dcGlobalVars));
00362 if (str[0] != '/') // Given file name not fully qualified
00363 {
00364 str = filename; // so strip dir. name from current one
00365 len = str.lastIndexOf('/') + 1;
00366 if (len > 0)
00367 str.chop(str.length() - len);
00368 else
00369 str = ""; // No slash in current filename
00370 str << ps.get(dcGlobalVars);
00371 }
00372 Read(str);
00373 line = 0;
00374 continue;
00375 }
00376 
00377 AddParsed(name, value);
00378 line = 0;
00379 }
00380 fclose(in);
00381 return OK;
00382 }
00383 
00384 
00385 //*********************************************************************
00386 // void Configuration::Defaults(ConfigDefaults *array)
00387 //
00388 void Configuration::Defaults(const ConfigDefaults *array)
00389 {
00390 for (int i = 0; array[i].name; i++)
00391 {
00392 AddParsed(array[i].name, array[i].value);
00393 }
00394 }
00395 

Generated on Sun Jun 8 10:56:39 2008 for GNUmifluz by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /