void Connection_task(void *v) { Connection *conn = (Connection *)v; int i = 0; int next = OPEN; State_init(&conn->state, &CONN_ACTIONS); while(1) { if(Filter_activated()) { next = Filter_run(next, conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d from filter!", i, next); } if(next == CLOSE) break; next = State_exec(&conn->state, next, (void *)conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d, Tell ZED!", i, next); if(conn->iob && !conn->iob->closed) { Register_ping(IOBuf_fd(conn->iob)); } i++; } error: // fallthrough State_exec(&conn->state, CLOSE, (void *)conn); Connection_destroy(conn); taskexit(0); }
static void testTransitions() { StateController * stateController; State state1, state2, state3; State_init(&state1); State_init(&state2); stateController = StateController_create(); stateController->addState(stateController, &state1); stateController->addState(stateController, &state2); stateController->addTransition(stateController, &state1, &state2, "transition1"); stateController->addTransition(stateController, &state2, &state1, "transition2"); TestCase_assert(stateController->currentState == NULL, "Expected NULL but got %p", stateController->currentState); stateController->setState(stateController, &state1); TestCase_assert(stateController->currentState == &state1, "Expected %p but got %p", &state1, stateController->currentState); stateController->transition(stateController, "transition1"); TestCase_assert(stateController->currentState == &state2, "Expected %p but got %p", &state2, stateController->currentState); stateController->transition(stateController, "transition2"); TestCase_assert(stateController->currentState == &state1, "Expected %p but got %p", &state1, stateController->currentState); stateController->setState(stateController, &state2); TestCase_assert(stateController->currentState == &state2, "Expected %p but got %p", &state2, stateController->currentState); stateController->dispose(stateController); State_init(&state3); stateController = StateController_create(); stateController->addState(stateController, &state1); stateController->addState(stateController, &state2); stateController->addState(stateController, &state3); stateController->addTransition(stateController, &state1, &state2, "transition"); stateController->addTransition(stateController, &state2, &state3, "transition"); stateController->addTransition(stateController, &state3, &state1, "transition1"); stateController->addTransition(stateController, &state3, &state2, "transition2"); TestCase_assert(stateController->currentState == NULL, "Expected NULL but got %p", stateController->currentState); stateController->setState(stateController, &state1); TestCase_assert(stateController->currentState == &state1, "Expected %p but got %p", &state1, stateController->currentState); stateController->transition(stateController, "transition"); TestCase_assert(stateController->currentState == &state2, "Expected %p but got %p", &state2, stateController->currentState); stateController->transition(stateController, "transition"); TestCase_assert(stateController->currentState == &state3, "Expected %p but got %p", &state3, stateController->currentState); stateController->transition(stateController, "transition1"); TestCase_assert(stateController->currentState == &state1, "Expected %p but got %p", &state1, stateController->currentState); stateController->setState(stateController, &state3); TestCase_assert(stateController->currentState == &state3, "Expected %p but got %p", &state3, stateController->currentState); stateController->transition(stateController, "transition2"); TestCase_assert(stateController->currentState == &state2, "Expected %p but got %p", &state2, stateController->currentState); stateController->dispose(stateController); }
/** * Runs a bunch of events on the given state, printing out the * results, and then returning whether it exited cleanly or not. */ int run_events(State *state, const char *name, int *events) { int i = 0; int rc = 0; State_init(state, &test_actions); debug(">>> RUNNING %s", name); for(i = 0; events[i] != 0; i++) { rc = State_exec(state, events[i], (void *)(intptr_t)i); check(State_invariant(state) != -1, "Failed on processing %d event.", events[i]); } debug("<<< FINAL RESULT: %d, finished: %d", rc, State_invariant(state)); return State_invariant(state); error: return 0; }
void Connection_task(void *v) { Connection *conn = (Connection *)v; int i = 0; int next = 0; State_init(&conn->state, &CONN_ACTIONS); for(i = 0, next = OPEN; next != CLOSE; i++) { next = State_exec(&conn->state, next, (void *)conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d, Tell ZED!", i, next); } error: // fallthrough State_exec(&conn->state, CLOSE, (void *)conn); Connection_destroy(conn); return; }
/* The main program. Parse the command line and do it... */ int main(int argc, char **argv) { static int version = 0; static int rpflag = 0; static int basisflag = 0; static int compress = 0; static int quiet = 0; static int statistics = 0; static int mhflag = 0; static struct s_options options[] = { {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, {OPT_FSTR, "l", (char*)handle_l_option, "Set an output language (c, c++, d)."}, {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"}, {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, {OPT_FLAG, "s", (char*)&statistics, "Print parser stats to standard output."}, {OPT_FLAG, "x", (char*)&version, "Print the version number."}, {OPT_FLAG,0,0,0} }; int i; struct lemon lem; OptInit(argv,options,stderr); if( version ){ printf("Lemon version 1.0\n"); exit(0); } if( OptNArgs()!=1 ){ ErrorMsg("lemon", LINENO_NONE, "Exactly one filename argument is required.\n"); exit(1); } memset(&lem, 0, sizeof(lem)); lem.errorcnt = 0; /* Initialize the machine */ Strsafe_init(); Symbol_init(); State_init(); lem.argv0 = argv[0]; lem.filename = OptArg(0); lem.basisflag = basisflag; Symbol_new("$"); lem.errsym = Symbol_new("error"); lem.errsym->useCnt = 0; /* Parse the input file */ Parse(&lem); if( lem.errorcnt ) exit(lem.errorcnt); if( lem.nrule==0 ){ ErrorMsg(lem.filename, LINENO_NONE, "Empty grammar.\n"); exit(1); } /* Count and index the symbols of the grammar */ lem.nsymbol = Symbol_count(); Symbol_new("{default}"); lem.symbols = Symbol_arrayof(); for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), (int(*)())Symbolcmpp); for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; for(i=1; isupper(lem.symbols[i]->name[0]); i++); lem.nterminal = i; /* Generate a reprint of the grammar, if requested on the command line */ if( rpflag ){ Reprint(&lem); }else{ /* Initialize the size for all follow and first sets */ SetSize(lem.nterminal+1); /* Find the precedence for every production rule (that has one) */ FindRulePrecedences(&lem); /* Compute the lambda-nonterminals and the first-sets for every ** nonterminal */ FindFirstSets(&lem); /* Compute all LR(0) states. Also record follow-set propagation ** links so that the follow-set can be computed later */ lem.nstate = 0; FindStates(&lem); lem.sorted = State_arrayof(); /* Tie up loose ends on the propagation links */ FindLinks(&lem); /* Compute the follow set of every reducible configuration */ FindFollowSets(&lem); /* Compute the action tables */ FindActions(&lem); /* Compress the action tables */ if( compress==0 ) CompressTables(&lem); /* Reorder and renumber the states so that states with fewer choices ** occur at the end. */ ResortStates(&lem); /* Generate a report of the parser generated. (the "y.output" file) */ if( !quiet ) ReportOutput(&lem); /* Generate the source code for the parser */ ReportTable(&lem, mhflag); /* Produce a header file for use by the scanner. (This step is ** omitted if the "-m" option is used because makeheaders will ** generate the file for us.) */ if (! mhflag && language != LANG_D) ReportHeader(&lem); } if( statistics ){ LogMsg(LOGLEVEL_INFO, lem.filename, LINENO_NONE, "Parser statistics: %d terminals, %d nonterminals, %d rules\n", lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); LogMsg(LOGLEVEL_INFO, lem.filename, LINENO_NONE, " %d states, %d parser table entries, %d conflicts\n", lem.nstate, lem.tablesize, lem.nconflict); } if( lem.nconflict ){ LogMsg(LOGLEVEL_WARNING, lem.filename, LINENO_NONE, "%d parsing conflicts.\n", lem.nconflict); } exit(lem.errorcnt + lem.nconflict); return (lem.errorcnt + lem.nconflict); }