Example #1
0
int go_to_state( int from_state , int symbol_id )
{
    STATE *S_ptr;
    Config_set *C_ptr;
    char* symbol;
    int move_state;
    symbol = idtostr(symbol_id);
    
	for( S_ptr = state_start ; from_state != S_ptr->statenum ; S_ptr = S_ptr->next );

    if( from_state == 8 && strcmp(symbol,"void") == 0 )
		return 112;
    
    for( C_ptr = S_ptr->config_set ; C_ptr != NULL ; C_ptr = C_ptr->set_next )
    {
        
        if( C_ptr->dot == NULL ) // check lambda
        {
            if( strcmp(symbol,lambda) == 0 )
                if( (move_state = find_state(C_ptr)) > 0 )
                    return move_state;
        }
        else
        {
            if( strcmp( C_ptr->dot->string , symbol ) == 0 )
                if( (move_state = find_state(C_ptr)) > 0 )
                    return move_state;
        }
    }
    return 0;

}
Example #2
0
int main(int argc, char *argv[])
{
    int n_states, n_symbols, n_accepting_states;
    int i, j;
    char string[MAX_LEN];

    scanf("%d %d\n", &n_states, &n_symbols);
    char alphab[n_symbols];
    int table[n_states][n_symbols];

    for (i = 0; i < n_symbols; ++i)
        scanf("%c", &alphab[i]);

    for (i = 0; i < n_states; ++i)
        for (j = 0; j < n_symbols; ++j)
            scanf("%d", &table[i][j]);

    scanf("%d", &n_accepting_states);
    int accepting_states[n_accepting_states];

    for (i = 0; i < n_accepting_states; ++i)
        scanf("%d ", &accepting_states[i]);

    fgets(string, MAX_LEN, stdin);
    
        int current_state = 0;
        int word_length = strlen(string) - 1;
		int done = 0;
		
       // if (word_length == 0)
           
        if (string[word_length] == '\n')
            string[word_length] = '\0';
		
		while(done != 1)
		{
		
			for (i = 0; i < word_length; ++i)
			{
				if (string[i] == '.')
				{
					done = 1;
					break;
				}

				int char_index = find_char(alphab, n_symbols, string[i]);
				current_state = table[current_state][char_index];
			}
	    }
        printf("DFA has %saccepted input %s Ended in state %d.\n",
                find_state(accepting_states, n_accepting_states, current_state) == -1
                    ? "NOT " : "",
                strtok(string, "."),
                current_state);
    

    return 0;
}
Example #3
0
static void fix_action(struct syntax *syn, struct action *a, const char *prefix)
{
	if (a->destination) {
		const char *name = fix_name(a->destination->name, prefix);
		a->destination = find_state(syn, name);
	}
	if (a->emit_name)
		a->emit_name = xstrdup(a->emit_name);
}
Example #4
0
File: ai.cpp Project: diffblue/cbmc
  forall_goto_program_instructions(i_it, goto_program)
  {
    out << "**** " << i_it->location_number << " "
        << i_it->source_location << "\n";

    find_state(i_it).output(out, *this, ns);
    out << "\n";
    #if 1
    goto_program.output_instruction(ns, identifier, out, i_it);
    out << "\n";
    #endif
  }
/***************************************************************************
 * Recherche un processus dont au moins un état correspond à la place
 */
