[vlc-devel] [RFC] key/value parsing API

Rafaël Carré rafael.carre at gmail.com
Thu Mar 8 03:19:45 CET 2012


Hi,

This is still for ffmpeg modules and x264 private options.

static int parse(const char *string,
	void (*callback)(char *key, char *val, void *data), void *data);

Parse a string (s) into key/values, calling a callback for each pair
until failure or end of string.

Possible failures:
	- E2BIG (key or val is > 1024 chars)
	- EINVAL (bad syntax)

Syntax:
{key=val,key=val,key=val}

Use \ to escape }=,\

I would put it next to the config_ stuff in libvlccore although none of
it uses it (yet).

-------8<------->8---------
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>

static int parse(const char *s, void (*cb)(char *key, char *val, void
*data), void *data)
{
    if (!s || !*s) /* no options given */
        return 0;

    if (*s++ != '{') /* doesn't start with { */
        return EINVAL;

    char key[1024+1], val[1024+1];
    size_t len = 0;
    char *parse = key;

    bool esc = false;
    while (*s) {
        char c = *s++;

        if (!esc) switch (c) { /* command character ? */
        case '\\':
            esc = true;
            continue;

        case '=': /* we now read the value */
            if (parse != key)
                return EINVAL;
            parse[len] = '\0';
            parse = val;
            len = 0;
            continue;

        case ',': /* we got a new option */
            if (parse != val)
                return EINVAL;
            parse[len] = '\0';
            cb(key, val, data);
            parse = key;
            len = 0;
            continue;

        case '}': /* we finished parsing */
            goto out;
        }

        esc = false;
        if (len == 1024)
            return E2BIG;
        parse[len++] = c;
    }

out:
    if (parse != val)
        return EINVAL;
    parse[len] = '\0';
    cb(key, val, data);
    return 0;
}

static void set(char *k, char *v, void *data)
{
    printf("%s = %s\n", k, v);
}

/*
 ./a.out '{k=v,k2=\=\}\,v}'
    k = v
    k2 = =},v
 ./a.out '}'
 ./a.out 'a='
 ./a.out 'a=v,'
    EINVAL
 ./a.out "{`yes|head -513`"
    E2BIG
 */

int main(int argc, char *argv[])
{
    if (argc != 2)
        return 10;

    errno = parse(argv[1], set, (void*)0);
    perror("parse");

}



More information about the vlc-devel mailing list