From 0b9910b44263fc36590f562768e42c6e5683a46c Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 23 Mar 2010 20:12:16 -0400 Subject: [PATCH] add some functions for parsing a value in a .desktop file --- obt/ddfile.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/obt/ddfile.c b/obt/ddfile.c index c9ec32dd..9c651e6b 100644 --- a/obt/ddfile.c +++ b/obt/ddfile.c @@ -18,6 +18,25 @@ #include "obt/ddfile.h" #include +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#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 _ObtDDFile { } 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; +}