int aho_corasick_maketree(aho_corasick_t *in) { slist_t queue; aho_corasick_state_t *state,*s,*r; aho_corasick_t *g = in; int i; slist_init(&queue); // Set all FAIL transition of 0 state to point to itself for(i = 0; i < AHO_CORASICK_CHARACTERS ;i++) { if ( aho_corasick_goto_get(g->zerostate,i) == FAIL ) aho_corasick_goto_set(g->zerostate, i, g->zerostate); // Construct fail() else { if ( slist_append(&queue,aho_corasick_goto_get(g->zerostate,i)) < 0 ) goto fail; aho_corasick_fail(aho_corasick_goto_get(g->zerostate,i)) = g->zerostate; } } // Set fail() for depth > 0 while( (r = slist_pop_first(&queue)) != NULL ) { for(i = 0; i < AHO_CORASICK_CHARACTERS ;i++) { if ( (s = aho_corasick_goto_get(r,i)) == FAIL ) continue; if ( slist_append(&queue,s) < 0 ) goto fail; state = aho_corasick_fail(r); while( aho_corasick_goto_get(state,i) == FAIL ) state = aho_corasick_fail(state); aho_corasick_fail(s) = aho_corasick_goto_get(state,i); debug(printf("Setting f(%u) == %u\n",s->id, aho_corasick_goto_get(state,i)->id)); // Join outputs missing } } slist_destroy(&queue,SLIST_LEAVE_DATA); return 0; fail: slist_destroy(&queue,SLIST_LEAVE_DATA); return -1; }
int pm_makeFSM(pm_t *pm) { if(pm == NULL) { return -1; } slist_t* queue = (slist_t*)malloc(sizeof(slist_t)); if(queue == NULL) { perror("Failed to allocate memory\n"); exit(-1); } slist_init(queue); slist_node_t* p; for(p = pm->zerostate->slist_head(_transitions); p != NULL; p = slist_next(p)) { pm_state_t* state = ((pm_labeled_edge_t*)slist_data(p))->state; if(slist_append(queue, state) == -1) { return -1; } state->fail = pm->zerostate; } while(slist_size(queue) != 0) { pm_state_t* r = slist_pop_first(queue); for(p = r->slist_head(_transitions); p != NULL; p = slist_next(p)) { pm_labeled_edge_t* edge = ((pm_labeled_edge_t*)slist_data(p)); pm_state_t* current = edge->state; if(slist_append(queue, current) == -1) { return -1; } pm_state_t* state = r->fail; pm_state_t* failState; while((failState = pm_goto_get(state, edge->label)) == NULL) { state = state->fail; } current->fail = failState; printf("Settings f(%d) = %d\n", current->id, current->fail->id); if(slist_append_list(current->output, current->fail->output) == -1) { return -1; } } } free(queue); return 0; }