Exemple #1
0
static
GList* load_bzrep_conf_file(const char *path)
{
    FILE *fp = stdin;
    if (strcmp(path, "-") != 0)
    {
        fp = fopen(path, "r");
        if (!fp)
            return NULL;
    }

    GList *sections = NULL;

    char *line;
    while ((line = xmalloc_fgetline(fp)) != NULL)
    {
        /* Skip comments */
        char first = *skip_whitespace(line);
        if (first == '#')
            goto free_line;

        /* Handle trailing backslash continuation */
 check_continuation: ;
        unsigned len = strlen(line);
        if (len && line[len-1] == '\\')
        {
            line[len-1] = '\0';
            char *next_line = xmalloc_fgetline(fp);
            if (next_line)
            {
                line = append_to_malloced_string(line, next_line);
                free(next_line);
                goto check_continuation;
            }
        }

        /* We are reusing line buffer to form temporary
         * "key\0values\0..." in its beginning
         */
        bool summary_line = false;
        char *value = NULL;
        char *src;
        char *dst;
        for (src = dst = line; *src; src++)
        {
            char c = *src;
            /* did we reach the value list? */
            if (!value && c == ':' && src[1] == ':')
            {
                *dst++ = '\0'; /* terminate key */
                src += 2;
                value = dst; /* remember where value starts */
                summary_line = (strcmp(line, "%summary") == 0);
                if (summary_line)
                {
                    value = src;
                    break;
                }
                continue;
            }
            /* skip whitespace in value list */
            if (value && isspace(c))
                continue;
            *dst++ = c; /* store next key or value char */
        }

        GList *item_list = NULL;
        if (summary_line)
        {
            /* %summary is special */
            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
        }
        else
        {
            *dst = '\0'; /* terminate value (or key) */
            if (value)
                item_list = split_string_on_char(value, ',');
        }

        section_t *sec = xzalloc(sizeof(*sec));
        sec->name = xstrdup(line);
        sec->items = item_list;
        sections = g_list_prepend(sections, sec);

 free_line:
        free(line);
    }

    if (fp != stdin)
        fclose(fp);

    return g_list_reverse(sections);
}
Exemple #2
0
static GList*
load_stream(FILE *fp)
{
    assert(fp);

    GList *sections = NULL;
    section_t *master = section_new("%description");
    section_t *sec = NULL;

    sections = g_list_append(sections, master);

    char *line;
    while ((line = xmalloc_fgetline(fp)) != NULL)
    {
        /* Skip comments */
        char first = *skip_whitespace(line);
        if (first == '#')
            goto free_line;

        /* Handle trailing backslash continuation */
 check_continuation: ;
        unsigned len = strlen(line);
        if (len && line[len-1] == '\\')
        {
            line[len-1] = '\0';
            char *next_line = xmalloc_fgetline(fp);
            if (next_line)
            {
                line = append_to_malloced_string(line, next_line);
                free(next_line);
                goto check_continuation;
            }
        }

        /* We are reusing line buffer to form temporary
         * "key\0values\0..." in its beginning
         */
        bool summary_line = false;
        char *value = NULL;
        char *src;
        char *dst;
        for (src = dst = line; *src; src++)
        {
            char c = *src;
            /* did we reach the value list? */
            if (!value && c == ':' && src[1] == ':')
            {
                *dst++ = '\0'; /* terminate key */
                src += 1;
                value = dst; /* remember where value starts */
                summary_line = (strcmp(line, "%summary") == 0);
                if (summary_line)
                {
                    value = (src + 1);
                    break;
                }
                continue;
            }
            /* skip whitespace in value list */
            if (value && isspace(c))
                continue;
            *dst++ = c; /* store next key or value char */
        }

        GList *item_list = NULL;
        if (summary_line)
        {
            /* %summary is special */
            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
        }
        else
        {
            *dst = '\0'; /* terminate value (or key) */
            if (value)
                item_list = split_string_on_char(value, ',');
        }

        sec = section_new(line);
        sec->items = item_list;

        if (sec->name[0] == '%')
        {
            if (!summary_line && strcmp(sec->name, "%attach") != 0)
            {
                master->children = g_list_reverse(master->children);
                master = sec;
            }

            sections = g_list_prepend(sections, sec);
        }
        else
            master->children = g_list_prepend(master->children, sec);

 free_line:
        free(line);
    }

    /* If master equals sec, then master's children list was not yet reversed.
     *
     * %description is the default section (i.e is not explicitly mentioned)
     * and %summary nor %attach cause its children list to reverse.
     */
    if (master == sec || strcmp(master->name, "%description") == 0)
        master->children = g_list_reverse(master->children);

    return sections;
}