예제 #1
0
파일: difference.c 프로젝트: JakobR/hammer
static HParseResult* parse_difference(void *env, HParseState *state) {
  HTwoParsers *parsers = (HTwoParsers*)env;
  // cache the initial state of the input stream
  HInputStream start_state = state->input_stream;
  HParseResult *r1 = h_do_parse(parsers->p1, state);
  // if p1 failed, bail out early
  if (NULL == r1) {
    return NULL;
  } 
  // cache the state after parse #1, since we might have to back up to it
  HInputStream after_p1_state = state->input_stream;
  state->input_stream = start_state;
  HParseResult *r2 = h_do_parse(parsers->p2, state);
  // TODO(mlp): I'm pretty sure the input stream state should be the post-p1 state in all cases
  state->input_stream = after_p1_state;
  // if p2 failed, restore post-p1 state and bail out early
  if (NULL == r2) {
    return r1;
  }
  size_t r1len = token_length(r1);
  size_t r2len = token_length(r2);
  // if both match but p1's text is shorter than p2's, fail
  if (r1len < r2len) {
    return NULL;
  } else {
    return r1;
  }
}
예제 #2
0
파일: test.c 프로젝트: bronson/tmtest
void scan_sections(struct test *test, scanstate *scanner,
        void (*parseproc)(struct test *test, int sec, const char *datap,
                int len, void *refcon), void *refcon)
{
    // if the testfile is already at its eof, it means that
    // it didn't have any sections.  therefore, we'll assume
    // defaults for all values.  we're done.
    if(scan_is_finished(scanner)) {
        return;
    }

    do {
        int tokno = scan_next_token(scanner);
        if(tokno < 0) {
            test_abort(test, "scan_sections error %d pulling status tokens: "
                "%s\n", tokno, strerror(errno));
        } else if(tokno == 0) {
            break;
        }

        (*parseproc)(test, tokno, token_start(scanner),
                token_length(scanner), refcon);

    } while(!scan_is_finished(scanner));

    // give the parser an eof token so it can finalize things.
    (*parseproc)(test, 0, NULL, 0, refcon);
}
예제 #3
0
파일: test.c 프로젝트: bronson/tmtest
void test_command_copy(struct test *test, FILE *fp)
{
    int oldline;

    do {
        oldline = test->testscanner.line;
        int tokno = scan_next_token(&test->testscanner);
        if(tokno < 0) {
            test_abort(test, "Error %d pulling status tokens: %s\n",
                    tokno, strerror(errno));
        } else if(tokno == 0) {
            // if the test file is totally empty.
            break;
        }


        if(tokno != exCOMMAND) {
            // now we attempt to push the token back on the stream...
            scan_pushback(&test->testscanner);
            test->testscanner.line = oldline;
            // The pushback reset the stream, and I restored the line number,
            // but the scanner is still in a different state.
            // We need it to be in a COMMAND state, so that when it feeds
            // the new SECTION token it marks it NEW.  Reattaching resets
            // the state to a command state, so we can just do that.
            tfscan_attach(&test->testscanner);
            // Now we're done dumping the command and the scanner
            // is poised to return the correct section start to the
            // next client.
            break;
        }

        // print the modified data to the output stream.
        rewrite_command_section(test, tokno, token_start(&test->testscanner), token_length(&test->testscanner));

        if(fp) {
            // print the unmodified data to the command script.
            fwrite(token_start(&test->testscanner), token_length(&test->testscanner), 1, fp);
        }
    } while(!scan_is_finished(&test->testscanner));

    rewrite_command_section(test, 0, NULL, 0);
}
예제 #4
0
파일: test.c 프로젝트: bronson/tmtest
void scan_status_file(struct test *test)
{
    char lastfile[PATH_MAX];
    int lastfile_good = 0;
    char buf[BUFSIZ];
    scanstate ss;
    int tok;
    int state = 0;

    // first rewind the status file
    if(lseek(test->statusfd, 0, SEEK_SET) < 0) {
        test_abort(test, "read_file lseek on status file: %s\n",
            strerror(errno));
    }

    // then create our scanner
    scanstate_init(&ss, buf, sizeof(buf));
    readfd_attach(&ss, test->statusfd);
    stscan_attach(&ss);

    // now, if we see the token "CBRUNNING" in the token stream,
    // it means that we attempted to start the test.  If not,
    // then the test bailed early.
    do {
        tok = scan_next_token(&ss);

        // look for errors...
        if(tok < 0) {
            test_abort(test, "Error %d pulling status tokens: %s\n",
                tok, strerror(errno));
        } else if(tok == stGARBAGE) {
            fprintf(stderr, "Garbage on line %d in the status file: '%.*s'\n",
                    ss.line, (int)token_length(&ss)-1, token_start(&ss));
        } else {
            state = tok;
        }

        switch(tok) {
            case stSTART:
                // nothing to do
                break;

            case stCONFIG:
                if(test->status == test_pending) {
                    test->num_config_files += 1;
                    if(copy_status_arg(token_start(&ss), token_end(&ss), lastfile, sizeof(lastfile))) {
                        lastfile_good = 1;
                    } else {
                        fprintf(stderr, "CONFIG needs arg on line %d of the status file: '%.*s'\n",
                                ss.line, (int)token_length(&ss)-1, token_start(&ss));
                    }
                } else {
                    fprintf(stderr, "CONFIG but status (%d) wasn't pending on line %d of the status file: '%.*s'\n",
                            test->status, ss.line, (int)token_length(&ss)-1, token_start(&ss));
                }
                break;

            case stPREPARE:
                // nothing to do
                break;

            case stRUNNING:
                if(test->status == test_pending) {
                    test->status = test_was_started;
                    if(strlen(test->testfile) < sizeof(lastfile)) {
                        strcpy(lastfile, test->testfile);
                        lastfile_good = 1;
                    } else {
                        fprintf(stderr, "RUNNING lastfile is not big enough for %s", test->testfile);
                    }
                } else {
                    fprintf(stderr, "RUNNING but status (%d) wasn't pending on line %d of the status file: '%.*s'\n",
                            test->status, ss.line, (int)token_length(&ss)-1, token_start(&ss));
                }
                break;

            case stDONE:
                if(test->status == test_was_started) {
                    test->status = test_was_completed;
                } else {
                    fprintf(stderr, "DONE but status (%d) wasn't RUNNING on line %d of the status file: '%.*s'\n",
                            test->status, ss.line, (int)token_length(&ss)-1, token_start(&ss));
                }
                break;

            case stABORTED:
                test->status = (test->status >= test_was_started ? test_was_aborted : config_was_aborted);
                test->status_reason = dup_status_arg(token_start(&ss), token_end(&ss));
                break;

            case stDISABLED:
                test->status = (test->status >= test_was_started ? test_was_disabled : config_was_disabled);
                test->status_reason = dup_status_arg(token_start(&ss), token_end(&ss));
                break;

            default:
                fprintf(stderr, "Unknown token (%d) on line %d of the status file: '%.*s'\n",
                        tok, ss.line, (int)token_length(&ss)-1, token_start(&ss));
        }
    } while(!scan_is_finished(&ss));

    if(lastfile_good) {
        test->last_file_processed = strdup(lastfile);
    }
}
예제 #5
0
bool has_alpha(int t_id)
{
	return (t_id > 255) &&
		((token_length((token_id)t_id) > 3)
			|| alpha_with_2_or_3_letters(t_id));
}