Esempio n. 1
0
/* Top level wrapper around the parser */
int ini_config_parse(struct ini_cfgfile *file_ctx,
                     int error_level,
                     uint32_t collision_flags,
                     uint32_t parse_flags,
                     struct ini_cfgobj *ini_config)
{
    int error = EOK;
    struct parser_obj *po = NULL;
    uint32_t fl1, fl2, fl3;

    TRACE_FLOW_ENTRY();

    if ((!ini_config) || (!(ini_config->cfg))) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    if (!file_ctx) {
        TRACE_ERROR_NUMBER("Invalid file context", EINVAL);
        return EINVAL;
    }

    if (!valid_collision_flags(collision_flags)) {
        TRACE_ERROR_NUMBER("Invalid flags.", EINVAL);
        return EINVAL;
    }

    if ((error_level != INI_STOP_ON_ANY) &&
        (error_level != INI_STOP_ON_NONE) &&
        (error_level != INI_STOP_ON_ERROR)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    error = parser_create(ini_config,
                          file_ctx->file,
                          file_ctx->filename,
                          error_level,
                          collision_flags,
                          parse_flags,
                          &po);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to perform an action", error);
        return error;
    }

    error = parser_run(po);
    if (error) {
        fl1 = collision_flags & INI_MS_MASK;
        fl2 = collision_flags & INI_MV1S_MASK;
        fl3 = collision_flags & INI_MV2S_MASK;
        if ((error == EEXIST) &&
            (((fl1 == INI_MS_DETECT) &&
              (fl2 != INI_MV1S_ERROR) &&
              (fl3 != INI_MV2S_ERROR)) ||
             ((fl2 == INI_MV1S_DETECT) &&
              (fl1 != INI_MS_ERROR) &&
              (fl3 != INI_MV2S_ERROR)) ||
             ((fl3 == INI_MV2S_DETECT) &&
              (fl1 != INI_MS_ERROR) &&
              (fl2 != INI_MV1S_ERROR)))) {
            TRACE_ERROR_NUMBER("No error in detect mode", error);
            /* Fall through */
        }
        else {
            TRACE_ERROR_NUMBER("Failed to parse file", error);
            TRACE_ERROR_NUMBER("Mode", collision_flags);
            col_get_collection_count(ini_config->error_list, &(ini_config->count));
            if(ini_config->count) (ini_config->count)--;
            parser_destroy(po);
            return error;
        }
    }

    /* If should be empty anyways */
    col_destroy_collection_with_cb(ini_config->cfg, ini_cleanup_cb, NULL);
    ini_config->cfg = po->top;
    po->top = NULL;

    parser_destroy(po);

    TRACE_FLOW_EXIT();
    return error;
}
Esempio n. 2
0
/* Create parse object
 *
 * It assumes that the ini collection
 * has been precreated.
 */
static int parser_create(struct ini_cfgobj *co,
                         FILE *file,
                         const char *config_filename,
                         int error_level,
                         uint32_t collision_flags,
                         uint32_t parse_flags,
                         struct parser_obj **po)
{
    int error = EOK;
    struct parser_obj *new_po = NULL;
    unsigned count = 0;

    TRACE_FLOW_ENTRY();

    /* Make sure that all the parts are initialized */
    if ((!po) ||
        (!co) ||
        (!(co->cfg)) ||
        (!file) ||
        (!config_filename)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    error = col_get_collection_count(co->cfg, &count);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to check object size", error);
        return error;
    }

    if (count != 1) {
        TRACE_ERROR_NUMBER("Configuration is not empty", EINVAL);
        return EINVAL;
    }

    new_po = malloc(sizeof(struct parser_obj));
    if (!new_po) {
        TRACE_ERROR_NUMBER("No memory", ENOMEM);
        return ENOMEM;
    }

    /* Save external data */
    new_po->file = file;
    new_po->el = co->error_list;
    new_po->filename = config_filename;
    new_po->error_level = error_level;
    new_po->collision_flags = collision_flags;
    new_po->parse_flags = parse_flags;
    new_po->boundary = co->boundary;
    new_po->co = co;

