all repos — openbox @ 0b9910b44263fc36590f562768e42c6e5683a46c

openbox fork - make it a bit more like ryudo

add some functions for parsing a value in a .desktop file
Dana Jansens danakj@orodu.net
commit

0b9910b44263fc36590f562768e42c6e5683a46c

parent

e02f788409393a701bbb26ebbb01a82f085f2e96

1 files changed, 107 insertions(+), 0 deletions(-)

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

@@ -18,6 +18,25 @@ */

#include "obt/ddfile.h" #include <glib.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif + +typedef struct _ObtDDParse { + gchar *filename; + gulong lineno; +} ObtDDParse; + +typedef enum { + DATA_STRING, + DATA_LOCALESTRING, + DATA_BOOLEAN, + DATA_NUMERIC, + NUM_DATA_TYPES +} ObtDDDataType; struct _ObtDDFile { ObtDDFileType type;

@@ -47,3 +66,91 @@ struct {

} dir; } d; }; + +static void parse_error(const gchar *m, const ObtDDParse *const parse, + gboolean *error) +{ + if (!parse->filename) + g_warning("%s at line %lud of input\n", m, parse->lineno); + else + g_warning("%s at line %lud of file %s\n", + m, parse->lineno, parse->filename); + if (error) *error = TRUE; +} + +/* reads an input string, strips out invalid stuff, and parses + backslash-stuff */ +static gchar* parse_string(const gchar *in, gboolean locale, + const ObtDDParse *const parse, + gboolean *error) +{ + const gint bytes = strlen(in); + gboolean backslash; + gchar *out, *o; + const gchar *end, *i; + + g_return_val_if_fail(in != NULL, NULL); + + if (!locale) { + end = in + bytes; + for (i = in; i < end; ++i) { + if (*i > 127) { + end = i; + parse_error("Invalid bytes in string", parse, error); + break; + } + } + } + else if (!g_utf8_validate(in, bytes, &end)) + parse_error("Invalid bytes in localestring", parse, error); + + out = g_new(char, bytes + 1); + i = in; o = out; + backslash = FALSE; + while (i < end) { + const gchar *next = locale ? g_utf8_find_next_char(i, end) : i+1; + if (backslash) { + switch(*i) { + case 's': *o++ = ' '; break; + case 'n': *o++ = '\n'; break; + case 't': *o++ = '\t'; break; + case 'r': *o++ = '\r'; break; + case '\\': *o++ = '\\'; break; + default: + parse_error((locale ? + "Invalid escape sequence in localestring" : + "Invalid escape sequence in string"), + parse, error); + } + backslash = FALSE; + } + else if (*i == '\\') + backslash = TRUE; + else { + memcpy(o, i, next-i); + o += next-i; + } + i = next; + } + *o = '\0'; + return o; +} + +static gboolean parse_bool(const gchar *in, const ObtDDParse *const parse, + gboolean *error) +{ + if (strcmp(in, "true") == 0) + return TRUE; + else if (strcmp(in, "false") != 0) + parse_error("Invalid boolean value", parse, error); + return FALSE; +} + +static float parse_numeric(const gchar *in, const ObtDDParse *const parse, + gboolean *error) +{ + float out = 0; + if (sscanf(in, "%f", &out) == 0) + parse_error("Invalid numeric value", parse, error); + return out; +}