/[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 180 - (hide annotations)
Sat Dec 13 23:26:37 2003 UTC (20 years, 4 months ago) by frodo
File MIME type: text/plain
File size: 9859 byte(s)
(Frodo) Add configuration file parsing support

To do: install config file on installation of psiconv, also in Debian install

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

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