    /* Initialize internal varibles */
    new_po->sec = NULL;
    new_po->merge_sec = NULL;
    new_po->ic = NULL;
    new_po->last_error = 0;
    new_po->linenum = 0;
    new_po->keylinenum = 0;
    new_po->seclinenum = 0;
    new_po->last_read = NULL;
    new_po->last_read_len = 0;
    new_po->inside_comment = 0;
    new_po->key = NULL;
    new_po->key_len = 0;
    new_po->raw_lines = NULL;
    new_po->raw_lengths = NULL;
    new_po->ret = EOK;
    new_po->merge_key = NULL;
    new_po->merge_vo = NULL;
    new_po->merge_error = 0;
    new_po->top = NULL;
    new_po->queue = NULL;

    /* Create top collection */
    error = col_create_collection(&(new_po->top),
                                  INI_CONFIG_NAME,
                                  COL_CLASS_INI_CONFIG);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create top collection", error);
        parser_destroy(new_po);
        return error;
    }

    /* Create a queue */
    error = col_create_queue(&(new_po->queue));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create queue", error);
        parser_destroy(new_po);
        return error;
    }

    error = col_enqueue_unsigned_property(new_po->queue,
                                          PARSE_ACTION,
                                          PARSE_READ);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create queue", error);
        parser_destroy(new_po);
        return error;
    }

    *po = new_po;

    TRACE_FLOW_EXIT();
    return error;
}
Esempio n. 3
0
/* Internal function that prints errors */
static void print_error_list(FILE *file,
                             struct collection_item *error_list,
                             int cclass,
                             char *wrong_col_error,
                             char *failed_to_process,
                             char *error_header,
                             char *line_format,
                             int family)
{
    struct collection_iterator *iterator;
    int error;
    struct collection_item *item = NULL;
    struct parse_error *pe;
    unsigned int count;

    TRACE_FLOW_STRING("print_error_list", "Entry");

    /* If we have something to print print it */
    if (error_list == NULL) {
        TRACE_ERROR_STRING("No error list","");
        return;
    }

    /* Make sure we go the right collection */
    if (!col_is_of_class(error_list, cclass)) {
        TRACE_ERROR_STRING("Wrong collection class:", wrong_col_error);
        fprintf(file,"%s\n", wrong_col_error);
        return;
    }

    /* Bind iterator */
    error =  col_bind_iterator(&iterator, error_list, COL_TRAVERSE_DEFAULT);
    if (error) {
        TRACE_ERROR_STRING("Error (bind):", failed_to_process);
        fprintf(file, "%s\n", failed_to_process);
        return;
    }

    while(1) {
        /* Loop through a collection */
        error = col_iterate_collection(iterator, &item);
        if (error) {
            TRACE_ERROR_STRING("Error (iterate):", failed_to_process);
            fprintf(file, "%s\n", failed_to_process);
            col_unbind_iterator(iterator);
            return;
        }

        /* Are we done ? */
        if (item == NULL) break;

        /* Process collection header */
        if (col_get_item_type(item) == COL_TYPE_COLLECTION) {
            col_get_collection_count(item, &count);
            if (count <= 2) break;
        } else if (col_get_item_type(item) == COL_TYPE_STRING) {
            fprintf(file, error_header, (char *)col_get_item_data(item));
        }
        else {
            /* Put error into provided format */
            pe = (struct parse_error *)(col_get_item_data(item));
            fprintf(file, line_format,
                    col_get_item_property(item, NULL), /* Error or warning */
                    pe->error,                         /* Error */
                    pe->line,                          /* Line */
                    ini_get_error_str(pe->error,
                                      family));        /* Error str */
        }

    }

    /* Do not forget to unbind iterator - otherwise there will be a leak */
    col_unbind_iterator(iterator);

    TRACE_FLOW_STRING("print_error_list", "Exit");
}