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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 217 - (hide 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 frodo 168 /*
2     configuration.c - Part of psiconv, a PSION 5 file formats converter
3 frodo 196 Copyright (c) 1999-2004 Frodo Looijaard <frodol@dds.nl>
4 frodo 168
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 frodo 184 #include "compat.h"
22 frodo 173 #include "error.h"
23 frodo 181 #include "unicode.h"
24 frodo 180
25 frodo 168 #include <stdio.h>
26     #include <stdlib.h>
27     #include <string.h>
28 frodo 193 #include <strings.h>
29 frodo 180 #include <sys/types.h>
30     #include <sys/stat.h>
31     #include <unistd.h>
32     #include <fcntl.h>
33 frodo 168
34     #include "configuration.h"
35    
36     #ifdef DMALLOC
37     #include <dmalloc.h>
38     #endif
39    
40     #ifndef CONFIGURATION_SEARCH_PATH
41 frodo 197 #define CONFIGURATION_SEARCH_PATH PSICONVETCDIR "/psiconv.conf:~/.psiconv.conf"
42 frodo 168 #endif
43 frodo 180 static struct psiconv_config_s default_config =
44 frodo 181 { PSICONV_VERB_WARN, 2, 0,0,0,psiconv_bool_false,NULL,'?' };
45 frodo 168
46 frodo 180 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 frodo 168 {
59 frodo 180 psiconv_config result;
60     result = malloc(sizeof(*result));
61     *result = default_config;
62     return result;
63 frodo 168 }
64    
65 frodo 208 void psiconv_config_free(psiconv_config config)
66 frodo 204 {
67     free(config);
68     }
69    
70 frodo 180 void psiconv_config_parse_statement(const char *filename,
71     int linenr,
72     const char *var, int value,
73     psiconv_config *config)
74     {
75 frodo 181 int charnr;
76    
77 frodo 180 if (!(strcasecmp(var,"verbosity"))) {
78 frodo 217 if ((value >= 1) && (value <= 5))
79 frodo 180 (*config)->verbosity = value;
80     else
81 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
82 frodo 185 "Verbosity should be between 1 and 5",filename,linenr);
83 frodo 180 } else if (!(strcasecmp(var,"color"))) {
84     if ((value == 0) || (value == 1))
85     (*config)->color = value;
86     else
87 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
88 frodo 180 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
94 frodo 180 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
100 frodo 180 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
106 frodo 180 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
112 frodo 180 "BlueBits should be between 1 and 32 or 0",filename,linenr);
113 frodo 181 } else if (!(strcasecmp(var,"characterset"))) {
114 frodo 182 if ((value >= 0) && (value <= 1))
115 frodo 181 psiconv_unicode_select_characterset(*config,value);
116     else
117 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
118 frodo 217 "CharacterSet should be between 0 and 1",
119 frodo 181 filename,linenr);
120     } else if (!(strcasecmp(var,"unknownunicodechar"))) {
121     if ((value >= 1) && (value < 0x10000))
122     (*config)->unknown_unicode_char = value;
123     else
124 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
125 frodo 181 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
132 frodo 181 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
137 frodo 181 "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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
143 frodo 181 "CharXXX should be between 1 and 65535",
144     filename,linenr);
145 frodo 180 } else {
146 frodo 200 psiconv_error(*config,0,0,"Configuration file %s, line %d: "
147 frodo 180 "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 frodo 168
153    
154 frodo 180 void psiconv_config_parse_line(const char *filename, int linenr,
155     const char *line, psiconv_config *config)
156 frodo 168 {
157 frodo 180
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 frodo 200 if (sovar == eovar) {
173     psiconv_error(*config,0,0,"Configuration file %s, line %d: "
174 frodo 180 "Syntax error (no variable found)",filename,linenr);
175 frodo 200 return;
176     }
177 frodo 180 soval = eovar;
178     while (line[soval] && (line[soval] <= 32))
179     soval ++;
180 frodo 200 if (line[soval] != '=') {
181     psiconv_error(*config,0,0,"Configuration file %s, line %d: "
182 frodo 180 "Syntax error (no = token found)",filename,linenr);
183 frodo 200 return;
184     }
185 frodo 180 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 frodo 200 if (eoval == soval) {
192     psiconv_error(*config,0,0,"Configuration file %s, line %d: "
193 frodo 180 "Syntax error (no value found)",filename,linenr);
194 frodo 200 return;
195     }
196     if (soval - eoval > 7) {
197     psiconv_error(*config,0,0,"Configuration file %s, line %d: "
198 frodo 180 "Syntax error (value too large)",filename,linenr);
199 frodo 200 return;
200     }
201 frodo 180 eol = eoval;
202     while (line[eol] && (line[eol] < 32))
203     eol ++;
204 frodo 200 if (line[eol]) {
205     psiconv_error(*config,0,0,"Configuration file %s, line %d: "
206 frodo 180 "Syntax error (trailing garbage)",filename,linenr);
207 frodo 200 return;
208     }
209 frodo 180
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 frodo 168 struct stat stat_buf;
225 frodo 180 off_t filesize,bytes_left,bytes_read,sol,eol;
226     char *filebuffer,*filebuffer_ptr;
227 frodo 168
228 frodo 180 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 frodo 200 goto ERROR0;
234 frodo 180
235     /* Read the contents of the file into filebuffer. This may fail */
236     if (fstat(file,&stat_buf)) {
237     if (close(file))
238 frodo 200 psiconv_error(*config,0,0,"Configuration file %s: "
239 frodo 180 "Couldn't close file",filename);
240     return;
241     }
242    
243     filesize = stat_buf.st_size;
244 frodo 200 if (!(filebuffer = malloc(filesize + 1))) {
245     psiconv_error(*config,0,0,"Configuration file %s: "
246 frodo 180 "Out of memory error",filename);
247 frodo 200 goto ERROR1;
248     }
249    
250 frodo 180 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 frodo 200 psiconv_error(*config,0,0,"Configuration file %s: "
264 frodo 180 "Couldn't read file into memory",filename);
265 frodo 200 goto ERROR2;
266 frodo 180 }
267    
268 frodo 200 if (close(file)) {
269     psiconv_error(*config,0,0,"Configuration file %s: "
270 frodo 180 "Couldn't close file",filename);
271 frodo 200 file = -1;
272     goto ERROR2;
273     }
274     file = -1;
275 frodo 180
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 frodo 200 if ((eol < filesize) && (filebuffer[eol] == 0)) {
290     psiconv_error(*config,0,0,"Configuration file %s, line %d: "
291 frodo 180 "Unexpected character \000 found",filename,linenr);
292 frodo 200 goto ERROR2;
293     }
294 frodo 180 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 frodo 200 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 frodo 180 }
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 frodo 168 /* 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 frodo 180 strcat(path,extra_config_files);
331 frodo 168 } else {
332 frodo 180 path = strdup(CONFIGURATION_SEARCH_PATH);
333 frodo 168 }
334    
335     pathptr = path;
336     while (strlen(pathptr)) {
337     /* Isolate the next filename */
338 frodo 180 filename_len = (index(pathptr,':')?(index(pathptr,':') - pathptr):
339     strlen(pathptr));
340 frodo 168 filename = malloc(filename_len + 1);
341 frodo 180 filename = strncpy(filename,pathptr,filename_len);
342     filename[filename_len] = 0;
343 frodo 168 pathptr += filename_len;
344     if (strlen(pathptr))
345     pathptr ++;
346    
347 frodo 180 /* 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 frodo 168 }
357     }
358 frodo 180
359     psiconv_config_parse_file(filename,config);
360     free(filename);
361 frodo 168 }
362 frodo 208 free(path);
363 frodo 168 }

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