Example #1
0
/**
 * non-declaration statement
 */
do_statement () {
        if (amatch ("if", 2)) {
                doif ();
                lastst = STIF;
        } else if (amatch ("while", 5)) {
                dowhile ();
                lastst = STWHILE;
        } else if (amatch ("switch", 6)) {
                doswitch ();
                lastst = STSWITCH;
        } else if (amatch ("do", 2)) {
                dodo ();
                need_semicolon ();
                lastst = STDO;
        } else if (amatch ("for", 3)) {
                dofor ();
                lastst = STFOR;
        } else if (amatch ("return", 6)) {
                doreturn ();
                need_semicolon ();
                lastst = STRETURN;
        } else if (amatch ("break", 5)) {
                dobreak ();
                need_semicolon ();
                lastst = STBREAK;
        } else if (amatch ("continue", 8)) {
                docont ();
                need_semicolon ();
                lastst = STCONT;
        } else if (match (";"))
                ;
        else if (amatch ("case", 4)) {
                docase ();
                lastst = statement (NO);
        } else if (amatch ("default", 7)) {
                dodefault ();
                lastst = statement (NO);
        } else if (match ("__asm__")) {
                doasm ();
                lastst = STASM;
        } else if (match("#")) {
                kill();
        } else if (match ("{"))
                do_compound (NO);
        else {
                expression (YES);
/*              if (match (":")) {
                        dolabel ();
                        lastst = statement (NO);
                } else {
*/                      need_semicolon ();
                        lastst = STEXP;
/*              }
*/      }
}
Example #2
0
void dofile(FILE *fp, int translating) {
    char buf[1024], sparebuf[1024], *p;

    /*
     * Command syntax is:
     *
     *  - "seed <integer>" sets a random seed
     *
     *  - "test <function> <ntests>" generates random test lines
     *
     *  - "<function> op1=foo [op2=bar]" generates a specific test
     *  - "func=<function> op1=foo [op2=bar]" does the same
     *  - "func=<function> op1=foo result=bar" will just output the line as-is
     *
     *  - a semicolon or a blank line is ignored
     */
    while (fgets(buf, sizeof(buf), fp)) {
        buf[strcspn(buf, "\r\n")] = '\0';
        strcpy(sparebuf, buf);
        p = buf;
        while (*p && isspace(*p)) p++;
        if (!*p || *p == ';') {
            /* Comment or blank line. Only print if `translating' is set. */
            if (translating)
                printf("%s\n", buf);
            continue;
        }
        if (!strncmp(buf, "seed ", 5)) {
            seed_random(atoi(buf+5));
        } else if (!strncmp(buf, "random=", 7)) {
            /*
             * Copy 'random=on' / 'random=off' lines unconditionally
             * to the output, so that random test failures can be
             * accumulated into a recent-failures-list file and
             * still identified as random-in-origin when re-run the
             * next day.
             */
            printf("%s\n", buf);
        } else if (!strncmp(buf, "test ", 5)) {
            char *p = buf+5;
            char *q;
            int ntests, i;
            q = p;
            while (*p && !isspace(*p)) p++;
            if (*p) *p++ = '\0';
            while (*p && isspace(*p)) p++;
            if (*p)
                ntests = atoi(p);
            else
                ntests = 100;          /* *shrug* */
            for (i = 0; i < nfunctions; i++) {
                if (!strcmp(q, functions[i].name)) {
                    gencases(&functions[i], ntests);
                    break;
                }
            }
            if (i == nfunctions) {
                fprintf(stderr, "unknown test `%s'\n", q);
            }
        } else {
            /*
             * Parse a specific test line.
             */
            uint32 ops[8], result[8];
            int got_op = 0; /* &1 for got_op1, &4 for got_op3 etc. */
            Testable *f;
            char *q, *r;
            int i;
            int got_result = 0, got_errno_in = 0;

            for (q = strtok(p, " \t"); q; q = strtok(NULL, " \t")) {
                r = strchr(q, '=');
                if (!r) {
                    f = find_function(q);
                } else {
                    *r++ = '\0';

                    if (!strcmp(q, "func"))
                        f = find_function(r);
                    else if (!strcmp(q, "op1") || !strcmp(q, "op1r")) {
                        get_operand(r, f, &ops[0], &ops[1]);
                        got_op |= 1;
                    } else if (!strcmp(q, "op2") || !strcmp(q, "op1i")) {
                        get_operand(r, f, &ops[2], &ops[3]);
                        got_op |= 2;
                    } else if (!strcmp(q, "op2r")) {
                        get_operand(r, f, &ops[4], &ops[5]);
                        got_op |= 4;
                    } else if (!strcmp(q, "op2i")) {
                        get_operand(r, f, &ops[6], &ops[7]);
                        got_op |= 8;
                    } else if (!strcmp(q, "result") || !strcmp(q, "resultr")) {
                        get_operand(r, f, &result[0], &result[1]);
                        got_result |= 1;
                    } else if (!strcmp(q, "resulti")) {
                        get_operand(r, f, &result[4], &result[5]);
                        got_result |= 2;
                    } else if (!strcmp(q, "res2")) {
                        get_operand(r, f, &result[2], &result[3]);
                        got_result |= 4;
                    } else if (!strcmp(q, "errno_in")) {
                        got_errno_in = 1;
                    }
                }
            }

            /*
             * Test cases already set up by the input are not
             * reprocessed by default, unlike the fplib tests. (This
             * is mostly for historical reasons, because we used to
             * use a very slow and incomplete internal reference
             * implementation; now our ref impl is MPFR/MPC it
             * probably wouldn't be such a bad idea, though we'd still
             * have to make sure all the special cases came out
             * right.) If translating==2 (corresponding to the -T
             * command-line option) then we regenerate everything
             * regardless.
             */
            if (got_result && translating < 2) {
                if (f)
                    vet_for_decline(f, ops, result, got_errno_in);
                puts(sparebuf);
                continue;
            }

            if (f && got_op==(1<<nargs_(f))-1) {
                /*
                 * And do it!
                 */
                docase(f, ops);
            }
        }
    }
}