ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/auterman/SusyScan/Limits/ConfigFile.cc
Revision: 1.1
Committed: Wed Jan 26 14:37:51 2011 UTC (14 years, 3 months ago) by auterman
Content type: text/plain
Branch point for: Limits, MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 auterman 1.1 // ConfigFile.cpp
2    
3     #include "ConfigFile.h"
4    
5     using std::string;
6    
7     #include <iostream>
8    
9     bag_of_string::bag_of_string(std::string s) : std::vector<std::string>::vector() {
10     std::string buffer;
11     size_type pos1 = 0, pos2 = 0, pos2a = 0, pos2b = 0;
12    
13     while ( pos2<s.length()-1 )
14     {
15     pos1 = pos2;
16     pos2 = s.find(";", pos1+1);
17     pos2a = s.find("\n", pos1+1);
18     pos2b = s.find(";\n", pos1+1);
19    
20     if (pos2a<pos2) pos2=pos2a;
21     if (pos2b<pos2) pos2=pos2b;
22    
23     if (pos1>0) pos1+=1;
24     pos1 = s.find_first_not_of(" ", pos1);
25    
26     buffer.insert(0, s.substr(pos1, pos2-pos1) );
27     this->push_back(buffer);
28    
29     buffer.clear();
30     }
31     }
32    
33    
34     ConfigFile::ConfigFile( string filename, string delimiter,
35     string comment, string sentry )
36     : myDelimiter(delimiter), myComment(comment), mySentry(sentry)
37     {
38     // Construct a ConfigFile, getting keys and values from given file
39    
40     std::ifstream in( filename.c_str() );
41    
42     if( !in ) throw file_not_found( filename );
43    
44     in >> (*this);
45     }
46    
47    
48     ConfigFile::ConfigFile()
49     : myDelimiter( string(1,'=') ), myComment( string(1,'#') )
50     {
51     // Construct a ConfigFile without a file; empty
52     }
53    
54    
55     void ConfigFile::remove( const string& key )
56     {
57     // Remove key and its value
58     myContents.erase( myContents.find( key ) );
59     return;
60     }
61    
62    
63     bool ConfigFile::keyExists( const string& key ) const
64     {
65     // Indicate whether key is found
66     mapci p = myContents.find( key );
67     return ( p != myContents.end() );
68     }
69    
70    
71     /* static */
72     void ConfigFile::trim( string& s )
73     {
74     // Remove leading and trailing whitespace
75     static const char whitespace[] = " \n\t\v\r\f";
76     s.erase( 0, s.find_first_not_of(whitespace) );
77     s.erase( s.find_last_not_of(whitespace) + 1U );
78     }
79    
80    
81     std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
82     {
83     // Save a ConfigFile to os
84     for( ConfigFile::mapci p = cf.myContents.begin();
85     p != cf.myContents.end();
86     ++p )
87     {
88     os << p->first << " " << cf.myDelimiter << " ";
89     os << p->second << std::endl;
90     }
91     return os;
92     }
93    
94    
95     std::istream& operator>>( std::istream& is, ConfigFile& cf )
96     {
97     // Load a ConfigFile from is
98     // Read in keys and values, keeping internal whitespace
99     typedef string::size_type pos;
100     const string& delim = cf.myDelimiter; // separator
101     const string& comm = cf.myComment; // comment
102     const string& sentry = cf.mySentry; // end of file sentry
103     const pos skip = delim.length(); // length of separator
104    
105     string nextline = ""; // might need to read ahead to see where value ends
106    
107     while( is || nextline.length() > 0 )
108     {
109     // Read an entire line at a time
110     string line;
111     if( nextline.length() > 0 )
112     {
113     line = nextline; // we read ahead; use it now
114     nextline = "";
115     }
116     else
117     {
118     std::getline( is, line );
119     }
120    
121     // Ignore comments
122     line = line.substr( 0, line.find(comm) );
123    
124     // Check for end of file sentry
125     if( sentry != "" && line.find(sentry) != string::npos ) return is;
126    
127     // Parse the line if it contains a delimiter
128     pos delimPos = line.find( delim );
129     if( delimPos < string::npos )
130     {
131     // Extract the key
132     string key = line.substr( 0, delimPos );
133     line.replace( 0, delimPos+skip, "" );
134    
135     // See if value continues on the next line
136     // Stop at blank line, next line with a key, end of stream,
137     // or end of file sentry
138     bool terminate = false;
139     while( !terminate && is )
140     {
141     std::getline( is, nextline );
142     terminate = true;
143    
144     string nlcopy = nextline;
145     ConfigFile::trim(nlcopy);
146     if( nlcopy == "" ) continue;
147    
148     nextline = nextline.substr( 0, nextline.find(comm) );
149     if( nextline.find(delim) != string::npos )
150     continue;
151     if( sentry != "" && nextline.find(sentry) != string::npos )
152     continue;
153    
154     nlcopy = nextline;
155     ConfigFile::trim(nlcopy);
156     if( nlcopy != "" ) line += "\n";
157     line += nextline;
158     terminate = false;
159     }
160    
161     // Store key and value
162     ConfigFile::trim(key);
163     ConfigFile::trim(line);
164     cf.myContents[key] = line; // overwrites if key is repeated
165     }
166     }
167    
168     return is;
169     }