#include <glib.h>
#include <stdlib.h>

#define SEP "\\s+"
#define PAD "\\s*+"
#define C_WORD "[_a-zA-Z][_a-zA-Z0-9]*+"

#define TYPE "(?:(?P<type>"C_WORD ")|(?:const" SEP ")(?P<type>" C_WORD ")|(?P<type>" C_WORD ")(?:" SEP "const))"
#define STARSEP "(?:" PAD "(?P<star>\\*)" PAD "|" PAD ")"

#define ARG_NM "(?P<nm>[nm])"
#define ARG_STRIDE "(?P<stride>(?P<arg_class>[isd])s(?P<index>\\d?))"
#define LEN_SPEC "\\d+|[nm](p\\d+)?"
#define ARG_VECTOR "(?P<array>(?P<arg_class>[isd])(?P<index>\\d?)"\
"(_(?P<len1>"LEN_SPEC")(x(?P<len2>"LEN_SPEC"))?)?)"

#define ARG "("ARG_NM"|"ARG_STRIDE"|"ARG_VECTOR")"
#define PARAM "^" PAD TYPE STARSEP ARG PAD "$"

gint main ()
{
    const gchar reg[] = PARAM;
    GRegex *param_pattern = NULL;
    gchar param_str[] = "uint32_t *i_n";
    GMatchInfo *param_info = NULL;
    
    GError *err = NULL;
    
    g_print ("Create regex: %s\n", reg);
    param_pattern = g_regex_new (PARAM,
            G_REGEX_NO_AUTO_CAPTURE | G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES,
            0, &err);
    
    if (err) {
        g_print ("failed to create regex\n");
        exit (-1);
    }
    g_print ("Match \"%s\"", param_str);
    if (!g_regex_match (param_pattern, param_str, 0, &param_info)) {
            g_warning ("Bad parameter: \"%s\"", param_str);
            goto out;
    }
    
    {
        gchar *arg_class, *index, *len1, *len2;
        arg_class = g_match_info_fetch_named (param_info, "arg_class");
        index = g_match_info_fetch_named (param_info, "index");
        len1 = g_match_info_fetch_named (param_info, "len1");
        len2 = g_match_info_fetch_named (param_info, "len2");
        
        g_print ("arg_class: \"%s\", index: \"%s\", len1: \"%s\", len2: \"%s\"\n", arg_class, index, len1, len2);
    }

out: 
    if (param_info)
        g_match_info_free (param_info);
    
    return 0;
}
