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 $
24 #include "dialog.priv.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
)
42 if ((rc_file
= fopen(filename
, "wt")) == NULL
) {
43 fprintf(stderr
, "\nError opening file for writing in create_rc().\n");
48 \n# Run-time configuration file for dialog\
50 \n# Automatically generated by \"dialog --create-rc <file>\"\
55 \n# Number - <number>\
56 \n# String - \"string\"\
57 \n# Boolean - <ON|OFF>\
58 \n# Attribute - (foreground,background,highlight?)\
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
) {
66 fprintf(rc_file
, "%s = %d\n", vars
[i
].name
, *((int *) vars
[i
].var
));
69 fprintf(rc_file
, "%s = \"%s\"\n", vars
[i
].name
, (unsigned char *) vars
[i
].var
);
72 fprintf(rc_file
, "%s = %s\n", vars
[i
].name
, *((bool *) vars
[i
].var
) ? "ON" : "OFF");
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]));
82 /* End of create_rc() */
86 * Parse the configuration file and set up variables
90 int i
, l
= 1, parse
, fg
, bg
, hl
;
91 unsigned char str
[MAX_LEN
+1], *var
, *value
, *tempptr
;
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? */
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
);
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
);
130 return -1; /* parse aborted */
134 parse
= parse_line(str
, &var
, &value
); /* parse current line */
137 case LINE_BLANK
: /* ignore blank lines and comments */
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
) {
151 *((int *) vars
[i
].var
) = atoi(value
);
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 */
159 /* remove the (") quotes */
161 lastch(value
) = '\0';
162 strcpy((unsigned char *) vars
[i
].var
, value
);
166 if (!strcasecmp(value
, "ON"))
167 *((bool *) vars
[i
].var
) = TRUE
;
168 else if (!strcasecmp(value
, "OFF"))
169 *((bool *) vars
[i
].var
) = FALSE
;
171 fprintf(stderr
, "\nParse error: boolean value expected at line %d of configuration file.\n", l
);
172 return -1; /* parse aborted */
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
;
188 fprintf(stderr
, "\nParse error: syntax error at line %d of configuration file.\n", l
);
189 return -1; /* parse aborted */
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
)
210 static unsigned char str
[MAX_LEN
+1];
214 for (i
= 0; fg
!= color_names
[i
].value
; i
++);
215 strcat(str
, color_names
[i
].name
);
219 for (i
= 0; bg
!= color_names
[i
].value
; i
++);
220 strcat(str
, color_names
[i
].name
);
223 strcat(str
, hl
? ",ON)" : ",OFF)");
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 */
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 ',' */
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 */
279 *fg
= color_names
[j
].value
;
280 get_fg
= 0; /* next we have to get the background */
283 *bg
= color_names
[j
].value
;
286 } /* got foreground and background */
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
--;
302 if (!strcasecmp(part
, "ON"))
304 else if (!strcasecmp(part
, "OFF"))
307 return -1; /* invalid highlight value */
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.
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
)
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 */
336 else if (line
[i
] == '#') /* line is comment */
338 else if (line
[i
] == '=') /* variables names can't strart with a '=' */
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 */
349 else if (line
[i
] == '=')
354 /* skip white space before '=' */
355 while(whitespace(line
[i
]) && line
[i
] != '\0') i
++;
357 if (line
[i
] != '=') /* syntax error */
360 i
++; /* skip the '=' */
363 /* skip white space after '=' */
364 while(whitespace(line
[i
]) && line
[i
] != '\0') i
++;
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() */