]> Dogcows Code - chaz/openbox/blob - obt/ddfile.c
add some functions for parsing a value in a .desktop file
[chaz/openbox] / obt / ddfile.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3 obt/ddfile.c for the Openbox window manager
4 Copyright (c) 2009 Dana Jansens
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include "obt/ddfile.h"
20 #include <glib.h>
21 #ifdef HAVE_STRING_H
22 #include <string.h>
23 #endif
24 #ifdef HAVE_STDIO_H
25 #include <stdio.h>
26 #endif
27
28 typedef struct _ObtDDParse {
29 gchar *filename;
30 gulong lineno;
31 } ObtDDParse;
32
33 typedef enum {
34 DATA_STRING,
35 DATA_LOCALESTRING,
36 DATA_BOOLEAN,
37 DATA_NUMERIC,
38 NUM_DATA_TYPES
39 } ObtDDDataType;
40
41 struct _ObtDDFile {
42 ObtDDFileType type;
43 gchar *name; /*!< Specific name for the object (eg Firefox) */
44 gchar *generic; /*!< Generic name for the object (eg Web Browser) */
45 gchar *comment; /*!< Comment/description to display for the object */
46 gchar *icon; /*!< Name/path for an icon for the object */
47
48 union _ObtDDFileData {
49 struct {
50 gchar *exec; /*!< Executable to run for the app */
51 gchar *wdir; /*!< Working dir to run the app in */
52 gboolean term; /*!< Run the app in a terminal or not */
53 ObtDDFileAppOpen open;
54
55 /* XXX gchar**? or something better, a mime struct.. maybe
56 glib has something i can use. */
57 gchar **mime; /*!< Mime types the app can open */
58
59 ObtDDFileAppStartup startup;
60 gchar *startup_wmclass;
61 } app;
62 struct {
63 gchar *url;
64 } link;
65 struct {
66 } dir;
67 } d;
68 };
69
70 static void parse_error(const gchar *m, const ObtDDParse *const parse,
71 gboolean *error)
72 {
73 if (!parse->filename)
74 g_warning("%s at line %lud of input\n", m, parse->lineno);
75 else
76 g_warning("%s at line %lud of file %s\n",
77 m, parse->lineno, parse->filename);
78 if (error) *error = TRUE;
79 }
80
81 /* reads an input string, strips out invalid stuff, and parses
82 backslash-stuff */
83 static gchar* parse_string(const gchar *in, gboolean locale,
84 const ObtDDParse *const parse,
85 gboolean *error)
86 {
87 const gint bytes = strlen(in);
88 gboolean backslash;
89 gchar *out, *o;
90 const gchar *end, *i;
91
92 g_return_val_if_fail(in != NULL, NULL);
93
94 if (!locale) {
95 end = in + bytes;
96 for (i = in; i < end; ++i) {
97 if (*i > 127) {
98 end = i;
99 parse_error("Invalid bytes in string", parse, error);
100 break;
101 }
102 }
103 }
104 else if (!g_utf8_validate(in, bytes, &end))
105 parse_error("Invalid bytes in localestring", parse, error);
106
107 out = g_new(char, bytes + 1);
108 i = in; o = out;
109 backslash = FALSE;
110 while (i < end) {
111 const gchar *next = locale ? g_utf8_find_next_char(i, end) : i+1;
112 if (backslash) {
113 switch(*i) {
114 case 's': *o++ = ' '; break;
115 case 'n': *o++ = '\n'; break;
116 case 't': *o++ = '\t'; break;
117 case 'r': *o++ = '\r'; break;
118 case '\\': *o++ = '\\'; break;
119 default:
120 parse_error((locale ?
121 "Invalid escape sequence in localestring" :
122 "Invalid escape sequence in string"),
123 parse, error);
124 }
125 backslash = FALSE;
126 }
127 else if (*i == '\\')
128 backslash = TRUE;
129 else {
130 memcpy(o, i, next-i);
131 o += next-i;
132 }
133 i = next;
134 }
135 *o = '\0';
136 return o;
137 }
138
139 static gboolean parse_bool(const gchar *in, const ObtDDParse *const parse,
140 gboolean *error)
141 {
142 if (strcmp(in, "true") == 0)
143 return TRUE;
144 else if (strcmp(in, "false") != 0)
145 parse_error("Invalid boolean value", parse, error);
146 return FALSE;
147 }
148
149 static float parse_numeric(const gchar *in, const ObtDDParse *const parse,
150 gboolean *error)
151 {
152 float out = 0;
153 if (sscanf(in, "%f", &out) == 0)
154 parse_error("Invalid numeric value", parse, error);
155 return out;
156 }
This page took 0.034352 seconds and 4 git commands to generate.