libconfused/confused_runtime.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. listify
  2. 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
}

/* [<][>][^][v][top][bottom][index][help] */