inline process_t* find_process_state(global_table_t* global_table, unsigned int place) {
        unsigned int i;
               
        /* Recherche de la case du vecteur concernée par la suppression */
        for (i = 0 ; i < global_table->size; i++) {
                /* Si l'élément a été trouvé, on peut le remplacer par le dernier élément du tableau */
                if (find_state(global_table->processes[i], place) != NULL) {
                        return global_table->processes[i];
                }
        }
        return NULL;
}
Example #6
0
/*
Looks up a previously stored state, or generates a new one. No assumptions are
made about whether the board state is in reduced form already. Never fails. If
the memory is full it allocates a new state regardless. If the state is found
and returned it's OpenMP lock is first set. Thread-safe.
RETURNS the state information
*/
tt_stats * tt_lookup_create(
    const board * b,
    bool is_black,
    u64 hash
){
    u32 key = (u32)(hash % ((u64)number_of_buckets));
    omp_lock_t * bucket_lock = is_black ? &b_table_lock : &w_table_lock;
    omp_set_lock(bucket_lock);

    tt_stats * ret = find_state(hash, b, is_black);
    if(ret == NULL) /* doesnt exist */
    {
        if(states_in_use >= max_allocated_states)
        {
            /*
            It is possible in theory for a complex ko to produce a situation
            where freeing the game tree that is not reachable doesn't free any
            states.
            */
            tt_log_status();
            char * s = alloc();
            board_to_string(s, b->p, b->last_played, b->last_eaten);
            flog_warn("tt", s);
            release(s);
            flog_warn("tt", "memory exceeded on root lookup");
        }

        ret = create_state(hash);
        memcpy(ret->p, b->p, TOTAL_BOARD_SIZ);
        ret->last_eaten_passed =
            (b->last_played == PASS) ? PASS : b->last_eaten;
        omp_set_lock(&ret->lock);

        if(is_black)
        {
            ret->next = b_stats_table[key];
            b_stats_table[key] = ret;
        }
        else
        {
            ret->next = w_stats_table[key];
            w_stats_table[key] = ret;
        }
        omp_unset_lock(bucket_lock);
    }
    else /* update */
    {
        omp_set_lock(&ret->lock);
        omp_unset_lock(bucket_lock);
    }

    return ret;
}
Example #7
0
SC_FUNC constvalue *state_add(const char *name,int fsa)
{
  constvalue *ptr;
  int last;

  assert(strlen(name)<sizeof(ptr->name));
  ptr=find_state(name,fsa,&last,NULL);
  if (ptr==NULL) {
    assert(fsa <= SHRT_MAX);
    ptr=append_constval(&sc_state_tab,name,(cell)(last+1),(short)fsa);
  } /* if */
  return ptr;
}
Example #8
0
void add_action (Action_s *a)
{
	State_s	*s;

	s = find_state(a->address);
	if (!s) {
		s = ezalloc(sizeof(*s));
		s->address = a->address;
		add_state(s);
		init_cir( &s->actions);
	}
	enq_cir( &s->actions, a, link);
	do_transition(s, a);
}
Example #9
0
File: state.c Project: dsaravel/dex
static struct state *find_or_add_state(const char *name)
{
	struct state *st = find_state(current_syntax, name);

	if (st)
		return st;

	st = xnew0(struct state, 1);
	st->name = xstrdup(name);
	st->defined = false;
	st->type = -1;
	ptr_array_add(&current_syntax->states, st);
	return st;
}
Example #10
0
/*
Frees states outside of the subtree started at state b. Not thread-safe.
RETURNS number of states freed.
*/
u32 tt_clean_unreachable(
    const board * b,
    bool is_black
){
    u64 hash = zobrist_new_hash(b);
    u32 states_in_use_before = states_in_use;
    tt_stats * stats = find_state(hash, b, is_black);
    if(stats == NULL) /* free all */
        tt_clean_all();
    else
    {
        /* free outside tree */
        ++maintenance_mark;
        mark_states_for_keeping(stats);
        release_states_not_marked();
    }

    d32 states_released = states_in_use_before - states_in_use;
    assert(states_released >= 0);
    return states_released;
}
Example #11
0
SC_FUNC constvalue *state_find(const char *name,int fsa_id)
{
  int last;     /* dummy */
  return find_state(name,fsa_id,&last);
}
Example #12
0
struct high_state *load_dfa(struct high_syntax *syntax)
{
    unsigned char name[1024];
    unsigned char buf[1024];
    unsigned char bf[256];
    int clist[256];
    unsigned char *p;
    int c;
    FILE *f = NULL;
    struct ifstack *stack = 0;
    struct high_state *state = 0; /* Current state */
    struct high_state *first = 0; /* First state */
    int line = 0;
    int this_one = 0;
    int inside_subr = 0;

    /* Load it */

    if ((p = (unsigned char *)exists_prefs_dir()) && strlen((const char *)p) + 2 + strlen(SYNTAX_DIR) + strlen(SYNTAX_EXT) + strlen((const char *)syntax->name) < sizeof name)
    {
        strcat(strcat(strcat(strcat(strcpy((char *)name, (const char *)p), SYNTAX_DIR), "/"), (const char *)syntax->name), SYNTAX_EXT);
        f = fopen((char *)name, "r");
    }

