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 " reset Reset the value of a key\n"
84 " monitor Monitor a key for changes\n"
85 " writable Check if a key is writable\n"
87 "Use '%s COMMAND --help' to get help for individual commands.\n"),
89 g_option_context_set_description (context, s);
91 s = g_option_context_get_help (context, FALSE, NULL);
97 g_option_context_free (context);
99 return use_stdout ? 0 : 1;
103 remove_arg (gint num, gint *argc, gchar **argv[])
107 g_assert (num <= (*argc));
109 for (n = num; (*argv)[n] != NULL; n++)
110 (*argv)[n] = (*argv)[n+1];
112 (*argc) = (*argc) - 1;
117 modify_argv0_for_command (gint *argc,
119 const gchar *command)
123 g_assert (g_strcmp0 ((*argv)[1], command) == 0);
124 remove_arg (1, argc, argv);
126 s = g_strdup_printf ("%s %s", (*argv)[0], command);
131 schema_exists (const gchar *name)
133 const gchar * const *schemas;
136 schemas = g_settings_list_schemas ();
137 for (i = 0; schemas[i]; i++)
138 if (g_strcmp0 (name, schemas[i]) == 0)
145 list_schemas (const gchar *prefix)
147 const gchar * const *schemas;
150 schemas = g_settings_list_schemas ();
151 for (i = 0; schemas[i]; i++)
152 if (prefix == NULL || g_str_has_prefix (schemas[i], prefix))
153 g_print ("%s \n", schemas[i]);
157 key_exists (GSettings *settings,
166 keys = g_settings_list_items (settings);
167 for (i = 0; keys[i]; i++)
168 if (!g_str_has_suffix (keys[i], "/") &&
169 g_strcmp0 (keys[i], name) == 0)
180 list_keys (GSettings *settings,
186 keys = g_settings_list_items (settings);
187 for (i = 0; keys[i]; i++)
189 if (!g_str_has_suffix (keys[i], "/") &&
190 (prefix == NULL || g_str_has_prefix (keys[i], prefix)))
191 g_print ("%s \n", keys[i]);
197 list_options (GOptionContext *context,
200 /* FIXME extract options from context */
201 const gchar *options[] = { "--help", "--path", NULL };
203 for (i = 0; options[i]; i++)
204 if (g_str_has_prefix (options[i], prefix))
205 g_print ("%s \n", options[i]);
209 handle_get (gint *argc,
211 gboolean request_completion,
212 gchar *completion_cur,
213 gchar *completion_prev)
220 GOptionContext *context;
221 GOptionEntry entries[] = {
222 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
228 modify_argv0_for_command (argc, argv, "get");
230 context = g_option_context_new (_("SCHEMA KEY"));
231 g_option_context_set_help_enabled (context, FALSE);
232 g_option_context_set_summary (context, _("Get the value of KEY"));
233 g_option_context_set_description (context,
235 " SCHEMA The id of the schema\n"
236 " KEY The name of the key\n"));
237 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
245 if (!g_option_context_parse (context, argc, argv, NULL))
247 if (!request_completion)
250 s = g_option_context_get_help (context, FALSE, NULL);
251 g_printerr ("%s", s);
263 if (request_completion && completion_cur[0] == '-')
265 list_options (context, completion_cur);
270 if (request_completion && !schema_exists (schema))
272 list_schemas (schema);
278 settings = g_settings_new_with_path (schema, path);
280 settings = g_settings_new (schema);
282 if (request_completion && !key_exists (settings, key))
284 list_keys (settings, key);
289 if (!request_completion)
291 v = g_settings_get_value (settings, key);
292 g_print ("%s\n", g_variant_print (v, FALSE));
299 g_object_unref (settings);
301 g_option_context_free (context);
307 handle_set (gint *argc,
309 gboolean request_completion,
310 gchar *completion_cur,
311 gchar *completion_prev)
318 GVariant *v, *default_v;
319 const GVariantType *type;
320 GOptionContext *context;
321 GOptionEntry entries[] = {
322 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
328 modify_argv0_for_command (argc, argv, "set");
330 context = g_option_context_new (_("SCHEMA KEY VALUE"));
331 g_option_context_set_help_enabled (context, FALSE);
332 g_option_context_set_summary (context, _("Set the value of KEY"));
333 g_option_context_set_description (context,
335 " SCHEMA The id of the schema\n"
336 " KEY The name of the key\n"
337 " VALUE The value to set key to, as a serialized GVariant\n"));
338 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
346 if (!g_option_context_parse (context, argc, argv, NULL))
348 if (!request_completion)
351 s = g_option_context_get_help (context, FALSE, NULL);
352 g_printerr ("%s", s);
365 if (request_completion && completion_cur[0] == '-')
367 list_options (context, completion_cur);
372 if (request_completion && !schema_exists (schema))
374 list_schemas (schema);
380 settings = g_settings_new_with_path (schema, path);
382 settings = g_settings_new (schema);
384 if (request_completion && !key_exists (settings, key))
386 list_keys (settings, key);
391 if (!request_completion)
393 default_v = g_settings_get_value (settings, key);
394 type = g_variant_get_type (default_v);
397 v = g_variant_parse (type, value, NULL, NULL, &error);
398 g_variant_unref (default_v);
401 g_printerr ("%s\n", error->message);
405 if (!g_settings_set_value (settings, key, v))
407 g_printerr (_("Key %s is not writable\n"), key);
417 g_object_unref (settings);
419 g_option_context_free (context);
426 handle_reset (gint *argc,
428 gboolean request_completion,
429 gchar *completion_cur,
430 gchar *completion_prev)
436 GOptionContext *context;
437 GOptionEntry entries[] = {
438 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
444 modify_argv0_for_command (argc, argv, "reset");
446 context = g_option_context_new (_("SCHEMA KEY VALUE"));
447 g_option_context_set_help_enabled (context, FALSE);
448 g_option_context_set_summary (context, _("Sets KEY to its default value"));
449 g_option_context_set_description (context,
451 " SCHEMA The id of the schema\n"
452 " KEY The name of the key\n"));
453 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
461 if (!g_option_context_parse (context, argc, argv, NULL))
463 if (!request_completion)
466 s = g_option_context_get_help (context, FALSE, NULL);
467 g_printerr ("%s", s);
478 if (request_completion && completion_cur[0] == '-')
480 list_options (context, completion_cur);
485 if (request_completion && !schema_exists (schema))
487 list_schemas (schema);
493 settings = g_settings_new_with_path (schema, path);
495 settings = g_settings_new (schema);
497 if (request_completion && !key_exists (settings, key))
499 list_keys (settings, key);
504 if (!request_completion)
506 g_settings_reset (settings, key);
513 g_object_unref (settings);
515 g_option_context_free (context);
521 handle_writable (gint *argc,
523 gboolean request_completion,
524 gchar *completion_cur,
525 gchar *completion_prev)
531 GOptionContext *context;
532 GOptionEntry entries[] = {
533 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
539 modify_argv0_for_command (argc, argv, "writable");
541 context = g_option_context_new (_("SCHEMA KEY"));
542 g_option_context_set_help_enabled (context, FALSE);
543 g_option_context_set_summary (context, _("Find out whether KEY is writable"));
544 g_option_context_set_description (context,
546 " SCHEMA The id of the schema\n"
547 " KEY The name of the key\n"));
548 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
556 if (!g_option_context_parse (context, argc, argv, NULL))
558 if (!request_completion)
561 s = g_option_context_get_help (context, FALSE, NULL);
562 g_printerr ("%s", s);
573 if (request_completion && completion_cur[0] == '-')
575 list_options (context, completion_cur);
580 if (request_completion && !schema_exists (schema))
582 list_schemas (schema);
588 settings = g_settings_new_with_path (schema, path);
590 settings = g_settings_new (schema);
592 if (request_completion && !key_exists (settings, key))
594 list_keys (settings, key);
599 if (!request_completion)
601 if (g_settings_is_writable (settings, key))
610 g_object_unref (settings);
612 g_option_context_free (context);
618 key_changed (GSettings *settings,
624 v = g_settings_get_value (settings, key);
625 value = g_variant_print (v, FALSE);
626 g_print ("%s\n", value);
632 handle_monitor (gint *argc,
634 gboolean request_completion,
635 gchar *completion_cur,
636 gchar *completion_prev)
642 gchar *detailed_signal;
644 GOptionContext *context;
645 GOptionEntry entries[] = {
646 { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
652 modify_argv0_for_command (argc, argv, "monitor");
654 context = g_option_context_new (_("SCHEMA KEY"));
655 g_option_context_set_help_enabled (context, FALSE);
656 g_option_context_set_summary (context,
657 _("Monitor KEY for changes and print the changed values.\n"
658 "Monitoring will continue until the process is terminated."));
660 g_option_context_set_description (context,
662 " SCHEMA The id of the schema\n"
663 " KEY The name of the key\n"));
664 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
672 if (!g_option_context_parse (context, argc, argv, NULL))
674 if (!request_completion)
677 s = g_option_context_get_help (context, FALSE, NULL);
678 g_printerr ("%s", s);
689 if (request_completion && completion_cur[0] == '-')
691 list_options (context, completion_cur);
696 if (request_completion && !schema_exists (schema))
698 list_schemas (schema);
704 settings = g_settings_new_with_path (schema, path);
706 settings = g_settings_new (schema);
708 if (request_completion && !key_exists (settings, key))
710 list_keys (settings, key);
715 if (!request_completion)
717 detailed_signal = g_strdup_printf ("changed::%s", key);
718 g_signal_connect (settings, detailed_signal,
719 G_CALLBACK (key_changed), NULL);
721 loop = g_main_loop_new (NULL, FALSE);
722 g_main_loop_run (loop);
723 g_main_loop_unref (loop);
729 g_object_unref (settings);
731 g_option_context_free (context);
737 main (int argc, char *argv[])
741 gboolean request_completion;
742 gchar *completion_cur;
743 gchar *completion_prev;
745 setlocale (LC_ALL, "");
750 completion_cur = NULL;
751 completion_prev = NULL;
752 request_completion = FALSE;
756 ret = usage (&argc, &argv, FALSE);
763 if (g_strcmp0 (command, "help") == 0)
765 if (!request_completion)
766 ret = usage (&argc, &argv, TRUE);
768 else if (g_strcmp0 (command, "get") == 0)
769 ret = handle_get (&argc, &argv, request_completion, completion_cur, completion_prev);
770 else if (g_strcmp0 (command, "set") == 0)
771 ret = handle_set (&argc, &argv, request_completion, completion_cur, completion_prev);
772 else if (g_strcmp0 (command, "reset") == 0)
773 ret = handle_reset (&argc, &argv, request_completion, completion_cur, completion_prev);
774 else if (g_strcmp0 (command, "monitor") == 0)
775 ret = handle_monitor (&argc, &argv, request_completion, completion_cur, completion_prev);
776 else if (g_strcmp0 (command, "writable") == 0)
777 ret = handle_writable (&argc, &argv, request_completion, completion_cur, completion_prev);
778 else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
780 gchar *completion_line;
781 gint completion_point;
783 gchar **completion_argv;
784 gint completion_argc;
787 request_completion = TRUE;
789 completion_line = argv[2];
790 completion_point = strtol (argv[3], &endp, 10);
791 if (endp == argv[3] || *endp != '\0')
794 if (!g_shell_parse_argv (completion_line,
799 /* can't parse partical cmdline, don't attempt completion */
803 completion_prev = NULL;
804 completion_cur = pick_word_at (completion_line, completion_point, &cur_begin);
808 for (prev_end = cur_begin - 1; prev_end >= 0; prev_end--)
810 if (!g_ascii_isspace (completion_line[prev_end]))
812 completion_prev = pick_word_at (completion_line, prev_end, NULL);
818 argc = completion_argc;
819 argv = completion_argv;
826 if (request_completion)
828 g_print ("help \nget \nmonitor \nwritable \nset \nreset \n");
833 g_printerr (_("Unknown command '%s'\n"), argv[1]);
834 ret = usage (&argc, &argv, FALSE);
839 g_free (completion_cur);
840 g_free (completion_prev);