all repos — openbox @ 00fb4d392fd25641f877c658463ccfd3286003bf

openbox fork - make it a bit more like ryudo

parse key/value pairs from the .desktop file and save them in a hashtable
Dana Jansens danakj@orodu.net
commit

00fb4d392fd25641f877c658463ccfd3286003bf

parent

448cc6620e1b36544c2ce2e75727e55cdf604f80

1 files changed, 72 insertions(+), 2 deletions(-)

jump to
M obt/ddfile.cobt/ddfile.c

@@ -26,19 +26,22 @@ #include <stdio.h>

#endif typedef void (*ObtDDParseGroupFunc)(const gchar *group, - const gchar *key, - const gchar *value); + GHashTable *key_hash); typedef struct _ObtDDParseGroup { gchar *name; gboolean seen; ObtDDParseGroupFunc func; + /* the key is a string (a key in the .desktop). + the value is a strings (a value in the .desktop) */ + GHashTable *key_hash; } ObtDDParseGroup; typedef struct _ObtDDParse { gchar *filename; gulong lineno; ObtDDParseGroup *group; + /* the key is a group name, the value is a ObtDDParseGroup */ GHashTable *group_hash; } ObtDDParse;

@@ -84,6 +87,7 @@

static void group_free(ObtDDParseGroup *g) { g_free(g->name); + g_hash_table_destroy(g->key_hash); g_slice_free(ObtDDParseGroup, g); }

@@ -306,6 +310,8 @@ if (!g) {

g = g_slice_new(ObtDDParseGroup); g->name = group; g->func = NULL; + g->key_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_free); g_hash_table_insert(parse->group_hash, group, g); } else

@@ -317,6 +323,64 @@ g_print("Found group %s\n", g->name);

} } +static void parse_key_value(const gchar *buf, gulong len, + ObtDDParse *parse, gboolean *error) +{ + gulong i, keyend, valstart, eq; + char *key, *val; + + /* find the end of the key */ + for (i = 0; i < len; ++i) + if (!(((guchar)buf[i] >= 'A' && (guchar)buf[i] <= 'Z') || + ((guchar)buf[i] >= 'a' && (guchar)buf[i] <= 'z') || + ((guchar)buf[i] >= '0' && (guchar)buf[i] <= '9') || + ((guchar)buf[i] == '-'))) { + /* not part of the key */ + keyend = i; + break; + } + if (keyend < 1) { + parse_error("Empty key", parse, error); + return; + } + /* find the = character */ + for (i = keyend; i < len; ++i) { + if (buf[i] == '=') { + eq = i; + break; + } + else if (buf[i] != ' ') { + parse_error("Invalid character in key name", parse, error); + return ; + } + } + if (i == len) { + parse_error("Key without value found", parse, error); + return; + } + /* find the start of the value */ + for (i = eq+1; i < len; ++i) + if (buf[i] != ' ') { + valstart = i; + break; + } + if (i == len) { + parse_error("Empty value found", parse, error); + return; + } + + key = g_strndup(buf, keyend); + val = g_strndup(buf+valstart, len-valstart); + if (g_hash_table_lookup(parse->group->key_hash, key)) { + parse_error("Duplicate key found", parse, error); + g_free(key); + g_free(val); + return; + } + g_hash_table_insert(parse->group->key_hash, key, val); + g_print("Found key/value %s=%s.\n", key, val); +} + static gboolean parse_file(ObtDDFile *dd, FILE *f, ObtDDParse *parse) { gchar *buf = NULL;

@@ -330,6 +394,12 @@ if (buf[0] == '#' || buf[0] == '\0')

; /* ignore comment lines */ else if (buf[0] == '[' && buf[len-1] == ']') parse_group(buf, len, parse, &error); + else if (!parse->group) + /* just ignore keys outside of groups */ + parse_error("Key found before group", parse, NULL); + else + /* ignore errors in key-value pairs and continue */ + parse_key_value(buf, len, parse, NULL); ++parse->lineno; }