コード例 #1
0
ファイル: opts.c プロジェクト: fmutant/scriptorium
/*
 * Actual loading subsystem, this finds the ini or cfg file, and properly
 * loads it and executes it to set compiler options.
 */
void opts_ini_init(const char *file) {
    /*
     * Possible matches are:
     *  gmqcc.ini
     *  gmqcc.cfg
     */
    char       *error = NULL;
    char       *parse_file = NULL;
    size_t     line;
    fs_file_t  *ini;

    if (!file) {
        /* try ini */
        if (!(ini = fs_file_open((file = "gmqcc.ini"), "r")))
            /* try cfg */
            if (!(ini = fs_file_open((file = "gmqcc.cfg"), "r")))
                return;
    } else if (!(ini = fs_file_open(file, "r")))
        return;

    con_out("found ini file `%s`\n", file);

    parse_file = util_strdup(file);
    if ((line = opts_ini_parse(ini, &opts_ini_load, &error, &parse_file)) != 0) {
        /* there was a parse error with the ini file */
        con_printmsg(LVL_ERROR, parse_file, line, 0 /*TODO: column for ini error*/, "error", error);
        vec_free(error);
    }
    mem_d(parse_file);

    fs_file_close(ini);
}
コード例 #2
0
ファイル: test.c プロジェクト: CurrentResident/gmqcc
static bool task_template_parse(const char *file, task_template_t *tmpl, fs_file_t *fp, size_t *pad) {
    char  *data = NULL;
    char  *back = NULL;
    size_t size = 0;
    size_t line = 1;

    if (!tmpl)
        return false;

    /* top down parsing */
    while (fs_file_getline(&back, &size, fp) != FS_FILE_EOF) {
        /* skip whitespace */
        data = back;
        if (*data && (*data == ' ' || *data == '\t'))
            data++;

        switch (*data) {
            /*
             * Handle comments inside task tmpl files.  We're strict
             * about the language for fun :-)
             */
            case '/':
                if (data[1] != '/') {
                    con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error",
                        "invalid character `/`, perhaps you meant `//` ?");

                    mem_d(back);
                    return false;
                }
            case '#':
                break;

            /*
             * Empty newlines are acceptable as well, so we handle that here
             * despite being just odd since there should't be that many
             * empty lines to begin with.
             */
            case '\r':
            case '\n':
                break;


            /*
             * Now begin the actual "tag" stuff.  This works as you expect
             * it to.
             */
            case 'D':
            case 'T':
            case 'C':
            case 'E':
            case 'I':
            case 'F':
                if (data[1] != ':') {
                    con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error",
                        "expected `:` after `%c`",
                        *data
                    );
                    goto failure;
                }
                if (!task_template_generate(tmpl, *data, file, line, &data[3], pad)) {
                    con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl compile error",
                        "failed to generate for given task\n"
                    );
                    goto failure;
                }
                break;

            /*
             * Match requires it's own system since we allow multiple M's
             * for multi-line matching.
             */
            case 'M':
            {
                char *value = &data[3];
                if (data[1] != ':') {
                    con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error",
                        "expected `:` after `%c`",
                        *data
                    );
                    goto failure;
                }

                /*
                 * Value will contain a newline character at the end, we need to strip
                 * this otherwise kaboom, seriously, kaboom :P
                 */
                if (strrchr(value, '\n'))
                    *strrchr(value, '\n')='\0';
                else /* cppcheck: possible null pointer dereference */
                    exit(EXIT_FAILURE);

                vec_push(tmpl->comparematch, util_strdup(value));

                break;
            }

            default:
                con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "tmpl parse error",
                    "invalid tag `%c`", *data
                );
                goto failure;
            /* no break required */
        }

        /* update line and free old sata */
        line++;
        mem_d(back);
        back = NULL;
    }
    if (back)
        mem_d(back);
    return true;

failure:
    mem_d (back);
    return false;
}
コード例 #3
0
ファイル: test.c プロジェクト: CurrentResident/gmqcc
/*
 * This is very much like a compiler code generator :-).  This generates
 * a value from some data observed from the compiler.
 */
static bool task_template_generate(task_template_t *tmpl, char tag, const char *file, size_t line, char *value, size_t *pad) {
    size_t desclen = 0;
    size_t filelen = 0;
    char **destval = NULL;

    if (!tmpl)
        return false;

    switch(tag) {
        case 'D': destval = &tmpl->description;    break;
        case 'T': destval = &tmpl->proceduretype;  break;
        case 'C': destval = &tmpl->compileflags;   break;
        case 'E': destval = &tmpl->executeflags;   break;
        case 'I': destval = &tmpl->sourcefile;     break;
        case 'F': destval = &tmpl->testflags;      break;
        default:
            con_printmsg(LVL_ERROR, __FILE__, __LINE__, 0, "internal error",
                "invalid tag `%c:` during code generation\n",
                tag
            );
            return false;
    }

    /*
     * Ensure if for the given tag, there already exists a
     * assigned value.
     */
    if (*destval) {
        con_printmsg(LVL_ERROR, file, line, 0, /*TODO: column for match*/ "compile error",
            "tag `%c:` already assigned value: %s\n",
            tag, *destval
        );
        return false;
    }

    /*
     * Strip any whitespace that might exist in the value for assignments
     * like "D:      foo"
     */
    if (value && *value && (*value == ' ' || *value == '\t'))
        value++;
    else if (!value)
        exit(EXIT_FAILURE);

    /*
     * Value will contain a newline character at the end, we need to strip
     * this otherwise kaboom, seriously, kaboom :P
     */
    if (strchr(value, '\n'))
        *strrchr(value, '\n')='\0';

    /*
     * Now allocate and set the actual value for the specific tag. Which
     * was properly selected and can be accessed with *destval.
     */
    *destval = util_strdup(value);


    if (*destval == tmpl->description) {
        /*
         * Create some padding for the description to align the
         * printing of the rules file.
         */
        if ((desclen = strlen(tmpl->description)) > pad[0])
            pad[0] = desclen;
    }

    if ((filelen = strlen(file)) > pad[2])
        pad[2] = filelen;

    return true;
}