    if (!f && (p = (unsigned char *)exists_gprefs_dir()) && strlen((const char *)p) + 2 + strlen(SYNTAX_DIR) + strlen(SYNTAX_EXT) + strlen((const char *)syntax->name) < sizeof name)
    {
        strcat(strcat(strcat(strcat(strcpy((char *)name, (const char *)p), SYNTAX_DIR), "/"), (const char *)syntax->name), SYNTAX_EXT);
        f = fopen((char *)name, "r");
    }

    if (!f)
    {
        return 0;
    }

    /* Parse file */
    while (fgets((char *)buf, 1023, f))
    {
        ++line;
        p = buf;
        c = parse_ws(&p, '#');
        if (!parse_char(&p, '.'))
        {
            if (!parse_ident(&p, bf, sizeof(bf)))
            {
                if (!zcmp(bf, USTR "ifdef"))
                {
                    struct ifstack *st = joe_malloc(sizeof(struct ifstack));
                    st->next = stack;
                    st->else_part = 0;
                    st->ignore = 1;
                    st->skip = 1;
                    st->line = line;
                    if (!stack || !stack->ignore)
                    {
                        parse_ws(&p, '#');
                        if (!parse_ident(&p, bf, sizeof(bf)))
                        {
                            struct high_param *param;
                            for (param = syntax->params; param; param = param->next)
                                if (!zcmp(param->name, bf))
                                {
                                    st->ignore = 0;
                                    break;
                                }
                            st->skip = 0;
                        }
                        else
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: missing parameter for ifdef\n")), name, line);
                        }
                    }
                    stack = st;
                }
                else if (!zcmp(bf, USTR "else"))
                {
                    if (stack && !stack->else_part)
                    {
                        stack->else_part = 1;
                        if (!stack->skip)
                        {
                            stack->ignore = !stack->ignore;
                        }
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: else with no matching if\n")), name, line);
                    }
                }
                else if (!zcmp(bf, USTR "endif"))
                {
                    if (stack)
                    {
                        struct ifstack *st = stack;
                        stack = st->next;
                        joe_free(st);
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: endif with no matching if\n")), name, line);
                    }
                }
                else if (!zcmp(bf, USTR "subr"))
                {
                    parse_ws(&p, '#');
                    if (parse_ident(&p, bf, sizeof(bf)))
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: Missing subroutine name\n")), name, line);
                    }
                    else
                    {
                        if (!stack || !stack->ignore)
                        {
                            inside_subr = 1;
                            this_one = 0;
                            if (syntax->subr && !zcmp(bf, syntax->subr))
                            {
                                this_one = 1;
                            }
                        }
                    }
                }
                else if (!zcmp(bf, USTR "end"))
                {
                    if (!stack || !stack->ignore)
                    {
                        this_one = 0;
                        inside_subr = 0;
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Unknown control statement\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing control statement name\n")), name, line);
            }
        }
        else if (stack && stack->ignore)
        {
            /* Ignore this line because of ifdef */
        }
        else if (!parse_char(&p, '='))
        {
            /* Parse color */
            parse_color_def(&syntax->color, p, name, line);
        }
        else if ((syntax->subr && !this_one) || (!syntax->subr && inside_subr))
        {
            /* Ignore this line because it's not the code we want */
        }
        else if (!parse_char(&p, ':'))
        {
            if (!parse_ident(&p, bf, sizeof(bf)))
            {

                state = find_state(syntax, bf);

                if (!first)
                {
                    first = state;
                }

                parse_ws(&p, '#');
                if (!parse_tows(&p, bf))
                {
                    struct high_color *color;
                    for (color = syntax->color; color; color = color->next)
                        if (!zcmp(color->name, bf))
                        {
                            break;
                        }
                    if (color)
                    {
                        state->color = color->color;
                    }
                    else
                    {
                        state->color = 0;
                        i_printf_2((char *)joe_gettext(_("%s %d: Unknown class\n")), name, line);
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing color for state definition\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing state name\n")), name, line);
            }
        }
        else if (!parse_char(&p, '-'))
        {
            /* No. sync lines ignored */
        }
        else
        {
            c = parse_ws(&p, '#');

            if (!c)
            {
            }
            else if (c == '"' || c == '*' || c == '&')
            {
                if (state)
                {
                    struct high_cmd *cmd;
                    int delim = 0;
                    if (!parse_field(&p, USTR "*"))
                    {
                        int z;
                        for (z = 0; z != 256; ++z)
                        {
                            clist[z] = 1;
                        }
                    }
                    else if (!parse_field(&p, USTR "&"))
                    {
                        delim = 1;
                    }
                    else
                    {
                        c = parse_string(&p, bf, sizeof(bf));
                        if (c < 0)
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: Bad string\n")), name, line);
                        }
                        else
                        {
                            int z;
                            int first, second;
                            unsigned char *t = bf;
                            for (z = 0; z != 256; ++z)
                            {
                                clist[z] = 0;
                            }
                            while (!parse_range(&t, &first, &second))
                            {
                                if (first > second)
                                {
                                    second = first;
                                }
                                while (first <= second)
                                {
                                    clist[first++] = 1;
                                }
                            }
                        }
                    }
                    /* Create command */
                    cmd = mkcmd();
                    parse_ws(&p, '#');
                    if (!parse_ident(&p, bf, sizeof(bf)))
                    {
                        int z;
                        cmd->new_state = find_state(syntax, bf);
                        parse_options(syntax, cmd, f, p, 0, name, line);

                        /* Install command */
                        if (delim)
                        {
                            state->delim = cmd;
                        }
                        else for (z = 0; z != 256; ++z)
                                if (clist[z])
                                {
                                    state->cmd[z] = cmd;
                                }
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: Missing jump\n")), name, line);
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: No state\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Unknown character\n")), name, line);
            }
        }
    }

    while (stack)
    {
        struct ifstack *st = stack;
        stack = st->next;
        i_printf_2((char *)joe_gettext(_("%s %d: ifdef with no matching endif\n")), name, st->line);
        joe_free(st);
    }

    fclose(f);

    return first;
}
Example #13
0
void parse_options(struct high_syntax *syntax, struct high_cmd *cmd, FILE *f, unsigned char *p, int parsing_strings, unsigned char *name, int line)
{
    unsigned char buf[1024];
    unsigned char bf[256];
    unsigned char bf1[256];

    while (parse_ws(&p, '#'), !parse_ident(&p, bf, sizeof(bf)))
    {
        if (!zcmp(bf, USTR "buffer"))
        {
            cmd->start_buffering = 1;
        }
        else if (!zcmp(bf, USTR "hold"))
        {
            cmd->stop_buffering = 1;
        }
        else if (!zcmp(bf, USTR "save_c"))
        {
            cmd->save_c = 1;
        }
        else if (!zcmp(bf, USTR "save_s"))
        {
            cmd->save_s = 1;
        }
        else if (!zcmp(bf, USTR "recolor"))
        {
            parse_ws(&p, '#');
            if (!parse_char(&p, '='))
            {
                parse_ws(&p, '#');
                if (parse_int(&p, &cmd->recolor))
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
            }
        }
        else if (!zcmp(bf, USTR "call"))
        {
            parse_ws(&p, '#');
            if (!parse_char(&p, '='))
            {
                parse_ws(&p, '#');
                if (!parse_char(&p, '.'))
                {
                    zcpy(bf, syntax->name);
                    goto subr;
                }
                else if (parse_ident(&p, bf, sizeof(bf)))
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
                }
                else
                {
                    if (!parse_char(&p, '.'))
                    {
subr:
                        if (parse_ident(&p, bf1, sizeof(bf1)))
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: Missing subroutine name\n")), name, line);
                        }
                        cmd->call = load_syntax_subr(bf, bf1, parse_params(syntax->params, &p, name, line));
                    }
                    else
                    {
                        cmd->call = load_syntax_subr(bf, 0, parse_params(syntax->params, &p, name, line));
                    }
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
            }
        }
        else if (!zcmp(bf, USTR "return"))
        {
            cmd->rtn = 1;
        }
        else if (!zcmp(bf, USTR "reset"))
        {
            cmd->reset = 1;
        }
        else if (!parsing_strings && (!zcmp(bf, USTR "strings") || !zcmp(bf, USTR "istrings")))
        {
            if (bf[0] == 'i')
            {
                cmd->ignore = 1;
            }
            while (fgets((char *)buf, 1023, f))
            {
                ++line;
                p = buf;
                parse_ws(&p, '#');
                if (*p)
                {
                    if (!parse_field(&p, USTR "done"))
                    {
                        break;
                    }
                    if (parse_string(&p, bf, sizeof(bf)) >= 0)
                    {
                        parse_ws(&p, '#');
                        if (cmd->ignore)
                        {
                            lowerize(bf);
                        }
                        if (!parse_ident(&p, bf1, sizeof(bf1)))
                        {
                            struct high_cmd *kw_cmd = mkcmd();
                            kw_cmd->noeat = 1;
                            kw_cmd->new_state = find_state(syntax, bf1);
                            if (!zcmp(bf, USTR "&"))
                            {
                                cmd->delim = kw_cmd;
                            }
                            else
                            {
                                if (!cmd->keywords)
                                {
                                    cmd->keywords = htmk(64);
                                }
                                htadd(cmd->keywords, zdup(bf), kw_cmd);
                            }
                            parse_options(syntax, kw_cmd, f, p, 1, name, line);
                        }
                        else
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: Missing state name\n")), name, line);
                        }
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: Missing string\n")), name, line);
                    }
                }
            }
        }
        else if (!zcmp(bf, USTR "noeat"))
        {
            cmd->noeat = 1;
        }
        else if (!zcmp(bf, USTR "mark"))
        {
            cmd->start_mark = 1;
        }
        else if (!zcmp(bf, USTR "markend"))
        {
            cmd->stop_mark = 1;
        }
        else if (!zcmp(bf, USTR "recolormark"))
        {
            cmd->recolor_mark = 1;
        }
        else
        {
            i_printf_2((char *)joe_gettext(_("%s %d: Unknown option\n")), name, line);
        }
    }
}
Example #14
0
stf_status
dpd_init(struct state *st)
{
    /**
     * Used to store the 1st state 
     */
    struct state *p1st;

#ifdef CONSOLE_DEBUG
    time_start = time(NULL);
#endif

    /* find the related Phase 1 state */
    p1st = find_state(st->st_icookie, st->st_rcookie,
		      &st->st_connection->that.host_addr, 0);

    if (p1st == NULL) {
        loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD");

	/*
	 * if the phase 1 state has gone away, it really should have
	 * deleted all of its children.
	 * Why would this happen? because a quick mode SA can take
	 * some time to create (DNS lookups for instance), and the phase 1
	 * might have been taken down for some reason in the meantime.
	 * We really can not do anything here --- attempting to invoke
	 * the DPD action would be a good idea, but we really should
	 * do that outside this function.
	 */
	return STF_FAIL;
    }

    /* if it was enabled, and we haven't turned it on already */
    if (p1st->hidden_variables.st_dpd) {
	time_t n = now();
	log("Dead Peer Detection (RFC 3706): enabled");

	/* If st is a phase 2 state, so turn its DPD on. This is needed, because
	 * DPD support is negotiated during phase 1.
	 */
	if (p1st != st)
	    st->hidden_variables.st_dpd = p1st->hidden_variables.st_dpd;

	if(st->st_dpd_event == NULL
	   || (st->st_connection->dpd_idle_timeout + n) <
	   st->st_dpd_event->ev_time) {
	    delete_dpd_event(st);
	    event_schedule(EVENT_DPD, st->st_connection->dpd_idle_timeout, st);
	}

    } else {
      log("Dead Peer Detection (RFC 3706): not enabled because peer did not advertise it");
    }

    if(p1st != st) {
	/* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */
	if(p1st->st_dpd_event != NULL
	   && p1st->st_dpd_event->ev_type == EVENT_DPD) {
	    delete_dpd_event(p1st);
	}
    }
    return STF_OK;
}
void
StateMachine::execute()
{
	State		*state_ptr;
	Transition	* volatile transition = 0;
	int			next_state;
	int			event;
	EventHandler	h( fsa_sig_handler, asynch_events );


	CurFSA = this;
	cur_state = start_state;

	h.display();
	h.install();

	while( cur_state != end_state ) {
		if ( transition != no_print_tr ) {
			dprintf( D_ALWAYS, "\t*FSM* Transitioning to state \"%s\"\n",
					StateNames.get_name(cur_state) );
		}
		state_ptr = find_state( cur_state );
		next_state = sigsetjmp( JmpBuf, TRUE );
		if( !next_state ) {

			if( state_ptr->func ) {
				h.allow_events( state_ptr->asynch_events );

				if ( transition != no_print_tr ) {
					dprintf( D_ALWAYS, 
							"\t*FSM* Executing state func \"%s\" [ ",
							StateFuncNames.get_name((long)state_ptr->func) );
					state_ptr->display_events();
					dprintf( D_ALWAYS | D_NOHEADER, " ]\n" );
				}

					
				event = state_ptr->func();

				h.block_events( state_ptr->asynch_events );
			} else {
				event = -1;
			}

			transition = find_transition( event );

			if( transition->func ) {
				if (transition != no_print_tr) {
					dprintf( D_ALWAYS, 
							"\t*FSM* Executing transition function \"%s\"\n",
							TransFuncNames.get_name((long)transition->func) );
				}
				transition->func();
			}
			next_state = transition->to;
		}
		cur_state = next_state;
	}
	dprintf( D_ALWAYS, "\t*FSM* Reached state \"%s\"\n", StateNames.get_name(cur_state) );

	h.de_install();
	CurFSA = NULL;
}
Example #16
0
SC_FUNC constvalue *state_find(const char *name,int fsa_id,char *closestmatch)
{
  int last;     /* dummy */
  return find_state(name,fsa_id,&last,closestmatch);
}
Example #17
0
t3_bool t3_highlight_match(t3_highlight_match_t *match, const char *line, size_t size) {
    match_context_t context;

    if ((match->highlight->flags & (T3_HIGHLIGHT_UTF8 | T3_HIGHLIGHT_UTF8_NOCHECK)) == T3_HIGHLIGHT_UTF8 && !match->utf8_checked) {
        if (!t3_highlight_utf8check(line, size)) {
            match->state = 0;
            match->begin_attribute = 0;
            match->match_attribute = 0;
            match->start = match->match_start = match->end = -1;
            return t3_false;
        }
        match->utf8_checked = t3_true;
    }

    context.match = match;
    context.line = line;
    context.size = size;
    context.state = &match->highlight->states.data[match->mapping.data[match->state].highlight_state];
    context.best = NULL;
    context.best_end = -1;

    match->start = match->end;
    match->begin_attribute = context.state->attribute_idx;

    if (match->last_progress != match->end) {
        match->last_progress = match->end;
        match->last_progress_state = match->state;
    } else if (match->last_progress_state < match->state) {
        match->last_progress_state = match->state;
    }

    for (match->match_start = match->end; match->match_start <= size; match->match_start +=
                (match->highlight->flags & T3_HIGHLIGHT_UTF8) ? step_utf8(line[match->match_start]) : 1)
    {
        match_internal(&context);

        if (context.best != NULL) {
            dst_idx_t next_state = find_state(match, context.best->next_state, context.best->extra,
                                              line + context.extract_start, context.extract_end - context.extract_start,
                                              context.best->extra != NULL ? context.best->extra->dynamic_pattern : NULL);

            /* Check if we have come full circle. If so, continue to the next byte and start over. */
            if (match->last_progress == (size_t) context.best_end &&
                    context.best->next_state > NO_CHANGE &&
                    match->last_progress_state == next_state)
            {
                context.best = NULL;
                continue;
            }

            match->end = context.best_end;
            match->state = next_state;
            if (context.best->extra != NULL && context.best->extra->on_entry != NULL) {
                int i;
                for (i = 0; i < context.best->extra->on_entry_cnt; i++) {
                    match->state = find_state(match, context.best->extra->on_entry[i].state, context.best->extra,
                                              line + context.extract_start, context.extract_end - context.extract_start,
                                              context.best->extra->on_entry[i].end_pattern);
                }
            }
            match->match_attribute = context.best->attribute_idx;
            return t3_true;
        }
    }

    match->match_start = size;
    match->end = size;
    return t3_false;
}