confused/confused.c

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

DEFINITIONS

This source file includes following functions.
  1. header
  2. main

/* $Id: confused.c,v 1.1.1.1 1998/07/29 15:14:28 proff Exp $
 * $Copyright:$
 */

/*
 * short, but sweet
 */

#include "libproff.h"

#define cf_string 0
#define cf_stringl 1
#define cf_bool 2
#define cf_int 3
#define cf_time 4

char *cftypes[] = {"char *", "struct strList *", "bool", "int", "long"};
char *cftypes2[] = {"cf_string", "cf_stringl", "cf_bool", "cf_int", "cf_time"};

struct cfa
{
        struct cfa *next;
        char *name;
        char *def;
        int type;
};

void header (FILE *fh, char *name)
/* [<][>][^][v][top][bottom][index][help] */
{
        fprintf (fh, "\
/*\n\
 * do not edit this file, as it was automatically generated by the `confused' program!\n\
 * instead edit the source file '%s' then re-create this file using `confused'.\n\
 */\n\n", name);
}

int main (int argc, char **argv)
/* [<][>][^][v][top][bottom][index][help] */
{
        struct cfa *cfa = NULL, *cf = NULL;
        FILE *fin;
        FILE *fh = NULL, *fc;
        char line[4096];
        char base[1024];
        char fnh[1024];
        char fnc[1024];
        char s1[256], s2[256], s3[1024];
        char *in = argv[1];
        char *p;

        if (argc != 2 || !strstr (in, ".cf"))
        {
                fprintf (stderr, "usage: %s file.cf\n", argv[0]);
                exit (1);
        }
        if (!(fin = fopen (in, "r")))
        {
                perror (in);
                exit (1);
        }
        while (fgets (line, sizeof line, fin))
        {
                strStripLeftRight (line);
                if (*line == '#' || !*line)
                        continue;
                *s1 = *s2 = *s3 = '\0';
                sscanf (line, "%255s %255s %255[^\r\n]", s1, s2, s3);
                if (!cfa)
                        cf = cfa = malloc (sizeof *cfa);
                else
                {
                        cf->next = malloc (sizeof *cfa);
                        cf = cf->next;
                }
                cf->name = strdup (s2);
                cf->def = strdup (s3);
                if (strEq (s1, "string"))
                        cf->type = cf_string;
                else if (strEq (s1, "stringl"))
                        cf->type = cf_stringl;
                else if (strEq (s1, "bool"))
                        cf->type = cf_bool;
                else if (strEq (s1, "int"))
                        cf->type = cf_int;
                else if (strEq (s1, "time"))
                        cf->type = cf_time;
                cf->next = NULL;
        }
        if (ferror (fin))
                goto err;
        p = strrchr(in, '/');
        strcpy (base, p? p+1: in);
        p = strrchr (base, '.');
        if (!p)
        {
            perror ("missing suffix");
            goto err;
        }
        *p = '\0';
        sprintf (fnh, "%s.h", base);
        if (!(fh = fopen (fnh, "w")))
        {
                perror (fnh);
                goto err;
        }
        sprintf (fnc, "%s.c", base);
        if (!(fc = fopen (fnc, "w")))
        {
                perror (fnc);
                goto err;
        }
        header (fh, in);
        header (fc, in);
        fprintf (fh, "#include <stdio.h>\n\n#include \"confused_runtime.h\"\n\n#define bool int\n\nstruct %s\n{", base);
        fprintf (fc, "#include \"%s\"\n\nstruct %s %s =\n{\n", fnh, base, base);
        for (cf = cfa; !ferror (fh) && !ferror (fc) && cf; cf = cf->next)
        {
                char *def;
                fprintf (fh, "\t%s %s;\n", cftypes[cf->type], cf->name);
                putc('\t', fc);
                switch (cf->type)
                {
                case cf_time:
                        fprintf (fc, "%ld", nndtoi (cf->def));
                        break;
                case cf_bool:
                        if (strCaseEq(cf->def, "true") ||
                            strCaseEq(cf->def, "yes") ||
                            strCaseEq(cf->def, "on") ||
                            strCaseEq(cf->def, "1") ||
                            strCaseEq(cf->def, "one"))
                                def = "1";
                        else
                        if (strCaseEq(cf->def, "false") ||
                            strCaseEq(cf->def, "no") ||
                            strCaseEq(cf->def, "off") ||
                            strCaseEq(cf->def, "none") ||
                            strCaseEq(cf->def, "0") ||
                            strCaseEq(cf->def, "zero"))
                                def = "0";
                        else
                        {
                                fprintf(stderr, "bad booleen value: %s\n", cf->def);
                                goto err;
                        }
                        fputs(def, fc);
                        break;
                case cf_int:
                        {
                        int i;
                        if (!strKToi(cf->def, &i))
                        {
                                fprintf(stderr, "bad integer value: %s\n", cf->def);
                                goto err;
                        }
                        fprintf (fc, "%d", i);
                        break;
                        }
                case cf_stringl:
                        fputs("NULL", fc);
                        break;
                default:
                        fputs(cf->def, fc);
                        break;
                }
                fprintf (fc, "%s\n", cf->next ? "," : "");
        }
        fprintf (fh, "};\nextern struct %s %s;\nextern struct confused_idx %s_idx[];\nextern char *confused(FILE *, char *, struct confused_idx *con_idx);\n", base, base, base);
        fprintf (fc, "};\n\nstruct confused_idx %s_idx[] =\n{\n", base);
        for (cf = cfa; !ferror (fh) && !ferror (fc) && cf; cf = cf->next)
        {
                fprintf (fc, "\t{\"%s\", %s, (void *)&%s.%s},\n", cf->name, cftypes2[cf->type], base, cf->name);
        }
        fputs ("\t{NULL, cf_none, NULL}\n};\n", fc);
        if (ferror (fh) || ferror (fc))
                goto err;
        fclose (fin);
        fclose (fh);
        fclose (fc);
        exit (0);
      err:
        fprintf (stderr, "%s error : deleted outputs\n", argv[0]);
        fclose (fin);
        fclose (fh);
        unlink (fnh);
        unlink (fnc);
        exit (1);
}

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