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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.181  
changed lines
  Added in v.220

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