Exemple #1
0
/* Handle key-value pair */
static int handle_kvp(struct parser_obj *po, uint32_t *action)
{
    int error = EOK;
    char *eq = NULL;
    uint32_t len = 0;
    char *dupval = NULL;
    char *str;
    uint32_t full_len;

    TRACE_FLOW_ENTRY();

    str = po->last_read;
    full_len = po->last_read_len;

    TRACE_INFO_STRING("Last read:", str);

    /* Trim spaces at the beginning */
    while ((full_len > 0) && (isspace(*(str)))) {
        str++;
        full_len--;
    }

    /* Check if we have the key */
    if (*(str) == '=') {
        TRACE_ERROR_STRING("No key", str);
        po->last_error = ERR_NOKEY;
        *action = PARSE_ERROR;
        return EOK;
    }

    /* Find "=" */
    eq = strchr(str, '=');
    if (eq == NULL) {
        TRACE_ERROR_STRING("No equal sign", str);
        po->last_error = ERR_NOEQUAL;
        *action = PARSE_ERROR;
        return EOK;
    }

    /* Strip spaces around "=" */
    /* Since eq > str we can substract 1 */
    len = eq - str - 1;
    while ((len > 0) && (isspace(*(str + len)))) len--;
    /* Adjust length properly */
    len++;

    /* Check the key length */
    if(len >= MAX_KEY) {
        TRACE_ERROR_STRING("Key name is too long", str);
        po->last_error = ERR_LONGKEY;
        *action = PARSE_ERROR;
        return EOK;
    }

    if (po->key) {
        /* Complete processing of the previous value */
        error = complete_value_processing(po);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to complete value processing", error);
            return error;
        }
    }

    /* Dup the key name */
    po->key = malloc(len + 1);
    if (!(po->key)) {
        TRACE_ERROR_NUMBER("Failed to dup key", ENOMEM);
        return ENOMEM;
    }

    memcpy(po->key, str, len);
    *(po->key + len) = '\0';
    po->key_len = len;

    TRACE_INFO_STRING("Key:", po->key);
    TRACE_INFO_NUMBER("Keylen:", po->key_len);

    len = full_len - (eq - str) - 1;

    /* Trim spaces after equal sign */
    eq++;
    while (isspace(*eq)) {
        eq++;
        len--;
    }

    TRACE_INFO_STRING("VALUE:", eq);
    TRACE_INFO_NUMBER("LENGTH:", len);

    /* Dup the part of the value */
    dupval = malloc(len + 1);
    if (!dupval) {
        TRACE_ERROR_NUMBER("Failed to dup value", ENOMEM);
        return ENOMEM;
    }

    memcpy(dupval, eq, len);
    *(dupval + len) = '\0';

    /* Create new arrays */
    error = value_create_arrays(&(po->raw_lines),
                                &(po->raw_lengths));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create arrays", error);
        free(dupval);
        return error;
    }

    /* Save a duplicated part in the value */
    error = value_add_to_arrays(dupval,
                                len,
                                po->raw_lines,
                                po->raw_lengths);

    if (error) {
        TRACE_ERROR_NUMBER("Failed to add value to arrays", error);
        free(dupval);
        return error;
    }

    /* Save the line number of the last found key */
    po->keylinenum = po->linenum;

    /* Prepare for reading */
    free(po->last_read);
    po->last_read = NULL;
    po->last_read_len = 0;

    *action = PARSE_READ;

    TRACE_FLOW_EXIT();
    return EOK;
}
Exemple #2
0
/* Create a copy of the value */
int value_copy(struct value_obj *vo,
               struct value_obj **copy_vo)
{

    int error = EOK;
    struct value_obj *new_vo = NULL;
    struct simplebuffer *oneline = NULL;

    TRACE_FLOW_ENTRY();

    if ((!copy_vo) || (!vo)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    /* Create buffer to hold the value */
    error = simplebuffer_alloc(&oneline);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
        return error;
    }

