summaryrefslogtreecommitdiffstats
path: root/gnu/lib/libodialog/rc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/lib/libodialog/rc.c')
-rw-r--r--gnu/lib/libodialog/rc.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/gnu/lib/libodialog/rc.c b/gnu/lib/libodialog/rc.c
new file mode 100644
index 0000000..36631a6
--- /dev/null
+++ b/gnu/lib/libodialog/rc.c
@@ -0,0 +1,375 @@
+/*
+ * rc.c -- routines for processing the configuration file
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <dialog.h>
+#include "dialog.priv.h"
+#include "colors.h"
+#include "rc.h"
+
+
+static unsigned char *attr_to_str(int fg, int bg, int hl);
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl);
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value);
+
+
+/*
+ * Create the configuration file
+ */
+void dialog_create_rc(unsigned char *filename)
+{
+ int i;
+ FILE *rc_file;
+
+ if ((rc_file = fopen(filename, "wt")) == NULL) {
+ fprintf(stderr, "\nError opening file for writing in create_rc().\n");
+ exit(-1);
+ }
+
+ fprintf(rc_file, "#\
+\n# Run-time configuration file for dialog\
+\n#\
+\n# Automatically generated by \"dialog --create-rc <file>\"\
+\n#\
+\n#\
+\n# Types of values:\
+\n#\
+\n# Number - <number>\
+\n# String - \"string\"\
+\n# Boolean - <ON|OFF>\
+\n# Attribute - (foreground,background,highlight?)\
+\n#\n\n");
+
+ /* Print an entry for each configuration variable */
+ for (i = 0; i < VAR_COUNT; i++) {
+ fprintf(rc_file, "\n# %s\n", vars[i].comment); /* print comment */
+ switch (vars[i].type) {
+ case VAL_INT:
+ fprintf(rc_file, "%s = %d\n", vars[i].name, *((int *) vars[i].var));
+ break;
+ case VAL_STR:
+ fprintf(rc_file, "%s = \"%s\"\n", vars[i].name, (unsigned char *) vars[i].var);
+ break;
+ case VAL_BOOL:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, *((bool *) vars[i].var) ? "ON" : "OFF");
+ break;
+ case VAL_ATTR:
+ 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]));
+ break;
+ }
+ }
+
+ fclose(rc_file);
+}
+/* End of create_rc() */
+
+
+/*
+ * Parse the configuration file and set up variables
+ */
+int parse_rc(void)
+{
+ int i, l = 1, parse, fg, bg, hl;
+ unsigned char str[MAX_LEN+1], *var, *value, *tempptr;
+ FILE *rc_file;
+
+ /*
+ *
+ * At start, 'dialog' determines the settings to use as follows:
+ *
+ * a) if environment variable DIALOGRC is set, it's value determines the
+ * name of the configuration file.
+ *
+ * b) if the file in (a) can't be found, use the file $HOME/.dialogrc
+ * as the configuration file.
+ *
+ * c) if the file in (b) can't be found, use compiled in defaults.
+ *
+ */
+
+ if ((tempptr = getenv("DIALOGRC")) != NULL)
+ rc_file = fopen(tempptr, "rt");
+
+ if (tempptr == NULL || rc_file == NULL) { /* step (a) failed? */
+ /* try step (b) */
+ if ((tempptr = getenv("HOME")) == NULL)
+ return 0; /* step (b) failed, use default values */
+
+ if (tempptr[0] == '\0' || lastch(tempptr) == '/')
+ sprintf(str, "%s%s", tempptr, DIALOGRC);
+ else
+ sprintf(str, "%s/%s", tempptr, DIALOGRC);
+
+ if ((rc_file = fopen(str, "rt")) == NULL)
+ return 0; /* step (b) failed, use default values */
+ }
+
+ /* Scan each line and set variables */
+ while (fgets(str, MAX_LEN, rc_file) != NULL) {
+ if (lastch(str) != '\n') { /* ignore rest of file if line too long */
+ fprintf(stderr, "\nParse error: line %d of configuration file too long.\n", l);
+ fclose(rc_file);
+ return -1; /* parse aborted */
+ }
+ else {
+ lastch(str) = '\0';
+ parse = parse_line(str, &var, &value); /* parse current line */
+
+ switch (parse) {
+ case LINE_BLANK: /* ignore blank lines and comments */
+ case LINE_COMMENT:
+ break;
+ case LINE_OK:
+ /* search table for matching config variable name */
+ for (i = 0; i < VAR_COUNT && strcmp(vars[i].name, var); i++);
+
+ if (i == VAR_COUNT) { /* no match */
+ fprintf(stderr, "\nParse error: unknown variable at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else { /* variable found in table, set run time variables */
+ switch (vars[i].type) {
+ case VAL_INT:
+ *((int *) vars[i].var) = atoi(value);
+ break;
+ case VAL_STR:
+ if (!isquote(value[0]) || !isquote(lastch(value)) || strlen(value) < 2) {
+ fprintf(stderr, "\nParse error: string value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else {
+ /* remove the (") quotes */
+ value++;
+ lastch(value) = '\0';
+ strcpy((unsigned char *) vars[i].var, value);
+ }
+ break;
+ case VAL_BOOL:
+ if (!strcasecmp(value, "ON"))
+ *((bool *) vars[i].var) = TRUE;
+ else if (!strcasecmp(value, "OFF"))
+ *((bool *) vars[i].var) = FALSE;
+ else {
+ fprintf(stderr, "\nParse error: boolean value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ break;
+ case VAL_ATTR:
+ if (str_to_attr(value, &fg, &bg, &hl) == -1) {
+ fprintf(stderr, "\nParse error: attribute value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ ((int *) vars[i].var)[0] = fg;
+ ((int *) vars[i].var)[1] = bg;
+ ((int *) vars[i].var)[2] = hl;
+ break;
+ }
+ }
+ break;
+ case LINE_ERROR:
+ fprintf(stderr, "\nParse error: syntax error at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ }
+
+ l++; /* next line */
+ }
+
+ fclose(rc_file);
+ return 0; /* parse successful */
+}
+/* End of parse_rc() */
+
+
+/*
+ * Convert an attribute to a string representation like this:
+ *
+ * "(foreground,background,highlight)"
+ */
+static unsigned char *attr_to_str(int fg, int bg, int hl)
+{
+ int i;
+ static unsigned char str[MAX_LEN+1];
+
+ strcpy(str, "(");
+ /* foreground */
+ for (i = 0; fg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+ strcat(str, ",");
+
+ /* background */
+ for (i = 0; bg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+
+ /* highlight */
+ strcat(str, hl ? ",ON)" : ",OFF)");
+
+ return str;
+}
+/* End of attr_to_str() */
+
+
+/*
+ * Extract the foreground, background and highlight values from an attribute
+ * represented as a string in this form:
+ *
+ * "(foreground,background,highlight)"
+ */
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl)
+{
+ int i = 0, j, get_fg = 1;
+ unsigned char tempstr[MAX_LEN+1], *part;
+
+ if (str[0] != '(' || lastch(str) != ')')
+ return -1; /* invalid representation */
+
+ /* remove the parenthesis */
+ strcpy(tempstr, str + 1);
+ lastch(tempstr) = '\0';
+
+
+ /* get foreground and background */
+
+ while (1) {
+ /* skip white space before fg/bg string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of fg/bg string */
+
+ /* find end of fg/bg string */
+ while(!whitespace(tempstr[i]) && tempstr[i] != ',' && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ else if (whitespace(tempstr[i])) { /* not yet ',' */
+ tempstr[i++] = '\0';
+
+ /* skip white space before ',' */
+ while(whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] != ',')
+ return -1; /* invalid representation */
+ }
+
+ tempstr[i++] = '\0'; /* skip the ',' */
+ for (j = 0; j < COLOR_COUNT && strcasecmp(part, color_names[j].name); j++);
+ if (j == COLOR_COUNT) /* invalid color name */
+ return -1;
+ if (get_fg) {
+ *fg = color_names[j].value;
+ get_fg = 0; /* next we have to get the background */
+ }
+ else {
+ *bg = color_names[j].value;
+ break;
+ }
+ } /* got foreground and background */
+
+
+ /* get highlight */
+
+ /* skip white space before highlight string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of highlight string */
+
+ /* trim trailing white space from highlight string */
+ i = strlen(part) - 1;
+ while(whitespace(part[i])) i--;
+ part[i+1] = '\0';
+
+ if (!strcasecmp(part, "ON"))
+ *hl = TRUE;
+ else if (!strcasecmp(part, "OFF"))
+ *hl = FALSE;
+ else
+ return -1; /* invalid highlight value */
+
+ return 0;
+}
+/* End of str_to_attr() */
+
+
+/*
+ * Parse a line in the configuration file
+ *
+ * Each line is of the form: "variable = value". On exit, 'var' will contain
+ * the variable name, and 'value' will contain the value string.
+ *
+ * Return values:
+ *
+ * LINE_BLANK - line is blank
+ * LINE_COMMENT - line is comment
+ * LINE_OK - line is ok
+ * LINE_ERROR - syntax error in line
+ */
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value)
+{
+ int i = 0;
+
+ /* ignore white space at beginning of line */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* line is blank */
+ return LINE_BLANK;
+ else if (line[i] == '#') /* line is comment */
+ return LINE_COMMENT;
+ else if (line[i] == '=') /* variables names can't strart with a '=' */
+ return LINE_ERROR;
+
+ /* set 'var' to variable name */
+ *var = line + i++; /* skip to next character */
+
+ /* find end of variable name */
+ while(!whitespace(line[i]) && line[i] != '=' && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* syntax error */
+ return LINE_ERROR;
+ else if (line[i] == '=')
+ line[i++] = '\0';
+ else {
+ line[i++] = '\0';
+
+ /* skip white space before '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] != '=') /* syntax error */
+ return LINE_ERROR;
+ else
+ i++; /* skip the '=' */
+ }
+
+ /* skip white space after '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0')
+ return LINE_ERROR;
+ else
+ *value = line + i; /* set 'value' to value string */
+
+ /* trim trailing white space from 'value' */
+ i = strlen(*value) - 1;
+ while(whitespace((*value)[i])) i--;
+ (*value)[i+1] = '\0';
+
+ return LINE_OK; /* no syntax error in line */
+}
+/* End of parse_line() */
OpenPOWER on IntegriCloud