/[public]/psiconv/trunk/lib/psiconv/configuration.c
ViewVC logotype

Contents of /psiconv/trunk/lib/psiconv/configuration.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 217 - (show annotations)
Sun Feb 22 22:24:39 2004 UTC (20 years, 1 month ago) by frodo
File MIME type: text/plain
File size: 11832 byte(s)
(Frodo) UTF8 work (it should now actually work!)

  * Replaced psiconv_unicode_from_char with psiconv_unicode_read_char
    and removed psiconv_unicode_from_chars
  * Replaced psiconv_unicode_to_char with psiconv_unicode_write_char
    and removed psiconv_unicode_to_chars
  * Rewrote psiconv_parse_text_section to be more sane, easier to read
    and to work with the above updates
  * Updated all places where the psiconv_unicode_from/to_char calls
    were used
  * Updated psiconv.conf.eg to reflect the correct character set numbers
  * Fixed a buglet that made it impossible to set verbosity to 5 in config
  * Removed strange code in make_printable
  * Rewrote the ENCODING_PSION option in the psiconv program to work
    with the new definitions.

1 /*
2 configuration.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 1999-2004 Frodo Looijaard <frodol@dds.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "config.h"
21 #include "compat.h"
22 #include "error.h"
23 #include "unicode.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33
34 #include "configuration.h"
35
36 #ifdef DMALLOC
37 #include <dmalloc.h>
38 #endif
39
40 #ifndef CONFIGURATION_SEARCH_PATH
41 #define CONFIGURATION_SEARCH_PATH PSICONVETCDIR "/psiconv.conf:~/.psiconv.conf"
42 #endif
43 static struct psiconv_config_s default_config =
44 { PSICONV_VERB_WARN, 2, 0,0,0,psiconv_bool_false,NULL,'?' };
45
46 static void psiconv_config_parse_statement(const char *filename,
47 int linenr,
48 const char *var, int value,
49 psiconv_config *config);
50
51 static void psiconv_config_parse_line(const char *filename, int linenr,
52 const char *line, psiconv_config *config);
53
54 static void psiconv_config_parse_file(const char *filename,
55 psiconv_config *config);
56
57 psiconv_config psiconv_config_default(void)
58 {
59 psiconv_config result;
60 result = malloc(sizeof(*result));
61 *result = default_config;
62 return result;
63 }
64
65 void psiconv_config_free(psiconv_config config)
66 {
67 free(config);
68 }
69
70 void psiconv_config_parse_statement(const char *filename,
71 int linenr,
72 const char *var, int value,
73 psiconv_config *config)
74 {
75 int charnr;
76
77 if (!(strcasecmp(var,"verbosity"))) {
78 if ((value >= 1) && (value <= 5))
79 (*config)->verbosity = value;
80 else
81 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
82 "Verbosity should be between 1 and 5",filename,linenr);
83 } else if (!(strcasecmp(var,"color"))) {
84 if ((value == 0) || (value == 1))
85 (*config)->color = value;
86 else
87 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
88 "Color should be 0 or 1",filename,linenr);
89 } else if (!(strcasecmp(var,"colordepth"))) {
90 if ((value > 0) && (value <= 32))
91 (*config)->colordepth = value;
92 else
93 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
94 "ColorDepth should be between 1 and 32",filename,linenr);
95 } else if (!(strcasecmp(var,"redbits"))) {
96 if ((value >= 0) && (value <= 32))
97 (*config)->redbits = value;
98 else
99 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
100 "RedBits should be between 1 and 32 or 0",filename,linenr);
101 } else if (!(strcasecmp(var,"greenbits"))) {
102 if ((value >= 0) && (value <= 32))
103 (*config)->greenbits = value;
104 else
105 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
106 "GreenBits should be between 1 and 32 or 0",filename,linenr);
107 } else if (!(strcasecmp(var,"bluebits"))) {
108 if ((value >= 0) && (value <= 32))
109 (*config)->bluebits = value;
110 else
111 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
112 "BlueBits should be between 1 and 32 or 0",filename,linenr);
113 } else if (!(strcasecmp(var,"characterset"))) {
114 if ((value >= 0) && (value <= 1))
115 psiconv_unicode_select_characterset(*config,value);
116 else
117 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
118 "CharacterSet should be between 0 and 1",
119 filename,linenr);
120 } else if (!(strcasecmp(var,"unknownunicodechar"))) {
121 if ((value >= 1) && (value < 0x10000))
122 (*config)->unknown_unicode_char = value;
123 else
124 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
125 "UnknownUnicodeChar should be between 1 and 65535",
126 filename,linenr);
127 } else if (!(strcasecmp(var,"unknownepocchar"))) {
128 if ((value >= 1) && (value < 0x100))
129 (*config)->unknown_epoc_char = value;
130 else
131 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
132 "UnknownEPOCChar should be between 1 and 255",
133 filename,linenr);
134 } else if (sscanf(var,"char%d",&charnr) == strlen(var)) {
135 if ((charnr < 0) || (charnr > 255))
136 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
137 "CharXXX should have XXX between 0 and 255",
138 filename,linenr);
139 if ((value >= 1) && (value <= 0x10000))
140 (*config)->unicode_table[charnr] = value;
141 else
142 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
143 "CharXXX should be between 1 and 65535",
144 filename,linenr);
145 } else {
146 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
147 "Unknown variable %s",filename,linenr,var);
148 }
149 psiconv_debug(*config,0,0,"Configuration file %s, line %d: "
150 "Set variable %s to %d",filename,linenr,var,value);
151 }
152
153
154 void psiconv_config_parse_line(const char *filename, int linenr,
155 const char *line, psiconv_config *config)
156 {
157
158 int sovar,eovar,soval,eoval,eol;
159 char *var;
160 long val;
161
162 psiconv_debug(*config,0,0,"Going to parse line %d: %s",linenr,line);
163 sovar = 0;
164 while (line[sovar] && (line[sovar] < 32))
165 sovar ++;
166 if (!line[sovar] || line[sovar] == '#')
167 return;
168 eovar = sovar;
169 while (line[eovar] && (((line[eovar] >= 'A') && (line[eovar] <= 'Z')) ||
170 ((line[eovar] >= 'a') && (line[eovar] <= 'z'))))
171 eovar ++;
172 if (sovar == eovar) {
173 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
174 "Syntax error (no variable found)",filename,linenr);
175 return;
176 }
177 soval = eovar;
178 while (line[soval] && (line[soval] <= 32))
179 soval ++;
180 if (line[soval] != '=') {
181 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
182 "Syntax error (no = token found)",filename,linenr);
183 return;
184 }
185 soval ++;
186 while (line[soval] && (line[soval] <= 32))
187 soval ++;
188 eoval = soval;
189 while (line[eoval] && ((line[eoval] >= '0') && (line[eovar] <= '9')))
190 eoval ++;
191 if (eoval == soval) {
192 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
193 "Syntax error (no value found)",filename,linenr);
194 return;
195 }
196 if (soval - eoval > 7) {
197 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
198 "Syntax error (value too large)",filename,linenr);
199 return;
200 }
201 eol = eoval;
202 while (line[eol] && (line[eol] < 32))
203 eol ++;
204 if (line[eol]) {
205 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
206 "Syntax error (trailing garbage)",filename,linenr);
207 return;
208 }
209
210 var = malloc(eovar - sovar + 1);
211 memcpy(var,line + sovar, eovar - sovar);
212 var[eovar-sovar] = 0;
213
214 val = atol(line + soval);
215
216 psiconv_config_parse_statement(filename,linenr,var,val,config);
217 free(var);
218 }
219
220
221 void psiconv_config_parse_file(const char *filename, psiconv_config *config)
222 {
223 int file,linenr;
224 struct stat stat_buf;
225 off_t filesize,bytes_left,bytes_read,sol,eol;
226 char *filebuffer,*filebuffer_ptr;
227
228 psiconv_progress(*config,0,0,
229 "Going to access configuration file %s",filename);
230
231 /* Try to open the file; it may fail, if it does not exist for example */
232 if ((file = open(filename,O_RDONLY)) == -1)
233 goto ERROR0;
234
235 /* Read the contents of the file into filebuffer. This may fail */
236 if (fstat(file,&stat_buf)) {
237 if (close(file))
238 psiconv_error(*config,0,0,"Configuration file %s: "
239 "Couldn't close file",filename);
240 return;
241 }
242
243 filesize = stat_buf.st_size;
244 if (!(filebuffer = malloc(filesize + 1))) {
245 psiconv_error(*config,0,0,"Configuration file %s: "
246 "Out of memory error",filename);
247 goto ERROR1;
248 }
249
250 filebuffer_ptr = filebuffer;
251 bytes_left = filesize;
252 bytes_read = 1; /* Dummy for the first time through the loop */
253 while ((bytes_read > 0) && bytes_left) {
254 bytes_read = read(file,filebuffer_ptr,bytes_left);
255 if (bytes_read > 0) {
256 filebuffer_ptr += bytes_read;
257 bytes_left -= bytes_read;
258 }
259 }
260
261 /* On NFS, the first read may fail and this is not fatal */
262 if (bytes_left && (bytes_left != filesize)) {
263 psiconv_error(*config,0,0,"Configuration file %s: "
264 "Couldn't read file into memory",filename);
265 goto ERROR2;
266 }
267
268 if (close(file)) {
269 psiconv_error(*config,0,0,"Configuration file %s: "
270 "Couldn't close file",filename);
271 file = -1;
272 goto ERROR2;
273 }
274 file = -1;
275
276 psiconv_progress(*config,0,0,
277 "Going to parse configuration file %s: ",filename);
278 /* Now we walk through the file to isolate lines */
279 linenr = 0;
280 sol = 0;
281
282 while (sol < filesize) {
283 linenr ++;
284 eol = sol;
285 while ((eol < filesize) && (filebuffer[eol] != 13) &&
286 (filebuffer[eol] != 10) && (filebuffer[eol] != 0))
287 eol ++;
288
289 if ((eol < filesize) && (filebuffer[eol] == 0)) {
290 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
291 "Unexpected character \000 found",filename,linenr);
292 goto ERROR2;
293 }
294 if ((eol < filesize + 1) &&
295 (((filebuffer[eol] == 13) && (filebuffer[eol+1] == 10)) ||
296 ((filebuffer[eol] == 10) && (filebuffer[eol+1] == 13)))) {
297 filebuffer[eol] = 0;
298 eol ++;
299 }
300 filebuffer[eol] = 0;
301 psiconv_config_parse_line(filename,linenr,filebuffer + sol,config);
302 sol = eol+1;
303 }
304 free(filebuffer);
305 return;
306
307 ERROR2:
308 free(filebuffer);
309 ERROR1:
310 if ((file != -1) && close(file))
311 psiconv_error(*config,0,0,"Configuration file %s: "
312 "Couldn't close file",filename);
313 ERROR0:
314 return;
315 }
316
317 void psiconv_config_read(const char *extra_config_files,
318 psiconv_config *config)
319 {
320 char *path,*pathptr,*filename,*filename_old;
321 const char *home;
322 int filename_len;
323
324 /* Make path be the complete search path, colon separated */
325 if (extra_config_files && strlen(extra_config_files)) {
326 path = malloc(strlen(CONFIGURATION_SEARCH_PATH) +
327 strlen(extra_config_files) + 2);
328 strcpy(path,CONFIGURATION_SEARCH_PATH);
329 strcat(path,":");
330 strcat(path,extra_config_files);
331 } else {
332 path = strdup(CONFIGURATION_SEARCH_PATH);
333 }
334
335 pathptr = path;
336 while (strlen(pathptr)) {
337 /* Isolate the next filename */
338 filename_len = (index(pathptr,':')?(index(pathptr,':') - pathptr):
339 strlen(pathptr));
340 filename = malloc(filename_len + 1);
341 filename = strncpy(filename,pathptr,filename_len);
342 filename[filename_len] = 0;
343 pathptr += filename_len;
344 if (strlen(pathptr))
345 pathptr ++;
346
347 /* Do ~ substitution */
348 if ((filename[0] == '~') && ((filename[1] == '/') || filename[1] == 0)) {
349 home = getenv("HOME");
350 if (home) {
351 filename_old = filename;
352 filename = malloc(strlen(filename_old) + strlen(home));
353 strcpy(filename,home);
354 strcpy(filename + strlen(filename),filename_old+1);
355 free(filename_old);
356 }
357 }
358
359 psiconv_config_parse_file(filename,config);
360 free(filename);
361 }
362 free(path);
363 }

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26