Esempio n. 1
0
/**
 * List free function for goto list items. This will be called once per
 * ac_goto in the list. The data should be an ac_goto_list_free_data as
 * explained above. The states in the list are added to the list in data
 * except where the state matches the state in data.
 *
 * Returns AC_SUCCESS if successful or AC_FAILURE if a failure is encountered
 * when adding a state to the list.
 */
ac_error_code
ac_goto_list_free_item(void* item, void* data) {
        ac_goto* goto_item = (ac_goto*) item;
    ac_goto_list_free_data* free_data = (ac_goto_list_free_data*) data;
    
    /* Add the state from the goto item to the list unless it is excluded. */
    if (goto_item->state != free_data->state &&
            ac_list_add(free_data->states, goto_item->state) != AC_SUCCESS) {
        return AC_FAILURE;
    }
    
    FREE(item);
    return AC_SUCCESS;
}
Esempio n. 2
0
/**
 * Associates the given symbol with the given state in a goto list. Returns
 * AC_SUCCESS if successful or AC_FAILURE if an error was encountered.
 */
ac_error_code
ac_goto_list_add(ac_list* self, ac_symbol symbol, ac_state* state) {
    ac_goto* new_item;
    
    if ( ! (new_item = MALLOC(sizeof(ac_goto)))) {
        return AC_FAILURE;
    }
    new_item->symbol = symbol;
    new_item->state  = state;
    
    if (ac_list_add(self, new_item) != AC_SUCCESS) {
        FREE(new_item);
        return AC_FAILURE;
    }
    
    return AC_SUCCESS;
}
Esempio n. 3
0
File: user.c Progetto: fbbs/fbbs
static ac_list *user_build_ac_list(void)
{
	if (!uidshm)
		return NULL;

	ac_list *acl = ac_list_new();
	if (!acl)
		return NULL;

	int size = uidshm->number;
	for (int i = 0; i < size; ++i) {
		const char *user_name = uidshm->userid[i];
		if (*user_name)
			ac_list_add(acl, user_name);
	}
	return acl;
}
Esempio n. 4
0
/**
 * Add an offset and an associated object to the output list. Returns
 * AC_SUCCESS if successful, or AC_FAILURE if the there was an error was
 * encountered.
 */
ac_error_code
ac_output_list_add(ac_list* self, ac_offset offset, void* object) {
    ac_output* new_item;
    
    if ( ! (new_item = MALLOC(sizeof(ac_output)))) {
        return AC_FAILURE;
    }
    
    new_item->offset = offset;
    new_item->object = object;
    
    if (ac_list_add(self, new_item) != AC_SUCCESS) {
        FREE(new_item);
        return AC_FAILURE;
    }
    
    return AC_SUCCESS;
}
Esempio n. 5
0
/**
 * Fix the index, making it ready to be queried. This is an implementation of
 * the last part of Algorithm 2 from the paper combined with an implementation
 * of 'Algorithm 3. Construction of the failure function.' from the paper.
 * Returns AC_SUCCESS if the index was successfully fixed or AC_FAILURE if an
 * error was encountered or if the index was not 'unfixed'.
 */
ac_error_code
ac_index_fix(ac_index* self) {
    // This is an implementation of the last part of Algorithm 2 from the paper
    // combined with an implementation of 'Algorithm 3. Construction of the
    // failure function.' from the paper.

    int             symbol;
    ac_state*       state = NULL;
    ac_state*       r = NULL;
    ac_list*        queue = NULL;
    ac_list_item*   list_item = NULL;
    ac_goto*        item = NULL;
    
    // You can't fix an index that is already fixed.
    if (self->index_state != AC_INDEX_UNFIXED) {
        return AC_FAILURE;
    }
    
    // Mark the index as being fixed.
    self->index_state = AC_INDEX_FIXED;
    
    // Make a temporary queue of states.
    if ( ! (queue = ac_list_new())) {
        return AC_FAILURE;
    }
    
    // Look at all the symbols. If state_0 has a goto for a symbol, add the
    // state to the queue and point the failure state back to state_0 - the
    // first part of Algorithm 3. Otherwise make state_0 goto itself for that
    // symbol - the last part of Algorithm 2.
    // TODO: Improve efficiency of state_0 to state_0 gotos.
    for (symbol = AC_MIN_SYMBOL; symbol <= AC_MAX_SYMBOL; symbol++) {
        if ((state = ac_goto_list_get(self->state_0->gotos, symbol))) {
            if (ac_list_add(queue, state) != AC_SUCCESS) {
                return AC_FAILURE;
            }
            state->failure = self->state_0;
        }
        else {
            if (ac_goto_list_add(self->state_0->gotos,
                                 symbol,
                                 self->state_0) != AC_SUCCESS) {
                return AC_FAILURE;
            }
        }
    }
    
    // Do the second part of Algorithm 3. Burn through the queue, enqueing
    // states from goto list in order to traverse the goto tree breadth-first.
    // ...
    while ((r = ac_state_queue_get(queue))) {
        list_item = r->gotos->first;
        
        while (list_item) {
            item = (ac_goto*) list_item->item;
            symbol = item->symbol;
            
            if (ac_list_add(queue, item->state) != AC_SUCCESS) {
                return AC_FAILURE;
            }
            
            // ... For each goto state, find the failure function by following
            // the failure function back until there is a goto defined. We
            // will always find a defined goto because state_0 has a goto
            // defined for every symbol (by now). ...
            state = r->failure;
            
            while ( ! ac_goto_list_has(state->gotos, symbol)) {
                state = state->failure;
            }
            
            item->state->failure = ac_goto_list_get(state->gotos,
                                                         symbol);
            
            // ... Add the outputs for the failure state to the outputs. We
            // use the extra_outputs list because the outputs are already
            // referenced.
            if (ac_output_list_add_list(item->state->extra_outputs,
                                        item->state->failure->outputs)) {
                return AC_FAILURE;
            };

            if (ac_output_list_add_list(item->state->extra_outputs,
                                    item->state->failure->extra_outputs)) {
                return AC_FAILURE;
            };

            list_item = list_item->next;
        }
        
    }
    
    // Free the temporary queue.
    ac_state_queue_free(queue);
    
    return AC_SUCCESS;
}