/[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 181 - (hide annotations)
Sun Jan 4 15:47:16 2004 UTC (20 years, 2 months ago) by frodo
File MIME type: text/plain
File size: 11308 byte(s)
(Frodo) Preparation for the conversion to Unicode.

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

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