kernel - swapcache - vm_object_page_remove()
[dragonfly.git] / gnu / lib / libdialog / rc.c
blob208a3775e0408641c4fab44d8e046a2b0105284d
1 /*
2 * rc.c -- routines for processing the configuration file
4 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * $DragonFly: src/gnu/lib/libdialog/rc.c,v 1.2 2005/06/04 13:42:28 eirikn Exp $
23 #include <dialog.h>
24 #include "dialog.priv.h"
25 #include "colors.h"
26 #include "rc.h"
29 static unsigned char *attr_to_str(int fg, int bg, int hl);
30 static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl);
31 static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value);
35 * Create the configuration file
37 void dialog_create_rc(unsigned char *filename)
39 int i;
40 FILE *rc_file;
42 if ((rc_file = fopen(filename, "wt")) == NULL) {
43 fprintf(stderr, "\nError opening file for writing in create_rc().\n");
44 exit(-1);
47 fprintf(rc_file, "#\
48 \n# Run-time configuration file for dialog\
49 \n#\
50 \n# Automatically generated by \"dialog --create-rc <file>\"\
51 \n#\
52 \n#\
53 \n# Types of values:\
54 \n#\
55 \n# Number - <number>\
56 \n# String - \"string\"\
57 \n# Boolean - <ON|OFF>\
58 \n# Attribute - (foreground,background,highlight?)\
59 \n#\n\n");
61 /* Print an entry for each configuration variable */
62 for (i = 0; i < VAR_COUNT; i++) {
63 fprintf(rc_file, "\n# %s\n", vars[i].comment); /* print comment */
64 switch (vars[i].type) {
65 case VAL_INT:
66 fprintf(rc_file, "%s = %d\n", vars[i].name, *((int *) vars[i].var));
67 break;
68 case VAL_STR:
69 fprintf(rc_file, "%s = \"%s\"\n", vars[i].name, (unsigned char *) vars[i].var);
70 break;
71 case VAL_BOOL:
72 fprintf(rc_file, "%s = %s\n", vars[i].name, *((bool *) vars[i].var) ? "ON" : "OFF");
73 break;
74 case VAL_ATTR:
75 fprintf(rc_file, "%s = %s\n", vars[i].name, attr_to_str(((int *) vars[i].var)[0], ((int *) vars[i].var)[1], ((int *) vars[i].var)[2]));
76 break;
80 fclose(rc_file);
82 /* End of create_rc() */
86 * Parse the configuration file and set up variables
88 int parse_rc(void)
90 int i, l = 1, parse, fg, bg, hl;
91 unsigned char str[MAX_LEN+1], *var, *value, *tempptr;
92 FILE *rc_file = NULL;
96 * At start, 'dialog' determines the settings to use as follows:
98 * a) if environment variable DIALOGRC is set, it's value determines the
99 * name of the configuration file.
101 * b) if the file in (a) can't be found, use the file $HOME/.dialogrc
102 * as the configuration file.
104 * c) if the file in (b) can't be found, use compiled in defaults.
108 if ((tempptr = getenv("DIALOGRC")) != NULL)
109 rc_file = fopen(tempptr, "rt");
111 if (tempptr == NULL || rc_file == NULL) { /* step (a) failed? */
112 /* try step (b) */
113 if ((tempptr = getenv("HOME")) == NULL)
114 return 0; /* step (b) failed, use default values */
116 if (tempptr[0] == '\0' || lastch(tempptr) == '/')
117 sprintf(str, "%s%s", tempptr, DIALOGRC);
118 else
119 sprintf(str, "%s/%s", tempptr, DIALOGRC);
121 if ((rc_file = fopen(str, "rt")) == NULL)
122 return 0; /* step (b) failed, use default values */
125 /* Scan each line and set variables */
126 while (fgets(str, MAX_LEN, rc_file) != NULL) {
127 if (lastch(str) != '\n') { /* ignore rest of file if line too long */
128 fprintf(stderr, "\nParse error: line %d of configuration file too long.\n", l);
129 fclose(rc_file);
130 return -1; /* parse aborted */
132 else {
133 lastch(str) = '\0';
134 parse = parse_line(str, &var, &value); /* parse current line */
136 switch (parse) {
137 case LINE_BLANK: /* ignore blank lines and comments */
138 case LINE_COMMENT:
139 break;
140 case LINE_OK:
141 /* search table for matching config variable name */
142 for (i = 0; i < VAR_COUNT && strcmp(vars[i].name, var); i++);
144 if (i == VAR_COUNT) { /* no match */
145 fprintf(stderr, "\nParse error: unknown variable at line %d of configuration file.\n", l);
146 return -1; /* parse aborted */
148 else { /* variable found in table, set run time variables */
149 switch (vars[i].type) {
150 case VAL_INT:
151 *((int *) vars[i].var) = atoi(value);
152 break;
153 case VAL_STR:
154 if (!isquote(value[0]) || !isquote(lastch(value)) || strlen(value) < 2) {
155 fprintf(stderr, "\nParse error: string value expected at line %d of configuration file.\n", l);
156 return -1; /* parse aborted */
158 else {
159 /* remove the (") quotes */
160 value++;
161 lastch(value) = '\0';
162 strcpy((unsigned char *) vars[i].var, value);
164 break;
165 case VAL_BOOL:
166 if (!strcasecmp(value, "ON"))
167 *((bool *) vars[i].var) = TRUE;
168 else if (!strcasecmp(value, "OFF"))
169 *((bool *) vars[i].var) = FALSE;
170 else {
171 fprintf(stderr, "\nParse error: boolean value expected at line %d of configuration file.\n", l);
172 return -1; /* parse aborted */
174 break;
175 case VAL_ATTR:
176 if (str_to_attr(value, &fg, &bg, &hl) == -1) {
177 fprintf(stderr, "\nParse error: attribute value expected at line %d of configuration file.\n", l);
178 return -1; /* parse aborted */
180 ((int *) vars[i].var)[0] = fg;
181 ((int *) vars[i].var)[1] = bg;
182 ((int *) vars[i].var)[2] = hl;
183 break;
186 break;
187 case LINE_ERROR:
188 fprintf(stderr, "\nParse error: syntax error at line %d of configuration file.\n", l);
189 return -1; /* parse aborted */
193 l++; /* next line */
196 fclose(rc_file);
197 return 0; /* parse successful */
199 /* End of parse_rc() */
203 * Convert an attribute to a string representation like this:
205 * "(foreground,background,highlight)"
207 static unsigned char *attr_to_str(int fg, int bg, int hl)
209 int i;
210 static unsigned char str[MAX_LEN+1];
212 strcpy(str, "(");
213 /* foreground */
214 for (i = 0; fg != color_names[i].value; i++);
215 strcat(str, color_names[i].name);
216 strcat(str, ",");
218 /* background */
219 for (i = 0; bg != color_names[i].value; i++);
220 strcat(str, color_names[i].name);
222 /* highlight */
223 strcat(str, hl ? ",ON)" : ",OFF)");
225 return str;
227 /* End of attr_to_str() */
231 * Extract the foreground, background and highlight values from an attribute
232 * represented as a string in this form:
234 * "(foreground,background,highlight)"
236 static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl)
238 int i = 0, j, get_fg = 1;
239 unsigned char tempstr[MAX_LEN+1], *part;
241 if (str[0] != '(' || lastch(str) != ')')
242 return -1; /* invalid representation */
244 /* remove the parenthesis */
245 strcpy(tempstr, str + 1);
246 lastch(tempstr) = '\0';
248 *fg = 0; /* fix compiler warning */
250 /* get foreground and background */
252 while (1) {
253 /* skip white space before fg/bg string */
254 while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
255 if (tempstr[i] == '\0')
256 return -1; /* invalid representation */
257 part = tempstr + i; /* set 'part' to start of fg/bg string */
259 /* find end of fg/bg string */
260 while(!whitespace(tempstr[i]) && tempstr[i] != ',' && tempstr[i] != '\0') i++;
262 if (tempstr[i] == '\0')
263 return -1; /* invalid representation */
264 else if (whitespace(tempstr[i])) { /* not yet ',' */
265 tempstr[i++] = '\0';
267 /* skip white space before ',' */
268 while(whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
270 if (tempstr[i] != ',')
271 return -1; /* invalid representation */
274 tempstr[i++] = '\0'; /* skip the ',' */
275 for (j = 0; j < COLOR_COUNT && strcasecmp(part, color_names[j].name); j++);
276 if (j == COLOR_COUNT) /* invalid color name */
277 return -1;
278 if (get_fg) {
279 *fg = color_names[j].value;
280 get_fg = 0; /* next we have to get the background */
282 else {
283 *bg = color_names[j].value;
284 break;
286 } /* got foreground and background */
289 /* get highlight */
291 /* skip white space before highlight string */
292 while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
293 if (tempstr[i] == '\0')
294 return -1; /* invalid representation */
295 part = tempstr + i; /* set 'part' to start of highlight string */
297 /* trim trailing white space from highlight string */
298 i = strlen(part) - 1;
299 while(whitespace(part[i])) i--;
300 part[i+1] = '\0';
302 if (!strcasecmp(part, "ON"))
303 *hl = TRUE;
304 else if (!strcasecmp(part, "OFF"))
305 *hl = FALSE;
306 else
307 return -1; /* invalid highlight value */
309 return 0;
311 /* End of str_to_attr() */
315 * Parse a line in the configuration file
317 * Each line is of the form: "variable = value". On exit, 'var' will contain
318 * the variable name, and 'value' will contain the value string.
320 * Return values:
322 * LINE_BLANK - line is blank
323 * LINE_COMMENT - line is comment
324 * LINE_OK - line is ok
325 * LINE_ERROR - syntax error in line
327 static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value)
329 int i = 0;
331 /* ignore white space at beginning of line */
332 while(whitespace(line[i]) && line[i] != '\0') i++;
334 if (line[i] == '\0') /* line is blank */
335 return LINE_BLANK;
336 else if (line[i] == '#') /* line is comment */
337 return LINE_COMMENT;
338 else if (line[i] == '=') /* variables names can't strart with a '=' */
339 return LINE_ERROR;
341 /* set 'var' to variable name */
342 *var = line + i++; /* skip to next character */
344 /* find end of variable name */
345 while(!whitespace(line[i]) && line[i] != '=' && line[i] != '\0') i++;
347 if (line[i] == '\0') /* syntax error */
348 return LINE_ERROR;
349 else if (line[i] == '=')
350 line[i++] = '\0';
351 else {
352 line[i++] = '\0';
354 /* skip white space before '=' */
355 while(whitespace(line[i]) && line[i] != '\0') i++;
357 if (line[i] != '=') /* syntax error */
358 return LINE_ERROR;
359 else
360 i++; /* skip the '=' */
363 /* skip white space after '=' */
364 while(whitespace(line[i]) && line[i] != '\0') i++;
366 if (line[i] == '\0')
367 return LINE_ERROR;
368 else
369 *value = line + i; /* set 'value' to value string */
371 /* trim trailing white space from 'value' */
372 i = strlen(*value) - 1;
373 while(whitespace((*value)[i])) i--;
374 (*value)[i+1] = '\0';
376 return LINE_OK; /* no syntax error in line */
378 /* End of parse_line() */