Пример #1
0
Status ws_new_pattern(SyntaxPattern **syn_pattern_ptr, const Regex *regex,
                      SyntaxToken token)
{
    assert(syn_pattern_ptr != NULL);
    assert(regex != NULL);
    assert(!is_null_or_empty(regex->regex_pattern));

    SyntaxPattern *syn_pattern = malloc(sizeof(SyntaxPattern));

    if (syn_pattern == NULL) {
        return OUT_OF_MEMORY("Unable to allocate SyntaxPattern");
    }

    memset(syn_pattern, 0, sizeof(SyntaxPattern));

    Status status = ru_compile_custom_error_msg(&syn_pattern->regex, regex, 
                                                "pattern ");

    if (!STATUS_IS_SUCCESS(status)) {
        free(syn_pattern);
        return status; 
    }

    syn_pattern->token = token;
    *syn_pattern_ptr = syn_pattern;

    return STATUS_SUCCESS;
}
Пример #2
0
/* Run SyntaxDefintion against buffer substring to determine
 * tokens present and return these matches */
static SyntaxMatches *ws_generate_matches(const SyntaxDefinition *syn_def,
                                          const char *str, size_t str_len,
                                          /* Offset into buffer str was taken
                                           * from */
                                          size_t offset)
{
    assert(str != NULL);

    SyntaxMatches *syn_matches = sy_new_matches(offset);

    if (syn_matches == NULL || str_len == 0) {
        return syn_matches;
    }

    const WedSyntaxDefinition *wed_def = (WedSyntaxDefinition *)syn_def;
    const SyntaxPattern *pattern = wed_def->patterns;
    SyntaxMatch syn_match;
    RegexResult result;
    Status status;

    /* Run each SyntaxPattern against str */
    while (pattern != NULL) {
        size_t offset = 0;

        /* Find all matches in str ensuring we don't 
         * exceed MAX_SYNTAX_MATCH_NUM */
        while (syn_matches->match_num < MAX_SYNTAX_MATCH_NUM &&
               offset < str_len) {
            status = ru_exec(&result, &pattern->regex, str, str_len, offset);

            if (!(STATUS_IS_SUCCESS(status) && result.match)) {
                st_free_status(status);
                /* Failure or no matches in the remainder of str
                 * so we're finished with this SyntaxPatten */
                break;
            }

            syn_match.offset = result.output_vector[0];
            syn_match.length = result.match_length;
            syn_match.token = pattern->token;

            ws_add_match(syn_matches, &syn_match);

            offset = result.output_vector[0] + result.match_length;
        } 

        pattern = pattern->next;
    }

    /* Order matches by offset then length */
    qsort(syn_matches->matches, syn_matches->match_num,
          sizeof(SyntaxMatch), ws_match_cmp);

    return syn_matches;
}
Пример #3
0
/* TODO: don't malloc name - on the stack */
chc_status_t con_create(unsigned int fd, struct syd_obj **obj)
{
    STATUS_INIT(status);
    int snprintf_result = 0;
    char *name = NULL;
    struct con_context *context = NULL;
    struct syd_obj *local_obj = NULL;

    if (NULL == obj) {
        STATUS_LABEL(status, CHC_CON_INVALID);
        goto cleanup;
    }

    context = (struct con_context *)vzalloc(sizeof(*context));
    if (NULL == context) {
        STATUS_LABEL(status, CHC_CON_VZALLOC);
        goto cleanup;
    }
    context->fd = fd;

    name = (char *)vzalloc(sizeof(COR_MAX_NAME));
    if (NULL == name) {
        STATUS_LABEL(status, CHC_CON_VZALLOC);
        goto cleanup;
    }
    /* TODO: validate null termination */
    snprintf_result = snprintf(name, COR_MAX_NAME, CON_PATTERN, fd);
    if (0 > snprintf_result) {
        STATUS_LABEL(status, CHC_CON_SNPRINTF);
        goto cleanup;
    }

    local_obj = (struct syd_obj *)vzalloc(sizeof(*local_obj));
    if (NULL == local_obj) {
        STATUS_LABEL(status, CHC_CON_VZALLOC);
        goto cleanup;
    }

    STATUS_ASSIGN(status, syd_create(name, context, &g_con_ops));
    if (STATUS_IS_ERROR(status)) {
        goto cleanup;
    }

    STATUS_LABEL(status, CHC_SUCCESS);
cleanup:
    if (STATUS_IS_SUCCESS(status)) {
        *obj = local_obj;
    } else {
        if (NULL != local_obj) {
            vfree(local_obj);
        }
        if (NULL != context) {
            vfree(context);
        }
        if (NULL != name) {
            vfree(name);
        }
    }

    return status;
}
Пример #4
0
/* Interface to run prompt completion */
Status pc_run_prompt_completer(const Session *sess, Prompt *prompt, int reverse)
{
    PromptType prompt_type = prompt->prompt_type;

    if (!pc_has_prompt_completer(prompt_type)) {
        return STATUS_SUCCESS;
    } 

    pr_clear_suggestions(prompt);

    char *prompt_content = pr_get_prompt_content(prompt);
    size_t prompt_content_len = strlen(prompt_content);

    if (prompt_content_len == 0) {
        free(prompt_content);
        return STATUS_SUCCESS;
    }

    const PromptCompleterConfig *pcc = &pc_prompt_completers[prompt_type];
    PromptCompleter completer = pcc->prompt_completer;
    Status status = completer(sess, prompt->suggestions, prompt_content,
                              prompt_content_len);

    if (!STATUS_IS_SUCCESS(status) || pr_suggestion_num(prompt) == 0) {
        free(prompt_content);
        return status;
    }

    list_sort(prompt->suggestions, pc_suggestion_comparator);
    
    /* Add the inital input from the user to the list of suggestions
     * so that it can be cycled back to when all the suggestions have
     * been displayed */
    PromptSuggestion *inital_input = pc_new_suggestion(prompt_content,
                                                       SR_NO_MATCH, NULL);
    free(prompt_content);

    if (inital_input == NULL ||
        !list_add(prompt->suggestions, inital_input)) {
        free(inital_input);
        return OUT_OF_MEMORY("Unable to allocated suggestions");
    }

    /* At this point there should be at least one suggestion plus
     * the inital input */
    assert(pr_suggestion_num(prompt) > 1);

    size_t start_index = 0;

    /* <S-Tab> can be used to reverse through the suggestions and
     * invoke prompt completion in reverse, so start from end of suggestion
     * list if necessary */
    if (reverse) {
        start_index = pr_suggestion_num(prompt) - 2;
    }

    /* Update prompt content with first suggestion */
    status = pr_show_suggestion(prompt, start_index);

    return status;
}