Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Examples

IniParser.h

Go to the documentation of this file.
00001 
00013 #ifndef __IniParser_h__
00014 #define __IniParser_h__
00015 
00016 #include <unistd.h>
00017 #include <ctype.h>
00018 #include <stdio.h>
00019 #include <regex.h>
00020 
00021 #include <y2util/RepDef.h>
00022 #include <YCP.h>
00023 
00024 #include <iosfwd>
00025 #include <fstream>
00026 #include <string>
00027 #include <vector>
00028 #include <set>
00029 
00030 #include "IniFile.h"
00031 
00032 using std::string;
00033 using std::vector;
00034 using std::ifstream;
00035 using std::ofstream;
00036 using std::set;
00037 
00038 DEFINE_BASE_POINTER (Regex_t);
00039 
00044 class Regex_t : virtual public Rep
00045 {
00046     REP_BODY (Regex_t); 
00047 private:
00048     friend class Regex;
00049 
00050     regex_t regex;              
00051     bool live; 
00052 
00053 public:
00054     Regex_t ():
00055         live (false) {}
00056     ~Regex_t () {
00057         if (live)
00058         {
00059             regfree (&regex);
00060         }
00061     }
00069     int compile (const string& pattern, bool ignore_case) {
00070         int ret = -1;
00071         if (live)
00072         {
00073             y2error ("Regex_t @%p already compiled", this);
00074         }
00075         else
00076         {
00077             ret = regcomp (&regex, pattern.c_str (),
00078                            REG_EXTENDED | (ignore_case ? REG_ICASE : 0));
00079             if (ret)
00080             {
00081                 char error[256];
00082                 regerror (ret, &regex, error, 256);
00083                 y2error ("Regex_t %s error: %s", pattern.c_str (), error);
00084             }
00085             else
00086             {
00087                 live = true;
00088             }
00089         }
00090         return ret;
00091     }
00092 };
00093 
00097 class Regex
00098 {
00099     Regex_tPtr rxtp;
00100 public:
00101     Regex (): rxtp (0) {}
00108     int compile (const string& pattern, bool ignore_case) {
00109         if (rxtp)
00110         {
00111             y2error ("Regex_t @%p already compiled", this);
00112             return -1;
00113         }
00114         else
00115         {
00116             rxtp = new Regex_t;
00117             return rxtp->compile (pattern, ignore_case);
00118         }
00119     }
00120     const regex_t * regex () const { return & rxtp->regex; }
00121 };
00122 
00126 class RegexMatch
00127 {
00128 public:
00130     vector<string> matches;
00132     string rest;
00133 
00135     const string& operator[] (size_t i) { return matches[i]; }
00137     operator bool () { return matches.size () > 0; }
00138 
00144     RegexMatch (const Regex& rx, const string& s, size_t nmatch = 20) {
00145         // allocate at least for the whole match
00146         if (nmatch == 0)
00147         {
00148             nmatch = 1;
00149         }
00150         regmatch_t rm_matches[nmatch];
00151         if (0 == regexec (rx.regex (), s.c_str (), nmatch, rm_matches, 0))
00152         {
00153             // match
00154             matches.reserve (nmatch);
00155             rest = s.substr (0, rm_matches[0].rm_so) +
00156                 s.substr (rm_matches[0].rm_eo);
00157         }
00158         else
00159         {
00160             // no match
00161             rm_matches[0].rm_so = -1;
00162             rest = s;
00163         }
00164 
00165         size_t i;
00166         for (i = 0; i < nmatch && rm_matches[i].rm_so != -1; ++i)
00167         {
00168             matches.push_back (s.substr (rm_matches[i].rm_so,
00169                                          rm_matches[i].rm_eo - rm_matches[i].rm_so));
00170         }
00171     }
00172     
00173 };
00174 
00178 struct IoPattern
00179 {
00180     Regex rx;
00181     string out;
00182 };
00183 
00187 struct section
00188 {
00189     IoPattern begin;
00190     IoPattern end;
00191     bool end_valid;
00192 };
00193 
00197 struct param
00198 {
00200     IoPattern line;
00202     Regex begin;
00204     Regex end;
00206     bool multiline_valid;
00207 };
00208 
00209 struct FileDescr
00210 {
00214     string fn;
00218     string sn;
00222     time_t timestamp;
00223     FileDescr (char*fn);
00224     bool changed ();
00225     FileDescr () {}
00226 };
00227 
00231 class IniParser
00232 {
00233 private:
00237     time_t timestamp;
00242     map<string,FileDescr> multi_files;
00246     string file;
00250     time_t getTimeStamp();
00252     bool line_can_continue;
00254     bool ignore_case_regexps;
00256     bool ignore_case;
00258     bool prefer_uppercase;
00263     bool first_upper;
00265     bool no_nested_sections;
00267     bool global_values;
00269     bool repeat_names;
00271     bool comments_last;
00273     bool join_multiline;
00275     bool no_finalcomment_kill;
00277     bool read_only;
00279     bool flat;
00280 
00282     string subindent;
00286     vector<Regex> linecomments;
00290     vector<Regex> comments;
00294     vector<section> sections;
00298     vector<param> params;
00302     vector<IoPattern> rewrites;
00303 
00307     ifstream scanner;
00311     int scanner_line;
00312 
00317     bool started;
00318 
00322     bool multiple_files;
00326     vector<string> files;
00327 
00331     int scanner_start(const char*fn);
00335     void scanner_stop();
00339     int scanner_get(string&s);
00340 
00344     int parse_helper(IniSection&ini);
00348     int write_helper(IniSection&ini, ofstream&of,int depth);
00349 public:
00360     set<string> deleted_sections;
00364     IniSection inifile;
00365     // apparently the uninitialized members are filled in
00366     // by the grammar definition
00367     IniParser () :
00368         linecomments (), comments (),
00369         sections (), params (), rewrites (),
00370         started (false), multiple_files (false),
00371 //      inifile ("toplevel")
00372         inifile (this)
00373             {}
00374     ~IniParser ();
00379     void initFiles (const char*fn);
00384     void initFiles (const YCPList&f);
00390     int initMachine (const YCPMap&scr);
00391     bool isStarted() { return started; }
00392 
00397     int parse();
00402     void UpdateIfModif ();
00403 
00407     int write ();
00408 
00414     bool sectionNeedsEnd (int i) { return sections[i].end_valid; }
00415 
00423     string getFileName (const string&sec, int rb);
00427     bool HaveRewrites () const { return rewrites.size () > 0; }
00428 
00430     bool repeatNames () const { return repeat_names; }
00432     bool isFlat () const { return flat; }
00433 
00439     string changeCase (const string&str) const;
00440 };
00441 
00442 #endif//__IniParser_h__

Generated on Fri Nov 9 18:15:22 2007 for yast2-core by doxygen 1.3.6