add some functions for parsing a value in a .desktop file
This commit is contained in:
parent
e02f788409
commit
0b9910b442
1 changed files with 107 additions and 0 deletions
107
obt/ddfile.c
107
obt/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 _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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue