1 |
commit: 5879972108bc28629f41c56d34592642df0c4588 |
2 |
Author: Alexandre Rostovtsev <tetromino <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Feb 9 08:26:48 2012 +0000 |
4 |
Commit: Alexandre Restovtsev <tetromino <AT> gmail <DOT> com> |
5 |
CommitDate: Thu Feb 9 08:40:24 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/openrc-settingsd.git;a=commit;h=58799721 |
7 |
|
8 |
Add beginnings of localed (read-only and no xorg.conf support) |
9 |
|
10 |
--- |
11 |
.gitignore | 1 + |
12 |
Makefile.am | 21 +++++- |
13 |
README | 22 +++++ |
14 |
TODO | 2 +- |
15 |
data/locale1.xml | 30 +++++++ |
16 |
src/localed.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
17 |
src/localed.h | 31 +++++++ |
18 |
src/main.c | 3 + |
19 |
src/shell-utils.c | 83 ++++++++++++++++---- |
20 |
src/shell-utils.h | 5 + |
21 |
10 files changed, 406 insertions(+), 19 deletions(-) |
22 |
|
23 |
diff --git a/.gitignore b/.gitignore |
24 |
index b0d689f..8fae933 100644 |
25 |
--- a/.gitignore |
26 |
+++ b/.gitignore |
27 |
@@ -20,6 +20,7 @@ |
28 |
/openrc-settingsd |
29 |
/stamp-h1 |
30 |
/src/hostname1-generated.[ch] |
31 |
+/src/locale1-generated.[ch] |
32 |
|
33 |
# Relative rules |
34 |
*.o |
35 |
|
36 |
diff --git a/Makefile.am b/Makefile.am |
37 |
index f2a770a..7ae61ed 100644 |
38 |
--- a/Makefile.am |
39 |
+++ b/Makefile.am |
40 |
@@ -2,6 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} |
41 |
|
42 |
EXTRA_DIST = \ |
43 |
data/hostname1.xml \ |
44 |
+ data/locale1.xml \ |
45 |
$(NULL) |
46 |
|
47 |
AM_CPPFLAGS = \ |
48 |
@@ -22,10 +23,18 @@ hostnamed_built_sources = \ |
49 |
src/hostname1-generated.h \ |
50 |
$(NULL) |
51 |
|
52 |
+localed_built_sources = \ |
53 |
+ src/locale1-generated.c \ |
54 |
+ src/locale1-generated.h \ |
55 |
+ $(NULL) |
56 |
+ |
57 |
openrc_settingsd_SOURCES = \ |
58 |
$(hostnamed_built_sources) \ |
59 |
+ $(localed_built_sources) \ |
60 |
src/hostnamed.c \ |
61 |
src/hostnamed.h \ |
62 |
+ src/localed.c \ |
63 |
+ src/localed.h \ |
64 |
src/bus-utils.c \ |
65 |
src/bus-utils.h \ |
66 |
src/shell-utils.c \ |
67 |
@@ -41,5 +50,13 @@ $(hostnamed_built_sources) : data/hostname1.xml |
68 |
$(srcdir)/data/hostname1.xml; \ |
69 |
mv hostname1-generated.{c,h} $(top_srcdir)/src/ ) |
70 |
|
71 |
-BUILT_SOURCES = $(hostnamed_built_sources) |
72 |
-CLEANFILES = $(hostnamed_built_sources) |
73 |
+$(localed_built_sources) : data/locale1.xml |
74 |
+ ( $(GDBUS_CODEGEN) \ |
75 |
+ --interface-prefix org.freedesktop. \ |
76 |
+ --c-namespace OpenrcSettingsdLocaled \ |
77 |
+ --generate-c-code locale1-generated \ |
78 |
+ $(srcdir)/data/locale1.xml; \ |
79 |
+ mv locale1-generated.{c,h} $(top_srcdir)/src/ ) |
80 |
+ |
81 |
+BUILT_SOURCES = $(hostnamed_built_sources) $(localed_built_sources) |
82 |
+CLEANFILES = $(hostnamed_built_sources) $(localed_built_sources) |
83 |
|
84 |
diff --git a/README b/README |
85 |
index 62bd904..bd6adac 100644 |
86 |
--- a/README |
87 |
+++ b/README |
88 |
@@ -16,6 +16,28 @@ Hostnamed: |
89 |
PRETTY_HOSTNAME="Foo !" |
90 |
ICON_NAME="computer-desktop" |
91 |
|
92 |
+Localed: |
93 |
+ |
94 |
+ See http://www.freedesktop.org/wiki/Software/systemd/localed for the DBus |
95 |
+ protocol description. |
96 |
+ |
97 |
+ The system locale variables are set in /etc/env.d/02locale. |
98 |
+ |
99 |
+ Virtual console keymap is set in /etc/conf.d/keymaps as |
100 |
+ keymap="foo" |
101 |
+ The virtual console keymap toggle is not supported. |
102 |
+ |
103 |
+/* |
104 |
+ Not implemented yet. |
105 |
+ |
106 |
+ X11 keyboard options are set in /etc/X11/xorg.conf.d/30-keyboard.conf |
107 |
+ (falling back to 00-keyboard.conf if it exists and 30-keyboard.conf does |
108 |
+ not) in an InputClass section. |
109 |
+ Localed will attempt to detect if multiple InputClass sections with |
110 |
+ keyboard options exist in /etc/X11/xorg.conf and /etc/X11/xorg.conf.d/, |
111 |
+ and if that is the case, will refuse to modify X11 keyboard settings. |
112 |
+*/ |
113 |
+ |
114 |
Note that openrc-settingsd expects any shell-syntax settings files that it |
115 |
modifies to be in UTF-8 encoding, and to consist only of comments and simple |
116 |
scalar assignments, i.e. something like |
117 |
|
118 |
diff --git a/TODO b/TODO |
119 |
index e8694da..a7feb33 100644 |
120 |
--- a/TODO |
121 |
+++ b/TODO |
122 |
@@ -1,4 +1,4 @@ |
123 |
-Add nss-myhostname detection (and add nss-myhostnane to portage) |
124 |
+Add nss-myhostname detection |
125 |
|
126 |
Source /etc/rc.conf after /etc/conf.d/$service; do something intelligent |
127 |
if the relevant variable is set in /etc/rc.conf (go to read-only mode?) |
128 |
|
129 |
diff --git a/data/locale1.xml b/data/locale1.xml |
130 |
new file mode 100644 |
131 |
index 0000000..dfd98d3 |
132 |
--- /dev/null |
133 |
+++ b/data/locale1.xml |
134 |
@@ -0,0 +1,30 @@ |
135 |
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
136 |
+<node name="/org/freedesktop/locale1"> |
137 |
+ <interface name="org.freedesktop.locale1"> |
138 |
+ <method name="SetLocale"> |
139 |
+ <arg direction="in" type="as" name="locale"/> |
140 |
+ <arg direction="in" type="b" name="user_interaction"/> |
141 |
+ </method> |
142 |
+ <method name="SetVConsoleKeyboard"> |
143 |
+ <arg direction="in" type="s" name="keymap"/> |
144 |
+ <arg direction="in" type="s" name="keymap_toggle"/> |
145 |
+ <arg direction="in" type="b" name="convert"/> |
146 |
+ <arg direction="in" type="b" name="user_interaction"/> |
147 |
+ </method> |
148 |
+ <method name="SetX11Keyboard"> |
149 |
+ <arg direction="in" type="s" name="layout"/> |
150 |
+ <arg direction="in" type="s" name="model"/> |
151 |
+ <arg direction="in" type="s" name="variant"/> |
152 |
+ <arg direction="in" type="s" name="options"/> |
153 |
+ <arg direction="in" type="b" name="convert"/> |
154 |
+ <arg direction="in" type="b" name="user_interaction"/> |
155 |
+ </method> |
156 |
+ <property name="Locale" type="as" access="read"/> |
157 |
+ <property name="VConsoleKeymap" type="s" access="read"/> |
158 |
+ <property name="VConsoleKeymapToggle" type="s" access="read"/> |
159 |
+ <property name="X11Layout" type="s" access="read"/> |
160 |
+ <property name="X11Model" type="s" access="read"/> |
161 |
+ <property name="X11Variant" type="s" access="read"/> |
162 |
+ <property name="X11Options" type="s" access="read"/> |
163 |
+ </interface> |
164 |
+</node> |
165 |
|
166 |
diff --git a/src/localed.c b/src/localed.c |
167 |
new file mode 100644 |
168 |
index 0000000..12d9ad7 |
169 |
--- /dev/null |
170 |
+++ b/src/localed.c |
171 |
@@ -0,0 +1,227 @@ |
172 |
+/* |
173 |
+ Copyright 2012 Alexandre Rostovtsev |
174 |
+ |
175 |
+ This program is free software; you can redistribute it and/or modify |
176 |
+ it under the terms of the GNU General Public License as published by |
177 |
+ the Free Software Foundation; either version 2 of the License, or |
178 |
+ (at your option) any later version. |
179 |
+ |
180 |
+ This program is distributed in the hope that it will be useful, |
181 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
182 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
183 |
+ GNU General Public License for more details. |
184 |
+ |
185 |
+ You should have received a copy of the GNU General Public License |
186 |
+ along with this program; if not, write to the Free Software |
187 |
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
188 |
+*/ |
189 |
+ |
190 |
+#include <stdlib.h> |
191 |
+ |
192 |
+#include <dbus/dbus-protocol.h> |
193 |
+#include <glib.h> |
194 |
+#include <gio/gio.h> |
195 |
+ |
196 |
+#include "localed.h" |
197 |
+#include "locale1-generated.h" |
198 |
+#include "bus-utils.h" |
199 |
+#include "shell-utils.h" |
200 |
+ |
201 |
+#include "config.h" |
202 |
+ |
203 |
+#define SERVICE_NAME "openrc-settingsd localed" |
204 |
+ |
205 |
+static guint bus_id = 0; |
206 |
+static gboolean read_only = FALSE; |
207 |
+ |
208 |
+static OpenrcSettingsdLocaledLocale1 *locale1 = NULL; |
209 |
+ |
210 |
+static gchar *locale_variables[] = { |
211 |
+ "LANG", "LC_CTYPE", "LC_NUMERIC", "LC_TIME", "LC_COLLATE", "LC_MONETARY", "LC_MESSAGES", "LC_PAPER", "LC_NAME", "LC_ADDRESS", "LC_TELEPHONE", "LC_MEASUREMENT", "LC_IDENTIFICATION", NULL |
212 |
+}; |
213 |
+ |
214 |
+static gchar **locale = NULL; /* Expected format is { "LANG=foo", "LC_TIME=bar", NULL } */ |
215 |
+static GFile *locale_file = NULL; |
216 |
+G_LOCK_DEFINE_STATIC (locale); |
217 |
+ |
218 |
+static gchar *vconsole_keymap = NULL; |
219 |
+static gchar *vconsole_keymap_toggle = NULL; |
220 |
+static GFile *keymaps_file = NULL; |
221 |
+G_LOCK_DEFINE_STATIC (keymaps); |
222 |
+ |
223 |
+static gchar *x11_layout = NULL; |
224 |
+static gchar *x11_model = NULL; |
225 |
+static gchar *x11_variant = NULL; |
226 |
+static gchar *x11_options = NULL; |
227 |
+G_LOCK_DEFINE_STATIC (xorg_conf); |
228 |
+ |
229 |
+static gboolean |
230 |
+on_handle_set_locale (OpenrcSettingsdLocaledLocale1 *locale1, |
231 |
+ GDBusMethodInvocation *invocation, |
232 |
+ const gchar * const *_locale, |
233 |
+ const gboolean user_interaction, |
234 |
+ gpointer user_data) |
235 |
+{ |
236 |
+ g_dbus_method_invocation_return_dbus_error (invocation, |
237 |
+ DBUS_ERROR_NOT_SUPPORTED, |
238 |
+ SERVICE_NAME " is in read-only mode"); |
239 |
+ |
240 |
+ return TRUE; |
241 |
+} |
242 |
+ |
243 |
+static gboolean |
244 |
+on_handle_set_vconsole_keyboard (OpenrcSettingsdLocaledLocale1 *locale1, |
245 |
+ GDBusMethodInvocation *invocation, |
246 |
+ const gchar *keymap, |
247 |
+ const gchar *keymap_toggle, |
248 |
+ const gboolean convert, |
249 |
+ const gboolean user_interaction, |
250 |
+ gpointer user_data) |
251 |
+{ |
252 |
+ g_dbus_method_invocation_return_dbus_error (invocation, |
253 |
+ DBUS_ERROR_NOT_SUPPORTED, |
254 |
+ SERVICE_NAME " is in read-only mode"); |
255 |
+ |
256 |
+ return TRUE; |
257 |
+} |
258 |
+ |
259 |
+static gboolean |
260 |
+on_handle_set_x11_keyboard (OpenrcSettingsdLocaledLocale1 *locale1, |
261 |
+ GDBusMethodInvocation *invocation, |
262 |
+ const gchar *layout, |
263 |
+ const gchar *model, |
264 |
+ const gchar *variant, |
265 |
+ const gchar *options, |
266 |
+ const gboolean convert, |
267 |
+ const gboolean user_interaction, |
268 |
+ gpointer user_data) |
269 |
+{ |
270 |
+ g_dbus_method_invocation_return_dbus_error (invocation, |
271 |
+ DBUS_ERROR_NOT_SUPPORTED, |
272 |
+ SERVICE_NAME " is in read-only mode"); |
273 |
+ |
274 |
+ return TRUE; |
275 |
+} |
276 |
+ |
277 |
+static void |
278 |
+on_bus_acquired (GDBusConnection *connection, |
279 |
+ const gchar *bus_name, |
280 |
+ gpointer user_data) |
281 |
+{ |
282 |
+ gchar *name; |
283 |
+ GError *err = NULL; |
284 |
+ |
285 |
+ g_debug ("Acquired a message bus connection"); |
286 |
+ |
287 |
+ locale1 = openrc_settingsd_localed_locale1_skeleton_new (); |
288 |
+ |
289 |
+ openrc_settingsd_localed_locale1_set_locale (locale1, (const gchar * const *) locale); |
290 |
+ openrc_settingsd_localed_locale1_set_vconsole_keymap (locale1, vconsole_keymap); |
291 |
+ openrc_settingsd_localed_locale1_set_vconsole_keymap_toggle (locale1, vconsole_keymap_toggle); |
292 |
+ openrc_settingsd_localed_locale1_set_x11_layout (locale1, x11_layout); |
293 |
+ openrc_settingsd_localed_locale1_set_x11_model (locale1, x11_model); |
294 |
+ openrc_settingsd_localed_locale1_set_x11_variant (locale1, x11_variant); |
295 |
+ openrc_settingsd_localed_locale1_set_x11_options (locale1, x11_options); |
296 |
+ |
297 |
+ g_signal_connect (locale1, "handle-set-locale", G_CALLBACK (on_handle_set_locale), NULL); |
298 |
+ g_signal_connect (locale1, "handle-set-vconsole-keyboard", G_CALLBACK (on_handle_set_vconsole_keyboard), NULL); |
299 |
+ g_signal_connect (locale1, "handle-set-x11-keyboard", G_CALLBACK (on_handle_set_x11_keyboard), NULL); |
300 |
+ |
301 |
+ if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (locale1), |
302 |
+ connection, |
303 |
+ "/org/freedesktop/locale1", |
304 |
+ &err)) { |
305 |
+ if (err != NULL) { |
306 |
+ g_printerr ("Failed to export interface on /org/freedesktop/locale1: %s\n", err->message); |
307 |
+ g_error_free (err); |
308 |
+ } |
309 |
+ } |
310 |
+} |
311 |
+ |
312 |
+static void |
313 |
+on_name_acquired (GDBusConnection *connection, |
314 |
+ const gchar *bus_name, |
315 |
+ gpointer user_data) |
316 |
+{ |
317 |
+ g_debug ("Acquired the name %s", bus_name); |
318 |
+} |
319 |
+ |
320 |
+static void |
321 |
+on_name_lost (GDBusConnection *connection, |
322 |
+ const gchar *bus_name, |
323 |
+ gpointer user_data) |
324 |
+{ |
325 |
+ if (connection == NULL) |
326 |
+ g_printerr ("Failed to acquire a dbus connection\n"); |
327 |
+ else |
328 |
+ g_printerr ("Failed to acquire dbus name %s\n", bus_name); |
329 |
+ exit(-1); |
330 |
+} |
331 |
+ |
332 |
+void |
333 |
+localed_init (gboolean _read_only) |
334 |
+{ |
335 |
+ GError *err = NULL; |
336 |
+ gchar **locale_values = NULL; |
337 |
+ |
338 |
+ read_only = _read_only; |
339 |
+ locale_file = g_file_new_for_path (SYSCONFDIR "/env.d/02locale"); |
340 |
+ keymaps_file = g_file_new_for_path (SYSCONFDIR "/conf.d/keymaps"); |
341 |
+ |
342 |
+ locale = g_new0 (gchar *, g_strv_length (locale_variables) + 1); |
343 |
+ locale_values = shell_utils_trivial_source_var_list (locale_file, (const gchar * const *)locale_variables, &err); |
344 |
+ if (locale_values != NULL) { |
345 |
+ gchar **variable, **value, **loc; |
346 |
+ loc = locale; |
347 |
+ for (variable = locale_variables, value = locale_values; *variable != NULL; variable++, value++) { |
348 |
+ if (*value != NULL) { |
349 |
+ *loc = g_strdup_printf ("%s=%s", *variable, *value); |
350 |
+ loc++; |
351 |
+ } |
352 |
+ } |
353 |
+ |
354 |
+ g_strfreev (locale_values); |
355 |
+ } |
356 |
+ if (err != NULL) { |
357 |
+ g_debug ("%s", err->message); |
358 |
+ g_clear_error (&err); |
359 |
+ } |
360 |
+ |
361 |
+ vconsole_keymap = shell_utils_source_var (keymaps_file, "${keymap}", &err); |
362 |
+ if (vconsole_keymap == NULL) |
363 |
+ vconsole_keymap = g_strdup (""); |
364 |
+ if (err != NULL) { |
365 |
+ g_debug ("%s", err->message); |
366 |
+ g_clear_error (&err); |
367 |
+ } |
368 |
+ |
369 |
+ /* We don't have a good equivalent for this in openrc at the moment */ |
370 |
+ vconsole_keymap_toggle = g_strdup (""); |
371 |
+ |
372 |
+ bus_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, |
373 |
+ "org.freedesktop.locale1", |
374 |
+ G_BUS_NAME_OWNER_FLAGS_NONE, |
375 |
+ on_bus_acquired, |
376 |
+ on_name_acquired, |
377 |
+ on_name_lost, |
378 |
+ NULL, |
379 |
+ NULL); |
380 |
+} |
381 |
+ |
382 |
+void |
383 |
+localed_destroy (void) |
384 |
+{ |
385 |
+ g_bus_unown_name (bus_id); |
386 |
+ bus_id = 0; |
387 |
+ read_only = FALSE; |
388 |
+ g_strfreev (locale); |
389 |
+ g_free (vconsole_keymap); |
390 |
+ g_free (vconsole_keymap_toggle); |
391 |
+ g_free (x11_layout); |
392 |
+ g_free (x11_model); |
393 |
+ g_free (x11_variant); |
394 |
+ g_free (x11_options); |
395 |
+ |
396 |
+ g_object_unref (locale_file); |
397 |
+ g_object_unref (keymaps_file); |
398 |
+} |
399 |
|
400 |
diff --git a/src/localed.h b/src/localed.h |
401 |
new file mode 100644 |
402 |
index 0000000..dff55c6 |
403 |
--- /dev/null |
404 |
+++ b/src/localed.h |
405 |
@@ -0,0 +1,31 @@ |
406 |
+/* |
407 |
+ Copyright 2012 Alexandre Rostovtsev |
408 |
+ |
409 |
+ This program is free software; you can redistribute it and/or modify |
410 |
+ it under the terms of the GNU General Public License as published by |
411 |
+ the Free Software Foundation; either version 2 of the License, or |
412 |
+ (at your option) any later version. |
413 |
+ |
414 |
+ This program is distributed in the hope that it will be useful, |
415 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
416 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
417 |
+ GNU General Public License for more details. |
418 |
+ |
419 |
+ You should have received a copy of the GNU General Public License |
420 |
+ along with this program; if not, write to the Free Software |
421 |
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
422 |
+*/ |
423 |
+ |
424 |
+#ifndef OPENRC_LOCALED_H |
425 |
+#define OPENRC_LOCALED_H |
426 |
+ |
427 |
+#include <glib.h> |
428 |
+#include <gio/gio.h> |
429 |
+ |
430 |
+void |
431 |
+localed_init (gboolean read_only); |
432 |
+ |
433 |
+void |
434 |
+localed_destroy (void); |
435 |
+ |
436 |
+#endif |
437 |
|
438 |
diff --git a/src/main.c b/src/main.c |
439 |
index c7165f0..fabb96c 100644 |
440 |
--- a/src/main.c |
441 |
+++ b/src/main.c |
442 |
@@ -23,6 +23,7 @@ |
443 |
#include <gio/gio.h> |
444 |
|
445 |
#include "hostnamed.h" |
446 |
+#include "localed.h" |
447 |
#include "shell-utils.h" |
448 |
|
449 |
#include "config.h" |
450 |
@@ -68,10 +69,12 @@ main (gint argc, gchar *argv[]) |
451 |
|
452 |
shell_utils_init (); |
453 |
hostnamed_init (read_only); |
454 |
+ localed_init (read_only); |
455 |
loop = g_main_loop_new (NULL, FALSE); |
456 |
g_main_loop_run (loop); |
457 |
|
458 |
g_main_loop_unref (loop); |
459 |
+ localed_destroy (); |
460 |
hostnamed_destroy (); |
461 |
shell_utils_destroy (); |
462 |
return 0; |
463 |
|
464 |
diff --git a/src/shell-utils.c b/src/shell-utils.c |
465 |
index 30026a9..db67303 100644 |
466 |
--- a/src/shell-utils.c |
467 |
+++ b/src/shell-utils.c |
468 |
@@ -45,6 +45,7 @@ struct ShellEntry { |
469 |
enum ShellEntryType type; |
470 |
gchar *string; |
471 |
gchar *variable; /* only relevant for assignments */ |
472 |
+ gchar *unquoted_value; /* only relevant for assignments */ |
473 |
}; |
474 |
|
475 |
gchar * |
476 |
@@ -104,10 +105,9 @@ shell_entry_free (struct ShellEntry *entry) |
477 |
if (entry == NULL) |
478 |
return; |
479 |
|
480 |
- if (entry->string != NULL) |
481 |
- g_free (entry->string); |
482 |
- if (entry->variable != NULL) |
483 |
- g_free (entry->variable); |
484 |
+ g_free (entry->string); |
485 |
+ g_free (entry->variable); |
486 |
+ g_free (entry->unquoted_value); |
487 |
g_free (entry); |
488 |
} |
489 |
|
490 |
@@ -132,7 +132,7 @@ shell_utils_trivial_new (GFile *file, |
491 |
{ |
492 |
gchar *filebuf = NULL; |
493 |
ShellUtilsTrivial *ret = NULL; |
494 |
- GError *local_err; |
495 |
+ GError *local_err = NULL; |
496 |
gchar *s; |
497 |
|
498 |
if (file == NULL) |
499 |
@@ -214,6 +214,7 @@ shell_utils_trivial_new (GFile *file, |
500 |
|
501 |
matched = g_regex_match (var_equals_regex, s, 0, &match_info); |
502 |
if (matched) { |
503 |
+ gchar *raw_value = NULL, *temp1 = NULL, *temp2 = NULL; |
504 |
/* If we expect a separator and get an assignment instead, fail */ |
505 |
if (want_separator) |
506 |
goto no_match; |
507 |
@@ -231,7 +232,6 @@ shell_utils_trivial_new (GFile *file, |
508 |
while (*s != 0) { |
509 |
g_debug ("Scanning string for values: ``%s''", s); |
510 |
gboolean matched2 = FALSE; |
511 |
- gchar *temp1 = NULL, *temp2 = NULL; |
512 |
|
513 |
matched2 = g_regex_match (single_quoted_regex, s, 0, &match_info); |
514 |
if (matched2) |
515 |
@@ -256,18 +256,36 @@ shell_utils_trivial_new (GFile *file, |
516 |
|
517 |
break; |
518 |
append_value: |
519 |
+ |
520 |
+ if (raw_value == NULL) { |
521 |
+ raw_value = g_match_info_fetch (match_info, 0); |
522 |
+ s += strlen (raw_value); |
523 |
+ g_debug ("Scanned value: ``%s''", raw_value); |
524 |
+ } else { |
525 |
+ temp1 = raw_value; |
526 |
+ temp2 = g_match_info_fetch (match_info, 0); |
527 |
+ raw_value = g_strconcat (temp1, temp2, NULL); |
528 |
+ s += strlen (temp2); |
529 |
+ g_debug ("Scanned value: ``%s''", temp2); |
530 |
+ g_free (temp1); |
531 |
+ g_free (temp2); |
532 |
+ } |
533 |
+ g_match_info_free (match_info); |
534 |
+ match_info = NULL; |
535 |
+ } |
536 |
+ |
537 |
+ if (raw_value != NULL) { |
538 |
+ entry->unquoted_value = g_shell_unquote (raw_value, &local_err); |
539 |
+ g_debug ("Unquoted value: ``%s''", entry->unquoted_value); |
540 |
temp1 = entry->string; |
541 |
- temp2 = g_match_info_fetch (match_info, 0); |
542 |
+ temp2 = raw_value; |
543 |
entry->string = g_strconcat (temp1, temp2, NULL); |
544 |
- s += strlen (temp2); |
545 |
- g_debug ("Scanned value: ``%s''", temp2); |
546 |
g_free (temp1); |
547 |
g_free (temp2); |
548 |
- g_match_info_free (match_info); |
549 |
- match_info = NULL; |
550 |
+ ret->entry_list = g_list_prepend (ret->entry_list, entry); |
551 |
+ if (local_err != NULL) |
552 |
+ goto no_match; |
553 |
} |
554 |
- |
555 |
- ret->entry_list = g_list_prepend (ret->entry_list, entry); |
556 |
continue; |
557 |
} |
558 |
|
559 |
@@ -275,9 +293,12 @@ no_match: |
560 |
/* Nothing matches, parsing has failed! */ |
561 |
g_match_info_free (match_info); |
562 |
match_info = NULL; |
563 |
- g_propagate_error (error, |
564 |
- g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED, |
565 |
- "Unable to parse '%s'", ret->filename)); |
566 |
+ if (local_err != NULL) |
567 |
+ g_propagate_prefixed_error (error, local_err, "Unable to parse '%s':", ret->filename); |
568 |
+ else |
569 |
+ g_propagate_error (error, |
570 |
+ g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED, |
571 |
+ "Unable to parse '%s'", ret->filename)); |
572 |
shell_utils_trivial_free (ret); |
573 |
return NULL; |
574 |
} |
575 |
@@ -420,6 +441,36 @@ shell_utils_trivial_set_and_save (GFile *file, |
576 |
return ret; |
577 |
} |
578 |
|
579 |
+gchar ** |
580 |
+shell_utils_trivial_source_var_list (GFile *file, |
581 |
+ const gchar * const *var_names, |
582 |
+ GError **error) |
583 |
+{ |
584 |
+ ShellUtilsTrivial *trivial; |
585 |
+ gchar **ret = NULL, **value; |
586 |
+ const gchar* const* var_name; |
587 |
+ |
588 |
+ if (var_names == NULL) |
589 |
+ return NULL; |
590 |
+ |
591 |
+ if ((trivial = shell_utils_trivial_new (file, error)) == NULL) |
592 |
+ return NULL; |
593 |
+ |
594 |
+ ret = g_new0 (gchar *, g_strv_length ((gchar **)var_names) + 1); |
595 |
+ for (var_name = var_names, value = ret; *var_name != NULL; var_name++, value++) { |
596 |
+ GList *curr; |
597 |
+ for (curr = trivial->entry_list; curr != NULL; curr = curr->next) { |
598 |
+ struct ShellEntry *entry; |
599 |
+ |
600 |
+ entry = (struct ShellEntry *)(curr->data); |
601 |
+ if (entry->type == SHELL_ENTRY_TYPE_ASSIGNMENT && g_strcmp0 (*var_name, entry->variable) == 0) |
602 |
+ *value = g_strdup (entry->unquoted_value); |
603 |
+ } |
604 |
+ } |
605 |
+ shell_utils_trivial_free (trivial); |
606 |
+ return ret; |
607 |
+} |
608 |
+ |
609 |
void |
610 |
shell_utils_destroy (void) |
611 |
{ |
612 |
|
613 |
diff --git a/src/shell-utils.h b/src/shell-utils.h |
614 |
index 5e1863d..9ca40e9 100644 |
615 |
--- a/src/shell-utils.h |
616 |
+++ b/src/shell-utils.h |
617 |
@@ -66,4 +66,9 @@ shell_utils_trivial_set_and_save (GFile *file, |
618 |
const gchar *first_alt_var_name, |
619 |
const gchar *first_value, |
620 |
...); |
621 |
+ |
622 |
+gchar ** |
623 |
+shell_utils_trivial_source_var_list (GFile *file, |
624 |
+ const gchar * const *var_names, |
625 |
+ GError **error); |
626 |
#endif |