/[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 180 Revision 217
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 24
24#include <stdio.h> 25#include <stdio.h>
25#include <stdlib.h> 26#include <stdlib.h>
26#include <string.h> 27#include <string.h>
28#include <strings.h>
27#include <sys/types.h> 29#include <sys/types.h>
28#include <sys/stat.h> 30#include <sys/stat.h>
29#include <unistd.h> 31#include <unistd.h>
30#include <fcntl.h> 32#include <fcntl.h>
31 33
34#ifdef DMALLOC 36#ifdef DMALLOC
35#include <dmalloc.h> 37#include <dmalloc.h>
36#endif 38#endif
37 39
38#ifndef CONFIGURATION_SEARCH_PATH 40#ifndef CONFIGURATION_SEARCH_PATH
39#define CONFIGURATION_SEARCH_PATH "/etc/psiconv.conf:~/.psiconv.conf" 41#define CONFIGURATION_SEARCH_PATH PSICONVETCDIR "/psiconv.conf:~/.psiconv.conf"
40#endif 42#endif
41static struct psiconv_config_s default_config = 43static struct psiconv_config_s default_config =
42 { PSICONV_VERB_WARN, 2, 0,0,0,psiconv_bool_false,NULL }; 44 { PSICONV_VERB_WARN, 2, 0,0,0,psiconv_bool_false,NULL,'?' };
43 45
44static void psiconv_config_parse_statement(const char *filename, 46static void psiconv_config_parse_statement(const char *filename,
45 int linenr, 47 int linenr,
46 const char *var, int value, 48 const char *var, int value,
47 psiconv_config *config); 49 psiconv_config *config);
58 result = malloc(sizeof(*result)); 60 result = malloc(sizeof(*result));
59 *result = default_config; 61 *result = default_config;
60 return result; 62 return result;
61} 63}
62 64
65void psiconv_config_free(psiconv_config config)
66{
67 free(config);
68}
69
63void psiconv_config_parse_statement(const char *filename, 70void psiconv_config_parse_statement(const char *filename,
64 int linenr, 71 int linenr,
65 const char *var, int value, 72 const char *var, int value,
66 psiconv_config *config) 73 psiconv_config *config)
67{ 74{
75 int charnr;
76
68 if (!(strcasecmp(var,"verbosity"))) { 77 if (!(strcasecmp(var,"verbosity"))) {
69 if ((value >= 1) && (value <= 4)) 78 if ((value >= 1) && (value <= 5))
70 (*config)->verbosity = value; 79 (*config)->verbosity = value;
71 else 80 else
72 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 81 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
73 "Verbosity should be between 1 and 4",filename,linenr); 82 "Verbosity should be between 1 and 5",filename,linenr);
74 } else if (!(strcasecmp(var,"color"))) { 83 } else if (!(strcasecmp(var,"color"))) {
75 if ((value == 0) || (value == 1)) 84 if ((value == 0) || (value == 1))
76 (*config)->color = value; 85 (*config)->color = value;
77 else 86 else
78 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 87 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
79 "Color should be 0 or 1",filename,linenr); 88 "Color should be 0 or 1",filename,linenr);
80 } else if (!(strcasecmp(var,"colordepth"))) { 89 } else if (!(strcasecmp(var,"colordepth"))) {
81 if ((value > 0) && (value <= 32)) 90 if ((value > 0) && (value <= 32))
82 (*config)->colordepth = value; 91 (*config)->colordepth = value;
83 else 92 else
84 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 93 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
85 "ColorDepth should be between 1 and 32",filename,linenr); 94 "ColorDepth should be between 1 and 32",filename,linenr);
86 } else if (!(strcasecmp(var,"redbits"))) { 95 } else if (!(strcasecmp(var,"redbits"))) {
87 if ((value >= 0) && (value <= 32)) 96 if ((value >= 0) && (value <= 32))
88 (*config)->redbits = value; 97 (*config)->redbits = value;
89 else 98 else
90 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 99 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
91 "RedBits should be between 1 and 32 or 0",filename,linenr); 100 "RedBits should be between 1 and 32 or 0",filename,linenr);
92 } else if (!(strcasecmp(var,"greenbits"))) { 101 } else if (!(strcasecmp(var,"greenbits"))) {
93 if ((value >= 0) && (value <= 32)) 102 if ((value >= 0) && (value <= 32))
94 (*config)->greenbits = value; 103 (*config)->greenbits = value;
95 else 104 else
96 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 105 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
97 "GreenBits should be between 1 and 32 or 0",filename,linenr); 106 "GreenBits should be between 1 and 32 or 0",filename,linenr);
98 } else if (!(strcasecmp(var,"bluebits"))) { 107 } else if (!(strcasecmp(var,"bluebits"))) {
99 if ((value >= 0) && (value <= 32)) 108 if ((value >= 0) && (value <= 32))
100 (*config)->bluebits = value; 109 (*config)->bluebits = value;
101 else 110 else
102 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 111 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
103 "BlueBits should be between 1 and 32 or 0",filename,linenr); 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);
104 } else { 145 } else {
105 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 146 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
106 "Unknown variable %s",filename,linenr,var); 147 "Unknown variable %s",filename,linenr,var);
107 } 148 }
108 psiconv_debug(*config,0,0,"Configuration file %s, line %d: " 149 psiconv_debug(*config,0,0,"Configuration file %s, line %d: "
109 "Set variable %s to %d",filename,linenr,var,value); 150 "Set variable %s to %d",filename,linenr,var,value);
110} 151}
126 return; 167 return;
127 eovar = sovar; 168 eovar = sovar;
128 while (line[eovar] && (((line[eovar] >= 'A') && (line[eovar] <= 'Z')) || 169 while (line[eovar] && (((line[eovar] >= 'A') && (line[eovar] <= 'Z')) ||
129 ((line[eovar] >= 'a') && (line[eovar] <= 'z')))) 170 ((line[eovar] >= 'a') && (line[eovar] <= 'z'))))
130 eovar ++; 171 eovar ++;
131 if (sovar == eovar) 172 if (sovar == eovar) {
132 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 173 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
133 "Syntax error (no variable found)",filename,linenr); 174 "Syntax error (no variable found)",filename,linenr);
175 return;
176 }
134 soval = eovar; 177 soval = eovar;
135 while (line[soval] && (line[soval] <= 32)) 178 while (line[soval] && (line[soval] <= 32))
136 soval ++; 179 soval ++;
137 if (line[soval] != '=') 180 if (line[soval] != '=') {
138 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 181 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
139 "Syntax error (no = token found)",filename,linenr); 182 "Syntax error (no = token found)",filename,linenr);
183 return;
184 }
140 soval ++; 185 soval ++;
141 while (line[soval] && (line[soval] <= 32)) 186 while (line[soval] && (line[soval] <= 32))
142 soval ++; 187 soval ++;
143 eoval = soval; 188 eoval = soval;
144 while (line[eoval] && ((line[eoval] >= '0') && (line[eovar] <= '9'))) 189 while (line[eoval] && ((line[eoval] >= '0') && (line[eovar] <= '9')))
145 eoval ++; 190 eoval ++;
146 if (eoval == soval) 191 if (eoval == soval) {
147 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 192 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
148 "Syntax error (no value found)",filename,linenr); 193 "Syntax error (no value found)",filename,linenr);
194 return;
195 }
149 if (soval - eoval > 7) 196 if (soval - eoval > 7) {
150 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 197 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
151 "Syntax error (value too large)",filename,linenr); 198 "Syntax error (value too large)",filename,linenr);
199 return;
200 }
152 eol = eoval; 201 eol = eoval;
153 while (line[eol] && (line[eol] < 32)) 202 while (line[eol] && (line[eol] < 32))
154 eol ++; 203 eol ++;
155 if (line[eol]) 204 if (line[eol]) {
156 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 205 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
157 "Syntax error (trailing garbage)",filename,linenr); 206 "Syntax error (trailing garbage)",filename,linenr);
207 return;
208 }
158 209
159 var = malloc(eovar - sovar + 1); 210 var = malloc(eovar - sovar + 1);
160 memcpy(var,line + sovar, eovar - sovar); 211 memcpy(var,line + sovar, eovar - sovar);
161 var[eovar-sovar] = 0; 212 var[eovar-sovar] = 0;
162 213
177 psiconv_progress(*config,0,0, 228 psiconv_progress(*config,0,0,
178 "Going to access configuration file %s",filename); 229 "Going to access configuration file %s",filename);
179 230
180 /* Try to open the file; it may fail, if it does not exist for example */ 231 /* Try to open the file; it may fail, if it does not exist for example */
181 if ((file = open(filename,O_RDONLY)) == -1) 232 if ((file = open(filename,O_RDONLY)) == -1)
182 return; 233 goto ERROR0;
183 234
184 /* Read the contents of the file into filebuffer. This may fail */ 235 /* Read the contents of the file into filebuffer. This may fail */
185 if (fstat(file,&stat_buf)) { 236 if (fstat(file,&stat_buf)) {
186 if (close(file)) 237 if (close(file))
187 psiconv_fatal(*config,0,0,"Configuration file %s: " 238 psiconv_error(*config,0,0,"Configuration file %s: "
188 "Couldn't close file",filename); 239 "Couldn't close file",filename);
189 return; 240 return;
190 } 241 }
191 242
192 filesize = stat_buf.st_size; 243 filesize = stat_buf.st_size;
193 if (!(filebuffer = malloc(filesize + 1))) 244 if (!(filebuffer = malloc(filesize + 1))) {
194 psiconv_fatal(*config,0,0,"Configuration file %s: " 245 psiconv_error(*config,0,0,"Configuration file %s: "
195 "Out of memory error",filename); 246 "Out of memory error",filename);
247 goto ERROR1;
248 }
249
196 filebuffer_ptr = filebuffer; 250 filebuffer_ptr = filebuffer;
197 bytes_left = filesize; 251 bytes_left = filesize;
198 bytes_read = 1; /* Dummy for the first time through the loop */ 252 bytes_read = 1; /* Dummy for the first time through the loop */
199 while ((bytes_read > 0) && bytes_left) { 253 while ((bytes_read > 0) && bytes_left) {
200 bytes_read = read(file,filebuffer_ptr,bytes_left); 254 bytes_read = read(file,filebuffer_ptr,bytes_left);
204 } 258 }
205 } 259 }
206 260
207 /* On NFS, the first read may fail and this is not fatal */ 261 /* On NFS, the first read may fail and this is not fatal */
208 if (bytes_left && (bytes_left != filesize)) { 262 if (bytes_left && (bytes_left != filesize)) {
209 psiconv_fatal(*config,0,0,"Configuration file %s: " 263 psiconv_error(*config,0,0,"Configuration file %s: "
210 "Couldn't read file into memory",filename); 264 "Couldn't read file into memory",filename);
265 goto ERROR2;
211 } 266 }
212 267
213 if (close(file)) 268 if (close(file)) {
214 psiconv_fatal(*config,0,0,"Configuration file %s: " 269 psiconv_error(*config,0,0,"Configuration file %s: "
215 "Couldn't close file",filename); 270 "Couldn't close file",filename);
271 file = -1;
272 goto ERROR2;
273 }
274 file = -1;
216 275
217 psiconv_progress(*config,0,0, 276 psiconv_progress(*config,0,0,
218 "Going to parse configuration file %s: ",filename); 277 "Going to parse configuration file %s: ",filename);
219 /* Now we walk through the file to isolate lines */ 278 /* Now we walk through the file to isolate lines */
220 linenr = 0; 279 linenr = 0;
225 eol = sol; 284 eol = sol;
226 while ((eol < filesize) && (filebuffer[eol] != 13) && 285 while ((eol < filesize) && (filebuffer[eol] != 13) &&
227 (filebuffer[eol] != 10) && (filebuffer[eol] != 0)) 286 (filebuffer[eol] != 10) && (filebuffer[eol] != 0))
228 eol ++; 287 eol ++;
229 288
230 if ((eol < filesize) && (filebuffer[eol] == 0)) 289 if ((eol < filesize) && (filebuffer[eol] == 0)) {
231 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: " 290 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
232 "Unexpected character \000 found",filename,linenr); 291 "Unexpected character \000 found",filename,linenr);
292 goto ERROR2;
293 }
233 if ((eol < filesize + 1) && 294 if ((eol < filesize + 1) &&
234 (((filebuffer[eol] == 13) && (filebuffer[eol+1] == 10)) || 295 (((filebuffer[eol] == 13) && (filebuffer[eol+1] == 10)) ||
235 ((filebuffer[eol] == 10) && (filebuffer[eol+1] == 13)))) { 296 ((filebuffer[eol] == 10) && (filebuffer[eol+1] == 13)))) {
236 filebuffer[eol] = 0; 297 filebuffer[eol] = 0;
237 eol ++; 298 eol ++;
239 filebuffer[eol] = 0; 300 filebuffer[eol] = 0;
240 psiconv_config_parse_line(filename,linenr,filebuffer + sol,config); 301 psiconv_config_parse_line(filename,linenr,filebuffer + sol,config);
241 sol = eol+1; 302 sol = eol+1;
242 } 303 }
243 free(filebuffer); 304 free(filebuffer);
305 return;
306
307ERROR2:
308 free(filebuffer);
309ERROR1:
310 if ((file != -1) && close(file))
311 psiconv_error(*config,0,0,"Configuration file %s: "
312 "Couldn't close file",filename);
313ERROR0:
314 return;
244} 315}
245 316
246void psiconv_config_read(const char *extra_config_files, 317void psiconv_config_read(const char *extra_config_files,
247 psiconv_config *config) 318 psiconv_config *config)
248{ 319{
286 } 357 }
287 358
288 psiconv_config_parse_file(filename,config); 359 psiconv_config_parse_file(filename,config);
289 free(filename); 360 free(filename);
290 } 361 }
362 free(path);
291} 363}

Legend:
Removed from v.180  
changed lines
  Added in v.217

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