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_strcmp0 (keys[i], name) == 0)
178 list_keys (GSettings *settings,
184 keys = g_settings_list_keys (settings);
185 for (i = 0; keys[i]; i++)
186 if (prefix == NULL || g_str_has_prefix (keys[i], prefix))
187 g_print ("%s \n", keys[i]);
192 list_options (GOptionContext *context,
195 /* FIXME extract options from context */
196 const gchar *options[] = { "--help", "--path", NULL };
198 for (i = 0; options[i]; i++)
199 if (g_str_has_prefix (options[i], prefix))
200 g_print ("%s \n", options[i]);
204 handle_get (gint *argc,
206 gboolean request_completion,
207 gchar *completion_cur,
208 gchar *completion_prev)
215 GOptionContext *context;
216 GOptionEntry entries[] = {
217 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
223 modify_argv0_for_command (argc, argv, "get");
225 context = g_option_context_new (_("SCHEMA KEY"));
226 g_option_context_set_help_enabled (context, FALSE);
227 g_option_context_set_summary (context, _("Get the value of KEY"));
228 g_option_context_set_description (context,
230 " SCHEMA The id of the schema\n"
231 " KEY The name of the key\n"));
232 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
240 if (!g_option_context_parse (context, argc, argv, NULL))
242 if (!request_completion)
245 s = g_option_context_get_help (context, FALSE, NULL);
246 g_printerr ("%s", s);
258 if (request_completion && completion_cur[0] == '-')
260 list_options (context, completion_cur);
265 if (request_completion && !schema_exists (schema))
267 list_schemas (schema);
273 settings = g_settings_new_with_path (schema, path);
275 settings = g_settings_new (schema);
277 if (request_completion && !key_exists (settings, key))
279 list_keys (settings, key);
284 if (!request_completion)
286 v = g_settings_get_value (settings, key);
287 g_print ("%s\n", g_variant_print (v, FALSE));
294 g_object_unref (settings);
296 g_option_context_free (context);
302 handle_set (gint *argc,
304 gboolean request_completion,
305 gchar *completion_cur,
306 gchar *completion_prev)
313 GVariant *v, *default_v;
314 const GVariantType *type;
315 GOptionContext *context;
316 GOptionEntry entries[] = {
317 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
323 modify_argv0_for_command (argc, argv, "set");
325 context = g_option_context_new (_("SCHEMA KEY VALUE"));
326 g_option_context_set_help_enabled (context, FALSE);
327 g_option_context_set_summary (context, _("Set the value of KEY"));
328 g_option_context_set_description (context,
330 " SCHEMA The id of the schema\n"
331 " KEY The name of the key\n"
332 " VALUE The value to set key to, as a serialized GVariant\n"));
333 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
341 if (!g_option_context_parse (context, argc, argv, NULL))
343 if (!request_completion)
346 s = g_option_context_get_help (context, FALSE, NULL);
347 g_printerr ("%s", s);
360 if (request_completion && completion_cur[0] == '-')
362 list_options (context, completion_cur);
367 if (request_completion && !schema_exists (schema))
369 list_schemas (schema);
375 settings = g_settings_new_with_path (schema, path);
377 settings = g_settings_new (schema);
379 if (request_completion && !key_exists (settings, key))
381 list_keys (settings, key);
386 if (!request_completion)
388 default_v = g_settings_get_value (settings, key);
389 type = g_variant_get_type (default_v);
392 v = g_variant_parse (type, value, NULL, NULL, &error);
393 g_variant_unref (default_v);
396 g_printerr ("%s\n", error->message);
400 if (!g_settings_set_value (settings, key, v))
402 g_printerr (_("Key %s is not writable\n"), key);
412 g_object_unref (settings);
414 g_option_context_free (context);
420 handle_writable (gint *argc,
422 gboolean request_completion,
423 gchar *completion_cur,
424 gchar *completion_prev)
430 GOptionContext *context;
431 GOptionEntry entries[] = {
432 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
438 modify_argv0_for_command (argc, argv, "writable");
440 context = g_option_context_new (_("SCHEMA KEY"));
441 g_option_context_set_help_enabled (context, FALSE);
442 g_option_context_set_summary (context, _("Find out whether KEY is writable"));
443 g_option_context_set_description (context,
445 " SCHEMA The id of the schema\n"
446 " KEY The name of the key\n"));
447 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
455 if (!g_option_context_parse (context, argc, argv, NULL))
457 if (!request_completion)
460 s = g_option_context_get_help (context, FALSE, NULL);
461 g_printerr ("%s", s);
472 if (request_completion && completion_cur[0] == '-')
474 list_options (context, completion_cur);
479 if (request_completion && !schema_exists (schema))
481 list_schemas (schema);
487 settings = g_settings_new_with_path (schema, path);
489 settings = g_settings_new (schema);
491 if (request_completion && !key_exists (settings, key))
493 list_keys (settings, key);
498 if (!request_completion)
500 if (g_settings_is_writable (settings, key))
509 g_object_unref (settings);
511 g_option_context_free (context);
517 key_changed (GSettings *settings,
523 v = g_settings_get_value (settings, key);
524 value = g_variant_print (v, FALSE);
525 g_print ("%s\n", value);
531 handle_monitor (gint *argc,
533 gboolean request_completion,
534 gchar *completion_cur,
535 gchar *completion_prev)
541 gchar *detailed_signal;
543 GOptionContext *context;
544 GOptionEntry entries[] = {
545 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
551 modify_argv0_for_command (argc, argv, "monitor");
553 context = g_option_context_new (_("SCHEMA KEY"));
554 g_option_context_set_help_enabled (context, FALSE);
555 g_option_context_set_summary (context,
556 _("Monitor KEY for changes and print the changed values.\n"
557 "Monitoring will continue until the process is terminated."));
559 g_option_context_set_description (context,
561 " SCHEMA The id of the schema\n"
562 " KEY The name of the key\n"));
563 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
571 if (!g_option_context_parse (context, argc, argv, NULL))
573 if (!request_completion)
576 s = g_option_context_get_help (context, FALSE, NULL);
577 g_printerr ("%s", s);
588 if (request_completion && completion_cur[0] == '-')
590 list_options (context, completion_cur);
595 if (request_completion && !schema_exists (schema))
597 list_schemas (schema);
603 settings = g_settings_new_with_path (schema, path);
605 settings = g_settings_new (schema);
607 if (request_completion && !key_exists (settings, key))
609 list_keys (settings, key);
614 if (!request_completion)
616 detailed_signal = g_strdup_printf ("changed::%s", key);
617 g_signal_connect (settings, detailed_signal,
618 G_CALLBACK (key_changed), NULL);
620 loop = g_main_loop_new (NULL, FALSE);
621 g_main_loop_run (loop);
622 g_main_loop_unref (loop);
628 g_object_unref (settings);
630 g_option_context_free (context);
635 main (int argc, char *argv[])
639 gboolean request_completion;
640 gchar *completion_cur;
641 gchar *completion_prev;
643 setlocale (LC_ALL, "");
648 completion_cur = NULL;
649 completion_prev = NULL;
650 request_completion = FALSE;
654 ret = usage (&argc, &argv, FALSE);
661 if (g_strcmp0 (command, "help") == 0)
663 if (!request_completion)
664 ret = usage (&argc, &argv, TRUE);
666 else if (g_strcmp0 (command, "get") == 0)
667 ret = handle_get (&argc, &argv, request_completion, completion_cur, completion_prev);
668 else if (g_strcmp0 (command, "set") == 0)
669 ret = handle_set (&argc, &argv, request_completion, completion_cur, completion_prev);
670 else if (g_strcmp0 (command, "monitor") == 0)
671 ret = handle_monitor (&argc, &argv, request_completion, completion_cur, completion_prev);
672 else if (g_strcmp0 (command, "writable") == 0)
673 ret = handle_writable (&argc, &argv, request_completion, completion_cur, completion_prev);
674 else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
676 gchar *completion_line;
677 gint completion_point;
679 gchar **completion_argv;
680 gint completion_argc;
683 request_completion = TRUE;
685 completion_line = argv[2];
686 completion_point = strtol (argv[3], &endp, 10);
687 if (endp == argv[3] || *endp != '\0')
690 if (!g_shell_parse_argv (completion_line,
695 /* can't parse partical cmdline, don't attempt completion */
699 completion_prev = NULL;
700 completion_cur = pick_word_at (completion_line, completion_point, &cur_begin);
704 for (prev_end = cur_begin - 1; prev_end >= 0; prev_end--)
706 if (!g_ascii_isspace (completion_line[prev_end]))
708 completion_prev = pick_word_at (completion_line, prev_end, NULL);
714 argc = completion_argc;
715 argv = completion_argv;
722 if (request_completion)
724 g_print ("help \nget \nmonitor \nwritable \nset \n");
729 g_printerr (_("Unknown command '%s'\n"), argv[1]);
730 ret = usage (&argc, &argv, FALSE);
735 g_free (completion_cur);
736 g_free (completion_prev);