source: gsdl/trunk/common-src/src/lib/cfgread.cpp@ 20710

Last change on this file since 20710 was 20710, checked in by mdewsnip, 15 years ago

Fixed memory error picked up by Valgrind.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
RevLine 
[1076]1/**********************************************************************
2 *
3 * cfgread.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "cfgread.h"
[9515]27#include <cctype> // for isspace()
[1076]28
[8727]29int write_ini_line (ofstream &fileout, const text_t &key, const text_t &value) {
[1076]30 if (key.empty() || value.empty()) return -1;
31 outconvertclass text_t2ascii;
32 fileout << text_t2ascii << key << "=" << value << "\n";
33 return 0;
34}
35
36int read_ini_line (ifstream &filein, text_t &key, text_t &value) {
37 if (filein.eof()) return -1;
38
39 key.clear();
40 value.clear();
41 char c;
42 filein.get(c);
43
44 int foundeq = 0;
45 while (!filein.eof() && c != '\n') {
46 if (!foundeq && c == '=') {foundeq = 1; filein.get(c);}
47
48 if (foundeq) value.push_back(c);
49 else key.push_back(c);
50 filein.get(c);
51 }
[1739]52 if (key.empty()) return 0; // blank line maybe?
[1076]53 return 0;
54}
55
[1421]56// write out line of values to cfgfile
57// does nothing fancy - make sure no values contain carriage returns
58int write_cfg_line (ofstream &fileout, const text_tarray &values) {
59 outconvertclass text_t2ascii;
[1076]60
[1421]61 text_tarray::const_iterator here = values.begin();
62 text_tarray::const_iterator end = values.end();
63
64 bool first = true;
65 while (here != end) {
66 if (first) fileout << text_t2ascii << *here;
67 else fileout << text_t2ascii << " \"" << *here << "\"";
68 first = false;
[8727]69 ++here;
[1421]70 }
71 fileout << "\n";
[1432]72 return 0;
[1421]73}
[3528]74
[3010]75// same, but use a file descriptor this time
76int write_cfg_line (int fileout, const text_tarray &values) {
77 outconvertclass text_t2ascii;
[1421]78
[3010]79 text_tarray::const_iterator here = values.begin();
80 text_tarray::const_iterator end = values.end();
81
[3528]82 if (here != end) {
83 char *s=here->getcstr();
84 write(fileout,s ,here->size());
[8727]85 delete []s;
[3528]86
87 ++here;
88 }
[3010]89 while (here != end) {
[3528]90 write(fileout, " \"", 2);
91 char *s=here->getcstr();
92 write(fileout,s ,here->size());
[8727]93 delete []s;
[3528]94 write(fileout, "\"", 1);
[3010]95
[3528]96 ++here;
[3010]97 }
98 write(fileout,"\n",1);
99 return 0;
100}
101
102
[1076]103// returns 0 on success, -1 on failure
104int read_cfg_line (ifstream &filein, text_tarray &values) {
[3417]105 // we split up the line into tokens, pushing each token into the
106 // values array. Quoted phrases are a single token. A "\" at the end
107 // of a line continues onto the next line.
[1076]108
109 values.erase(values.begin(), values.end());
110
111 if (!filein.good()) return -1;
112
113 text_t curvalue;
[7731]114 char c1;
[7705]115 filein.get(c1);
[1076]116
[3417]117 // skip white space
[9515]118 while (!filein.eof() && isspace((unsigned char) c1)) { filein.get(c1); }
[3417]119
[1076]120 // ignore comments
[20710]121 while (!filein.eof() && c1 == '#') {
[7705]122 while (!filein.eof() && c1!='\n' && c1!='\r') { filein.get(c1); }
[3417]123 // skip white space...
[9515]124 while (!filein.eof() && isspace((unsigned char) c1)) { filein.get(c1); }
[3417]125 }
126
127 // deal with all the records on this line (possibly multi-line)
[7705]128
[3417]129 while (!filein.eof()) {
[7705]130 if (c1=='\n' || c1=='\r') { // shouldn't happen?
[3417]131 break;
[1076]132 }
133
[3417]134 // get the next token
135 curvalue.clear();
136
[7705]137 bool inquote=false;
[7731]138 char quotemark='"';
[7733]139 char preceding='\0'; // 1-char state to allow \" and \'
[7705]140 // see if this is a quoted phrase
141 if (c1=='\'' || c1=='\"') { // starts with a quote
142 inquote=true;
143 quotemark = c1;
144 preceding = c1; // just to initialise
145 filein.get(c1);
146 }
147
148 // get token or a whole phrase
149 while (!filein.eof()) {
[9515]150 if (isspace((unsigned char) c1)) {
[7705]151 if (! inquote) {
152 // end of token, not inside quote marks
153 break;
154 } else {
155 // inside quote marks.
156 /* Turn eol into space, in case other parsing bits expect eol to
157 also mean end of parsing... */
158 c1=' ';
159 }
[3417]160 }
[7705]161 if (c1 == quotemark && inquote && preceding != '\\') {
162 // end of quoted phrase found
163 inquote=false;
164 filein.get(c1);
165 continue;
[3417]166 }
[7705]167
168 // add current char to token/phrase
169 // see if current byte is part of a multibyte char (utf-8 only!)
170 unsigned short int c; // text_t uses 16bit unicode
[7731]171 unsigned char uc1=(unsigned)c1;
172 if (uc1 < 0x80) {
173 c=uc1;
174 } else if (uc1 >= 0xc0 && uc1 <= 0xdf) {
[7705]175 // 2-byte utf-8
176 unsigned char c2;
177 // two byte character
[7733]178 filein.get((char&)c2); // get takes a signed char
[7731]179 c = ((uc1 & 0x1f) << 6) + (c2 & 0x3f);
180 } else if (uc1 >= 0xe0 && uc1 <= 0xef) {
[7705]181 // 3-byte character
182 unsigned char c2, c3;
[7733]183 filein.get((char&)c2);
184 filein.get((char&)c3);
[7731]185 c = ((uc1 & 0xf) << 12) + ((c2 & 0x3f) << 6)
186 + (c3 & 0x3f);
[7733]187 } else {c=uc1;} // we don't do group2/plane0 (4,5,6-byte utf-8)
[7705]188
189 curvalue.push_back(c); // 16bit unicode
190 if (inquote)
191 preceding = c1;
192
193 filein.get(c1);
[3417]194 }
195 // we now have a token or a phrase
196
197 // see if we've reached the end of the line
[7705]198 if (c1 == '\n' || c1 == '\r') {
[3417]199 if (curvalue != "\\") { // the line DOESN'T continue. End of line.
200 values.push_back(curvalue);
[7705]201 break; // end of token/phrase
[3521]202 } else {
203 // swallow up the EOL chars
[7705]204 while (!filein.eof() && (c1=='\r' || c1=='\n')) filein.get(c1);
205 // the current token "\\" will be cleared below
[3417]206 }
207 } else { // no new line seen
208 values.push_back(curvalue);
209 }
[1076]210
[3417]211 curvalue.clear();
[1076]212
[3521]213 // remove whitespace (but not newline/CR chars) before next token
[7705]214 while (!filein.eof() && (c1==' ' || c1=='\t')) filein.get(c1);
[1076]215
[3417]216 } // while(1)
217
[1076]218
219 return 0;
220}
Note: See TracBrowser for help on using the repository browser.