    /* Put value into the buffer */
    error = simplebuffer_add_str(oneline,
                                 (const char *)simplebuffer_get_buf(vo->unfolded),
                                 simplebuffer_get_len(vo->unfolded),
                                 INI_VALUE_BLOCK);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add string", error);
        simplebuffer_free(oneline);
        return error;
    }

    /* Acllocate new INI value structure */
    new_vo = malloc(sizeof(struct value_obj));
    if (!new_vo) {
        TRACE_ERROR_NUMBER("No memory", ENOMEM);
        simplebuffer_free(oneline);
        return ENOMEM;
    }

    new_vo->origin = vo->origin;
    new_vo->line = vo->line;
    new_vo->unfolded = oneline;
    new_vo->keylen = vo->keylen;
    new_vo->boundary = vo->boundary;
    new_vo->raw_lines = NULL;
    new_vo->raw_lengths = NULL;

    error = value_create_arrays(&(new_vo->raw_lines),
                                &(new_vo->raw_lengths));

    if (error) {
        TRACE_ERROR_NUMBER("Failed to fold", error);
        value_destroy(new_vo);
        return error;
    }

    /* Create arrays by folding the value */
    error = value_fold(new_vo->unfolded,
                       new_vo->keylen,
                       new_vo->boundary,
                       new_vo->raw_lines,
                       new_vo->raw_lengths);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to fold", error);
        value_destroy(new_vo);
        return error;
    }

    /* Copy comment */
    if (vo->ic) {
        error = ini_comment_copy(vo->ic, &new_vo->ic);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to copy comment", error);
            value_destroy(new_vo);
            return error;
        }
    }
    else new_vo->ic = NULL;

    *copy_vo = new_vo;

    TRACE_INFO_STRING("Orig value:",
                      (const char *)simplebuffer_get_buf(vo->unfolded));
    TRACE_INFO_STRING("Copy value:",
                      (const char *)simplebuffer_get_buf(new_vo->unfolded));

    TRACE_INFO_NUMBER("Orig value num lines:",
                      ref_array_len(vo->raw_lengths));
    TRACE_INFO_NUMBER("Copy value num lines:",
                      ref_array_len(new_vo->raw_lengths));

    TRACE_FLOW_EXIT();
    return error;
}
Exemple #3
0
/* Parse and process section */
static int handle_section(struct parser_obj *po, uint32_t *action)
{
    int error = EOK;
    char *start;
    char *end;
    char *dupval;
    uint32_t len;

    TRACE_FLOW_ENTRY();

    /* We are safe to substract 1
     * since we know that there is at
     * least one character on the line
     * based on the check above.
     */
    end = po->last_read + po->last_read_len - 1;
    while (isspace(*end)) end--;
    if (*end != ']') {
        *action = PARSE_ERROR;
        po->last_error = ERR_NOCLOSESEC;
        return EOK;
    }

    /* Skip spaces at the beginning of the section name */
    start = po->last_read + 1;
    while (isspace(*start)) start++;

    /* Check if there is a section name */
    if (start == end) {
        *action = PARSE_ERROR;
        po->last_error = ERR_NOSECTION;
        return EOK;
    }

    /* Skip spaces at the end of the section name */
    end--;
    while (isspace(*end)) end--;

    /* We got section name */
    len = end - start + 1;

    if (len > MAX_KEY) {
        *action = PARSE_ERROR;
        po->last_error = ERR_SECTIONLONG;
        return EOK;
    }

    if (po->key) {
        /* Complete processing of the previous value */
        error = complete_value_processing(po);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to complete value processing", error);
            return error;
        }
    }

    /* Save section if we have one*/
    error = parser_save_section(po);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to save section", error);
        return error;
    }

    /* Dup the name */
    dupval = malloc(len + 1);
    if (!dupval) {
        TRACE_ERROR_NUMBER("Failed to dup section name", ENOMEM);
        return ENOMEM;
    }

    memcpy(dupval, start, len);
    dupval[len] = '\0';

    /* Create a new section */
    error = col_create_collection(&po->sec,
                                  dupval,
                                  COL_CLASS_INI_SECTION);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create a section", error);
        free(dupval);
        return error;
    }

    /* But if there is just a comment then create a special key */
    po->key_len = sizeof(INI_SECTION_KEY) - 1;
    po->key = strndup(INI_SECTION_KEY, sizeof(INI_SECTION_KEY));
    /* Create new arrays */
    error = value_create_arrays(&(po->raw_lines),
                                &(po->raw_lengths));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create arrays", error);
        free(dupval);
        return error;
    }

    /* Save a duplicated part in the value */
    error = value_add_to_arrays(dupval,
                                len,
                                po->raw_lines,
                                po->raw_lengths);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add value to the arrays", error);
        free(dupval);
        return error;
    }

    /* Save the line number of the last found key */
    po->seclinenum = po->linenum;

    /* Complete processing of this value.
     * A new section will be created inside and a special
     * value will be added.
     */
    error = complete_value_processing(po);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to complete value processing", error);
        return error;
    }

    /* We are done dealing with section */
    free(po->last_read);
    po->last_read = NULL;
    po->last_read_len = 0;
    *action = PARSE_READ;

    TRACE_FLOW_EXIT();
    return EOK;

}
Exemple #4
0
/* Create value object from string buffer */
int value_create_new(const char *strvalue,
                     uint32_t length,
                     uint32_t origin,
                     uint32_t key_len,
                     uint32_t boundary,
                     struct ini_comment *ic,
                     struct value_obj **vo)
{
    int error = EOK;
    struct value_obj *new_vo = NULL;
    struct simplebuffer *oneline = NULL;

    TRACE_FLOW_ENTRY();

    if ((!strvalue) || (!vo)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    /* Create buffer to hold the value */
    error = simplebuffer_alloc(&oneline);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
        return error;
    }

    /* Put value into the buffer */
    error = simplebuffer_add_str(oneline,
                                 strvalue,
                                 length,
                                 INI_VALUE_BLOCK);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add string", error);
        simplebuffer_free(oneline);
        return error;
    }

    /* Acllocate new INI value structure */
    new_vo = malloc(sizeof(struct value_obj));
    if (!new_vo) {
        TRACE_ERROR_NUMBER("No memory", ENOMEM);
        simplebuffer_free(oneline);
        return ENOMEM;
    }

    new_vo->origin = origin;
    /* Line is not known in this case */
    new_vo->line = 0;
    new_vo->ic = ic;
    new_vo->unfolded = oneline;
    new_vo->keylen = key_len;
    new_vo->boundary = boundary;
    new_vo->raw_lines = NULL;
    new_vo->raw_lengths = NULL;

    error = value_create_arrays(&(new_vo->raw_lines),
                                &(new_vo->raw_lengths));

    if (error) {
        TRACE_ERROR_NUMBER("Failed to fold", error);
        value_destroy(new_vo);
        return error;
    }

    /* Create arrays by folding the value */
    error = value_fold(new_vo->unfolded,
                       new_vo->keylen,
                       new_vo->boundary,
                       new_vo->raw_lines,
                       new_vo->raw_lengths);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to fold", error);
        value_destroy(new_vo);
        return error;
    }

    *vo = new_vo;

    TRACE_FLOW_EXIT();

    return error;
}