1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 2010 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Author: Matthias Clasen
31 pick_word_at (const gchar *s,
33 gint *out_word_begins_at)
40 if (out_word_begins_at != NULL)
41 *out_word_begins_at = -1;
45 if (g_ascii_isspace (s[cursor]) &&
46 ((cursor > 0 && g_ascii_isspace (s[cursor-1])) || cursor == 0))
48 if (out_word_begins_at != NULL)
49 *out_word_begins_at = cursor;
52 while (!g_ascii_isspace (s[cursor - 1]) && cursor > 0)
57 while (!g_ascii_isspace (s[end]) && s[end] != '\0')
60 if (out_word_begins_at != NULL)
61 *out_word_begins_at = begin;
63 return g_strndup (s + begin, end - begin);
71 GOptionContext *context;
74 g_set_prgname (g_path_get_basename ((*argv)[0]));
76 context = g_option_context_new (_("COMMAND"));
77 g_option_context_set_help_enabled (context, FALSE);
80 " help Show this information\n"
81 " get Get the value of a key\n"
82 " set Set the value of a key\n"
83 " monitor Monitor a key for changes\n"
84 " writable Check if a key is writable\n"
86 "Use '%s COMMAND --help' to get help for individual commands.\n"),
88 g_option_context_set_description (context, s);
90 s = g_option_context_get_help (context, FALSE, NULL);
96 g_option_context_free (context);
98 return use_stdout ? 0 : 1;
102 remove_arg (gint num, gint *argc, gchar **argv[])
106 g_assert (num <= (*argc));
108 for (n = num; (*argv)[n] != NULL; n++)
109 (*argv)[n] = (*argv)[n+1];
111 (*argc) = (*argc) - 1;
116 modify_argv0_for_command (gint *argc,
118 const gchar *command)
122 g_assert (g_strcmp0 ((*argv)[1], command) == 0);
123 remove_arg (1, argc, argv);
125 s = g_strdup_printf ("%s %s", (*argv)[0], command);
130 schema_exists (const gchar *name)
132 const gchar * const *schemas;
135 schemas = g_settings_list_schemas ();
136 for (i = 0; schemas[i]; i++)
137 if (g_strcmp0 (name, schemas[i]) == 0)
144 list_schemas (const gchar *prefix)
146 const gchar * const *schemas;
149 schemas = g_settings_list_schemas ();
150 for (i = 0; schemas[i]; i++)
151 if (prefix == NULL || g_str_has_prefix (schemas[i], prefix))
152 g_print ("%s \n", schemas[i]);
156 key_exists (GSettings *settings,
165 keys = g_settings_list_keys (settings);
166 for (i = 0; keys[i]; i++)
167 if (!g_str_has_suffix (keys[i], "/") &&
168 g_strcmp0 (keys[i], name) == 0)
179 list_keys (GSettings *settings,
185 keys = g_settings_list_keys (settings);
186 for (i = 0; keys[i]; i++)
188 if (!g_str_has_suffix (keys[i], "/") &&
189 (prefix == NULL || g_str_has_prefix (keys[i], prefix)))
190 g_print ("%s \n", keys[i]);
196 list_options (GOptionContext *context,
199 /* FIXME extract options from context */
200 const gchar *options[] = { "--help", "--path", NULL };
202 for (i = 0; options[i]; i++)
203 if (g_str_has_prefix (options[i], prefix))
204 g_print ("%s \n", options[i]);
208 handle_get (gint *argc,
210 gboolean request_completion,
211 gchar *completion_cur,
212 gchar *completion_prev)
219 GOptionContext *context;
220 GOptionEntry entries[] = {
221 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
227 modify_argv0_for_command (argc, argv, "get");
229 context = g_option_context_new (_("SCHEMA KEY"));
230 g_option_context_set_help_enabled (context, FALSE);
231 g_option_context_set_summary (context, _("Get the value of KEY"));
232 g_option_context_set_description (context,
234 " SCHEMA The id of the schema\n"
235 " KEY The name of the key\n"));
236 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
244 if (!g_option_context_parse (context, argc, argv, NULL))
246 if (!request_completion)
249 s = g_option_context_get_help (context, FALSE, NULL);
250 g_printerr ("%s", s);
262 if (request_completion && completion_cur[0] == '-')
264 list_options (context, completion_cur);
269 if (request_completion && !schema_exists (schema))
271 list_schemas (schema);
277 settings = g_settings_new_with_path (schema, path);
279 settings = g_settings_new (schema);
281 if (request_completion && !key_exists (settings, key))
283 list_keys (settings, key);
288 if (!request_completion)
290 v = g_settings_get_value (settings, key);
291 g_print ("%s\n", g_variant_print (v, FALSE));
298 g_object_unref (settings);
300 g_option_context_free (context);
306 handle_set (gint *argc,
308 gboolean request_completion,
309 gchar *completion_cur,
310 gchar *completion_prev)
317 GVariant *v, *default_v;
318 const GVariantType *type;
319 GOptionContext *context;
320 GOptionEntry entries[] = {
321 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
327 modify_argv0_for_command (argc, argv, "set");
329 context = g_option_context_new (_("SCHEMA KEY VALUE"));
330 g_option_context_set_help_enabled (context, FALSE);
331 g_option_context_set_summary (context, _("Set the value of KEY"));
332 g_option_context_set_description (context,
334 " SCHEMA The id of the schema\n"
335 " KEY The name of the key\n"
336 " VALUE The value to set key to, as a serialized GVariant\n"));
337 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
345 if (!g_option_context_parse (context, argc, argv, NULL))
347 if (!request_completion)
350 s = g_option_context_get_help (context, FALSE, NULL);
351 g_printerr ("%s", s);
364 if (request_completion && completion_cur[0] == '-')
366 list_options (context, completion_cur);
371 if (request_completion && !schema_exists (schema))
373 list_schemas (schema);
379 settings = g_settings_new_with_path (schema, path);
381 settings = g_settings_new (schema);
383 if (request_completion && !key_exists (settings, key))
385 list_keys (settings, key);
390 if (!request_completion)
392 default_v = g_settings_get_value (settings, key);
393 type = g_variant_get_type (default_v);
396 v = g_variant_parse (type, value, NULL, NULL, &error);
397 g_variant_unref (default_v);
400 g_printerr ("%s\n", error->message);
404 if (!g_settings_set_value (settings, key, v))
406 g_printerr (_("Key %s is not writable\n"), key);
416 g_object_unref (settings);
418 g_option_context_free (context);
424 handle_writable (gint *argc,
426 gboolean request_completion,
427 gchar *completion_cur,
428 gchar *completion_prev)
434 GOptionContext *context;
435 GOptionEntry entries[] = {
436 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
442 modify_argv0_for_command (argc, argv, "writable");
444 context = g_option_context_new (_("SCHEMA KEY"));
445 g_option_context_set_help_enabled (context, FALSE);
446 g_option_context_set_summary (context, _("Find out whether KEY is writable"));
447 g_option_context_set_description (context,
449 " SCHEMA The id of the schema\n"
450 " KEY The name of the key\n"));
451 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
459 if (!g_option_context_parse (context, argc, argv, NULL))
461 if (!request_completion)
464 s = g_option_context_get_help (context, FALSE, NULL);
465 g_printerr ("%s", s);
476 if (request_completion && completion_cur[0] == '-')
478 list_options (context, completion_cur);
483 if (request_completion && !schema_exists (schema))
485 list_schemas (schema);
491 settings = g_settings_new_with_path (schema, path);
493 settings = g_settings_new (schema);
495 if (request_completion && !key_exists (settings, key))
497 list_keys (settings, key);
502 if (!request_completion)
504 if (g_settings_is_writable (settings, key))
513 g_object_unref (settings);
515 g_option_context_free (context);
521 key_changed (GSettings *settings,
527 v = g_settings_get_value (settings, key);
528 value = g_variant_print (v, FALSE);
529 g_print ("%s\n", value);
535 handle_monitor (gint *argc,
537 gboolean request_completion,
538 gchar *completion_cur,
539 gchar *completion_prev)
545 gchar *detailed_signal;
547 GOptionContext *context;
548 GOptionEntry entries[] = {
549 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
555 modify_argv0_for_command (argc, argv, "monitor");
557 context = g_option_context_new (_("SCHEMA KEY"));
558 g_option_context_set_help_enabled (context, FALSE);
559 g_option_context_set_summary (context,
560 _("Monitor KEY for changes and print the changed values.\n"
561 "Monitoring will continue until the process is terminated."));
563 g_option_context_set_description (context,
565 " SCHEMA The id of the schema\n"
566 " KEY The name of the key\n"));
567 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
575 if (!g_option_context_parse (context, argc, argv, NULL))
577 if (!request_completion)
580 s = g_option_context_get_help (context, FALSE, NULL);
581 g_printerr ("%s", s);
592 if (request_completion && completion_cur[0] == '-')
594 list_options (context, completion_cur);
599 if (request_completion && !schema_exists (schema))
601 list_schemas (schema);
607 settings = g_settings_new_with_path (schema, path);
609 settings = g_settings_new (schema);
611 if (request_completion && !key_exists (settings, key))
613 list_keys (settings, key);
618 if (!request_completion)
620 detailed_signal = g_strdup_printf ("changed::%s", key);
621 g_signal_connect (settings, detailed_signal,
622 G_CALLBACK (key_changed), NULL);
624 loop = g_main_loop_new (NULL, FALSE);
625 g_main_loop_run (loop);
626 g_main_loop_unref (loop);
632 g_object_unref (settings);
634 g_option_context_free (context);
639 main (int argc, char *argv[])
643 gboolean request_completion;
644 gchar *completion_cur;
645 gchar *completion_prev;
647 setlocale (LC_ALL, "");
652 completion_cur = NULL;
653 completion_prev = NULL;
654 request_completion = FALSE;
658 ret = usage (&argc, &argv, FALSE);
665 if (g_strcmp0 (command, "help") == 0)
667 if (!request_completion)
668 ret = usage (&argc, &argv, TRUE);
670 else if (g_strcmp0 (command, "get") == 0)
671 ret = handle_get (&argc, &argv, request_completion, completion_cur, completion_prev);
672 else if (g_strcmp0 (command, "set") == 0)
673 ret = handle_set (&argc, &argv, request_completion, completion_cur, completion_prev);
674 else if (g_strcmp0 (command, "monitor") == 0)
675 ret = handle_monitor (&argc, &argv, request_completion, completion_cur, completion_prev);
676 else if (g_strcmp0 (command, "writable") == 0)
677 ret = handle_writable (&argc, &argv, request_completion, completion_cur, completion_prev);
678 else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
680 gchar *completion_line;
681 gint completion_point;
683 gchar **completion_argv;
684 gint completion_argc;
687 request_completion = TRUE;
689 completion_line = argv[2];
690 completion_point = strtol (argv[3], &endp, 10);
691 if (endp == argv[3] || *endp != '\0')
694 if (!g_shell_parse_argv (completion_line,
699 /* can't parse partical cmdline, don't attempt completion */
703 completion_prev = NULL;
704 completion_cur = pick_word_at (completion_line, completion_point, &cur_begin);
708 for (prev_end = cur_begin - 1; prev_end >= 0; prev_end--)
710 if (!g_ascii_isspace (completion_line[prev_end]))
712 completion_prev = pick_word_at (completion_line, prev_end, NULL);
718 argc = completion_argc;
719 argv = completion_argv;
726 if (request_completion)
728 g_print ("help \nget \nmonitor \nwritable \nset \n");
733 g_printerr (_("Unknown command '%s'\n"), argv[1]);
734 ret = usage (&argc, &argv, FALSE);
739 g_free (completion_cur);
740 g_free (completion_prev);