libconfused/confused_runtime.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- listify
- confused
/* $Id: confused_runtime.c,v 1.1.1.1 1998/07/29 15:14:28 proff Exp $
* $Copyright:$
*/
#include "libproff.h"
#include "confused_runtime.h"
static struct strList *listify(char *s)
/* [<][>][^][v][top][bottom][index][help] */
{
struct strList *l = NULL;
for (;;)
{
char buf[1024];
char *bp;
bool f_quote = FALSE;
bool f_esc = FALSE;
SKIPWHITE(s);
if (*s == '\0')
break;
for (bp = buf; *s && (!isspace(*s) || f_esc || f_quote); s++)
{
switch (*s)
{
case '\\':
if (!f_esc)
{
f_esc = TRUE;
continue;
}
break;
case '"':
if (!f_esc)
{
f_quote = !f_quote;
continue;
}
}
*bp++ = *s;
f_esc = FALSE;
}
if (bp == buf)
continue;
*bp = '\0';
l = strListAdd(l, buf);
}
return l? l->head: NULL;
}
EXPORT char *confused (FILE *fin, char *terminator, struct confused_idx *cidx)
/* [<][>][^][v][top][bottom][index][help] */
{
#define BAD(x) {msg=(x); goto bad;}
char line[1024] = "";
char s1[256], s2_buf[1024], *s2 = s2_buf;
char *msg;
int n = 0;
int l;
for (n = 0; fgets (line, sizeof line, fin); n++)
{
struct confused_idx *idx = cidx;
strStripLeftRight (line);
if (*line == '#' || !*line)
continue;
if (strCaseEq (line, terminator))
break;
*s1 = *s2 = '\0';
if (sscanf (line, "%255s %1023[^\n]", s1, s2) != 2)
BAD ("need at least one argument")
for (idx = cidx; idx->name; idx++)
if (strCaseEq (idx->name, s1))
goto good;
BAD ("variable used is not known");
good:
strStripLeftRight (s2);
l = strlen (s2);
switch (idx->type)
{
case cf_string:
*(char **) idx->data = Xstrdup (s2);
break;
case cf_bool:
if (strCaseEq (s2, "yes") ||
strCaseEq (s2, "true") ||
strCaseEq (s2, "1") ||
strCaseEq (s2, "one") ||
strCaseEq (s2, "on"))
*(bool *) idx->data = 1;
else if (strCaseEq (s2, "no") ||
strCaseEq (s2, "false") ||
strCaseEq (s2, "0") ||
strCaseEq (s2, "zero") ||
strCaseEq (s2, "none") ||
strCaseEq (s2, "off"))
*(bool *) idx->data = 0;
else
BAD ("boolean required (yes, true, 1, one, on) or (no, false, 0, zero, one, off)");
break;
case cf_int:
if (!strKToi(s2, (int *)idx->data))
BAD ("variable requires integer");
break;
case cf_time:
if ((*(long *) idx->data = nndtoi (s2)) == -1)
BAD ("invalid time");
break;
case cf_stringl:
*(struct strList **) idx->data = listify(s2);
break;
default:
BAD ("boys in the attic");
break;
}
}
if (ferror (fin))
{
BAD ("couldn't read to the end");
}
return NULL;
bad:
{
static char errmsg[1024 + 256];
sprintf (errmsg, "%s (%d): %s", msg, n, line);
return errmsg;
}
#undef BAD
}