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

# Content
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 }