/[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 196 - (hide annotations)
Wed Feb 4 12:19:09 2004 UTC (20 years, 1 month ago) by frodo
File MIME type: text/plain
File size: 11323 byte(s)
(Frodo) Copyright dates update

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

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