1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: David Zeuthen <davidz@redhat.com>
34 /* ---------------------------------------------------------------------------------------------------- */
36 G_GNUC_UNUSED
static void completion_debug (const gchar
*format
, ...);
38 /* Uncomment to get debug traces in /tmp/gdbus-completion-debug.txt (nice
39 * to not have it interfere with stdout/stderr)
42 G_GNUC_UNUSED
static void
43 completion_debug (const gchar
*format
, ...)
47 static FILE *f
= NULL
;
49 va_start (var_args
, format
);
50 s
= g_strdup_vprintf (format
, var_args
);
53 f
= fopen ("/tmp/gdbus-completion-debug.txt", "a+");
55 fprintf (f
, "%s\n", s
);
60 completion_debug (const gchar
*format
, ...)
65 /* ---------------------------------------------------------------------------------------------------- */
69 remove_arg (gint num
, gint
*argc
, gchar
**argv
[])
73 g_assert (num
<= (*argc
));
75 for (n
= num
; (*argv
)[n
] != NULL
; n
++)
76 (*argv
)[n
] = (*argv
)[n
+1];
78 (*argc
) = (*argc
) - 1;
82 usage (gint
*argc
, gchar
**argv
[], gboolean use_stdout
)
88 o
= g_option_context_new (_("COMMAND"));
89 g_option_context_set_help_enabled (o
, FALSE
);
90 /* Ignore parsing result */
91 g_option_context_parse (o
, argc
, argv
, NULL
);
92 program_name
= g_path_get_basename ((*argv
)[0]);
93 s
= g_strdup_printf (_("Commands:\n"
94 " help Shows this information\n"
95 " introspect Introspect a remote object\n"
96 " monitor Monitor a remote object\n"
97 " call Invoke a method on a remote object\n"
98 " emit Emit a signal\n"
100 "Use \"%s COMMAND --help\" to get help on each command.\n"),
102 g_free (program_name
);
103 g_option_context_set_description (o
, s
);
105 s
= g_option_context_get_help (o
, FALSE
, NULL
);
109 g_printerr ("%s", s
);
111 g_option_context_free (o
);
115 modify_argv0_for_command (gint
*argc
, gchar
**argv
[], const gchar
*command
)
121 * 1. get a g_set_prgname() ?; or
122 * 2. save old argv[0] and restore later
125 g_assert (g_strcmp0 ((*argv
)[1], command
) == 0);
126 remove_arg (1, argc
, argv
);
128 program_name
= g_path_get_basename ((*argv
)[0]);
129 s
= g_strdup_printf ("%s %s", (*argv
)[0], command
);
131 g_free (program_name
);
134 /* ---------------------------------------------------------------------------------------------------- */
137 print_methods (GDBusConnection
*c
,
143 const gchar
*xml_data
;
149 result
= g_dbus_connection_call_sync (c
,
152 "org.freedesktop.DBus.Introspectable",
155 G_VARIANT_TYPE ("(s)"),
156 G_DBUS_CALL_FLAGS_NONE
,
162 g_printerr (_("Error: %s\n"), error
->message
);
163 g_error_free (error
);
166 g_variant_get (result
, "(&s)", &xml_data
);
169 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
170 g_variant_unref (result
);
173 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
174 g_error_free (error
);
178 for (n
= 0; node
->interfaces
!= NULL
&& node
->interfaces
[n
] != NULL
; n
++)
180 const GDBusInterfaceInfo
*iface
= node
->interfaces
[n
];
181 for (m
= 0; iface
->methods
!= NULL
&& iface
->methods
[m
] != NULL
; m
++)
183 const GDBusMethodInfo
*method
= iface
->methods
[m
];
184 g_print ("%s.%s \n", iface
->name
, method
->name
);
187 g_dbus_node_info_unref (node
);
194 print_paths (GDBusConnection
*c
,
200 const gchar
*xml_data
;
205 result
= g_dbus_connection_call_sync (c
,
208 "org.freedesktop.DBus.Introspectable",
211 G_VARIANT_TYPE ("(s)"),
212 G_DBUS_CALL_FLAGS_NONE
,
218 g_printerr (_("Error: %s\n"), error
->message
);
219 g_error_free (error
);
222 g_variant_get (result
, "(&s)", &xml_data
);
224 //g_printerr ("xml=`%s'", xml_data);
227 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
228 g_variant_unref (result
);
231 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
232 g_error_free (error
);
236 //g_printerr ("bar `%s'\n", path);
238 if (node
->interfaces
!= NULL
)
239 g_print ("%s \n", path
);
241 for (n
= 0; node
->nodes
!= NULL
&& node
->nodes
[n
] != NULL
; n
++)
245 //g_printerr ("foo `%s'\n", node->nodes[n].path);
247 if (g_strcmp0 (path
, "/") == 0)
248 s
= g_strdup_printf ("/%s", node
->nodes
[n
]->path
);
250 s
= g_strdup_printf ("%s/%s", path
, node
->nodes
[n
]->path
);
252 print_paths (c
, name
, s
);
256 g_dbus_node_info_unref (node
);
263 print_names (GDBusConnection
*c
,
264 gboolean include_unique_names
)
270 GHashTable
*name_set
;
274 name_set
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
277 result
= g_dbus_connection_call_sync (c
,
278 "org.freedesktop.DBus",
279 "/org/freedesktop/DBus",
280 "org.freedesktop.DBus",
283 G_VARIANT_TYPE ("(as)"),
284 G_DBUS_CALL_FLAGS_NONE
,
290 g_printerr (_("Error: %s\n"), error
->message
);
291 g_error_free (error
);
294 g_variant_get (result
, "(as)", &iter
);
295 while (g_variant_iter_loop (iter
, "s", &str
))
296 g_hash_table_insert (name_set
, g_strdup (str
), NULL
);
297 g_variant_iter_free (iter
);
298 g_variant_unref (result
);
301 result
= g_dbus_connection_call_sync (c
,
302 "org.freedesktop.DBus",
303 "/org/freedesktop/DBus",
304 "org.freedesktop.DBus",
305 "ListActivatableNames",
307 G_VARIANT_TYPE ("(as)"),
308 G_DBUS_CALL_FLAGS_NONE
,
314 g_printerr (_("Error: %s\n"), error
->message
);
315 g_error_free (error
);
318 g_variant_get (result
, "(as)", &iter
);
319 while (g_variant_iter_loop (iter
, "s", &str
))
320 g_hash_table_insert (name_set
, g_strdup (str
), NULL
);
321 g_variant_iter_free (iter
);
322 g_variant_unref (result
);
324 keys
= g_hash_table_get_keys (name_set
);
325 keys
= g_list_sort (keys
, (GCompareFunc
) g_strcmp0
);
326 for (l
= keys
; l
!= NULL
; l
= l
->next
)
328 const gchar
*name
= l
->data
;
329 if (!include_unique_names
&& g_str_has_prefix (name
, ":"))
332 g_print ("%s \n", name
);
337 g_hash_table_unref (name_set
);
340 /* ---------------------------------------------------------------------------------------------------- */
342 static gboolean opt_connection_system
= FALSE
;
343 static gboolean opt_connection_session
= FALSE
;
344 static gchar
*opt_connection_address
= NULL
;
346 static const GOptionEntry connection_entries
[] =
348 { "system", 'y', 0, G_OPTION_ARG_NONE
, &opt_connection_system
, N_("Connect to the system bus"), NULL
},
349 { "session", 'e', 0, G_OPTION_ARG_NONE
, &opt_connection_session
, N_("Connect to the session bus"), NULL
},
350 { "address", 'a', 0, G_OPTION_ARG_STRING
, &opt_connection_address
, N_("Connect to given D-Bus address"), NULL
},
354 static GOptionGroup
*
355 connection_get_group (void)
357 static GOptionGroup
*g
;
359 g
= g_option_group_new ("connection",
360 N_("Connection Endpoint Options:"),
361 N_("Options specifying the connection endpoint"),
364 g_option_group_set_translation_domain (g
, GETTEXT_PACKAGE
);
365 g_option_group_add_entries (g
, connection_entries
);
370 static GDBusConnection
*
371 connection_get_dbus_connection (GError
**error
)
377 /* First, ensure we have exactly one connect */
378 if (!opt_connection_system
&& !opt_connection_session
&& opt_connection_address
== NULL
)
383 _("No connection endpoint specified"));
386 else if ((opt_connection_system
&& (opt_connection_session
|| opt_connection_address
!= NULL
)) ||
387 (opt_connection_session
&& (opt_connection_system
|| opt_connection_address
!= NULL
)) ||
388 (opt_connection_address
!= NULL
&& (opt_connection_system
|| opt_connection_session
)))
393 _("Multiple connection endpoints specified"));
397 if (opt_connection_system
)
399 c
= g_bus_get_sync (G_BUS_TYPE_SYSTEM
, NULL
, error
);
401 else if (opt_connection_session
)
403 c
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, error
);
405 else if (opt_connection_address
!= NULL
)
407 c
= g_dbus_connection_new_for_address_sync (opt_connection_address
,
408 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
,
409 NULL
, /* GDBusAuthObserver */
410 NULL
, /* GCancellable */
418 /* ---------------------------------------------------------------------------------------------------- */
421 call_helper_get_method_in_signature (GDBusConnection
*c
,
424 const gchar
*interface_name
,
425 const gchar
*method_name
,
430 GDBusNodeInfo
*node_info
;
431 const gchar
*xml_data
;
432 GDBusInterfaceInfo
*interface_info
;
433 GDBusMethodInfo
*method_info
;
440 result
= g_dbus_connection_call_sync (c
,
443 "org.freedesktop.DBus.Introspectable",
446 G_VARIANT_TYPE ("(s)"),
447 G_DBUS_CALL_FLAGS_NONE
,
454 g_variant_get (result
, "(&s)", &xml_data
);
455 node_info
= g_dbus_node_info_new_for_xml (xml_data
, error
);
456 if (node_info
== NULL
)
459 interface_info
= g_dbus_node_info_lookup_interface (node_info
, interface_name
);
460 if (interface_info
== NULL
)
462 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
463 _("Warning: According to introspection data, interface `%s' does not exist\n"),
468 method_info
= g_dbus_interface_info_lookup_method (interface_info
, method_name
);
469 if (method_info
== NULL
)
471 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
472 _("Warning: According to introspection data, method `%s' does not exist on interface `%s'\n"),
478 ret
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_variant_type_free
);
479 for (n
= 0; method_info
->in_args
!= NULL
&& method_info
->in_args
[n
] != NULL
; n
++)
481 g_ptr_array_add (ret
, g_variant_type_new (method_info
->in_args
[n
]->signature
));
485 if (node_info
!= NULL
)
486 g_dbus_node_info_unref (node_info
);
488 g_variant_unref (result
);
493 /* ---------------------------------------------------------------------------------------------------- */
496 _g_variant_parse_me_harder (GVariantType
*type
,
497 const gchar
*given_str
,
505 str
= g_string_new ("\"");
506 for (n
= 0; given_str
[n
] != '\0'; n
++)
508 if (G_UNLIKELY (given_str
[n
] == '\"'))
509 g_string_append (str
, "\\\"");
511 g_string_append_c (str
, given_str
[n
]);
513 g_string_append_c (str
, '"');
514 s
= g_string_free (str
, FALSE
);
516 value
= g_variant_parse (type
,
526 /* ---------------------------------------------------------------------------------------------------- */
528 static gchar
*opt_emit_dest
= NULL
;
529 static gchar
*opt_emit_object_path
= NULL
;
530 static gchar
*opt_emit_signal
= NULL
;
532 static const GOptionEntry emit_entries
[] =
534 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_emit_dest
, N_("Optional destination for signal (unique name)"), NULL
},
535 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_emit_object_path
, N_("Object path to emit signal on"), NULL
},
536 { "signal", 's', 0, G_OPTION_ARG_STRING
, &opt_emit_signal
, N_("Signal and interface name"), NULL
},
541 handle_emit (gint
*argc
,
543 gboolean request_completion
,
544 const gchar
*completion_cur
,
545 const gchar
*completion_prev
)
552 GVariant
*parameters
;
553 gchar
*interface_name
;
555 GVariantBuilder builder
;
561 interface_name
= NULL
;
564 modify_argv0_for_command (argc
, argv
, "emit");
566 o
= g_option_context_new (NULL
);
567 g_option_context_set_help_enabled (o
, FALSE
);
568 g_option_context_set_summary (o
, _("Emit a signal."));
569 g_option_context_add_main_entries (o
, emit_entries
, GETTEXT_PACKAGE
);
570 g_option_context_add_group (o
, connection_get_group ());
572 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
574 if (!request_completion
)
576 s
= g_option_context_get_help (o
, FALSE
, NULL
);
577 g_printerr ("%s", s
);
584 c
= connection_get_dbus_connection (&error
);
587 if (request_completion
)
589 if (g_strcmp0 (completion_prev
, "--address") == 0)
597 g_print ("--system \n--session \n--address \n");
602 g_printerr (_("Error connecting: %s\n"), error
->message
);
603 g_error_free (error
);
608 /* All done with completion now */
609 if (request_completion
)
612 if (opt_emit_object_path
== NULL
)
614 g_printerr (_("Error: object path not specified.\n"));
617 if (!g_variant_is_object_path (opt_emit_object_path
))
619 g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path
);
623 if (opt_emit_signal
== NULL
)
625 g_printerr (_("Error: signal not specified.\n"));
629 s
= strrchr (opt_emit_signal
, '.');
632 g_printerr (_("Error: signal must be the fully-qualified name.\n"));
635 signal_name
= g_strdup (s
+ 1);
636 interface_name
= g_strndup (opt_emit_signal
, s
- opt_emit_signal
);
638 if (!g_dbus_is_interface_name (interface_name
))
640 g_printerr (_("Error: %s is not a valid interface name\n"), interface_name
);
644 if (!g_dbus_is_member_name (signal_name
))
646 g_printerr (_("Error: %s is not a valid member name\n"), signal_name
);
650 if (opt_emit_dest
!= NULL
&& !g_dbus_is_unique_name (opt_emit_dest
))
652 g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest
);
656 /* Read parameters */
657 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
658 for (n
= 1; n
< (guint
) *argc
; n
++)
663 value
= g_variant_parse (NULL
,
670 g_error_free (error
);
672 value
= _g_variant_parse_me_harder (NULL
, (*argv
)[n
], &error
);
675 g_printerr (_("Error parsing parameter %d: %s\n"),
678 g_error_free (error
);
679 g_variant_builder_clear (&builder
);
683 g_variant_builder_add_value (&builder
, value
);
685 parameters
= g_variant_builder_end (&builder
);
687 if (parameters
!= NULL
)
688 parameters
= g_variant_ref_sink (parameters
);
689 if (!g_dbus_connection_emit_signal (c
,
691 opt_emit_object_path
,
697 g_printerr (_("Error: %s\n"), error
->message
);
698 g_error_free (error
);
702 if (!g_dbus_connection_flush_sync (c
, NULL
, &error
))
704 g_printerr (_("Error flushing connection: %s\n"), error
->message
);
705 g_error_free (error
);
714 if (parameters
!= NULL
)
715 g_variant_unref (parameters
);
716 g_free (interface_name
);
717 g_free (signal_name
);
718 g_option_context_free (o
);
722 /* ---------------------------------------------------------------------------------------------------- */
724 static gchar
*opt_call_dest
= NULL
;
725 static gchar
*opt_call_object_path
= NULL
;
726 static gchar
*opt_call_method
= NULL
;
727 static gint opt_call_timeout
= -1;
729 static const GOptionEntry call_entries
[] =
731 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_call_dest
, N_("Destination name to invoke method on"), NULL
},
732 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_call_object_path
, N_("Object path to invoke method on"), NULL
},
733 { "method", 'm', 0, G_OPTION_ARG_STRING
, &opt_call_method
, N_("Method and interface name"), NULL
},
734 { "timeout", 't', 0, G_OPTION_ARG_INT
, &opt_call_timeout
, N_("Timeout in seconds"), NULL
},
739 handle_call (gint
*argc
,
741 gboolean request_completion
,
742 const gchar
*completion_cur
,
743 const gchar
*completion_prev
)
750 GVariant
*parameters
;
751 gchar
*interface_name
;
754 GPtrArray
*in_signature_types
;
755 gboolean complete_names
;
756 gboolean complete_paths
;
757 gboolean complete_methods
;
758 GVariantBuilder builder
;
764 interface_name
= NULL
;
767 in_signature_types
= NULL
;
769 modify_argv0_for_command (argc
, argv
, "call");
771 o
= g_option_context_new (NULL
);
772 g_option_context_set_help_enabled (o
, FALSE
);
773 g_option_context_set_summary (o
, _("Invoke a method on a remote object."));
774 g_option_context_add_main_entries (o
, call_entries
, GETTEXT_PACKAGE
);
775 g_option_context_add_group (o
, connection_get_group ());
777 complete_names
= FALSE
;
778 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
780 complete_names
= TRUE
;
781 remove_arg ((*argc
) - 1, argc
, argv
);
784 complete_paths
= FALSE
;
785 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
787 complete_paths
= TRUE
;
788 remove_arg ((*argc
) - 1, argc
, argv
);
791 complete_methods
= FALSE
;
792 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--method") == 0)
794 complete_methods
= TRUE
;
795 remove_arg ((*argc
) - 1, argc
, argv
);
798 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
800 if (!request_completion
)
802 s
= g_option_context_get_help (o
, FALSE
, NULL
);
803 g_printerr ("%s", s
);
810 c
= connection_get_dbus_connection (&error
);
813 if (request_completion
)
815 if (g_strcmp0 (completion_prev
, "--address") == 0)
823 g_print ("--system \n--session \n--address \n");
828 g_printerr (_("Error connecting: %s\n"), error
->message
);
829 g_error_free (error
);
834 /* validate and complete destination (bus name) */
835 if (g_dbus_connection_get_unique_name (c
) != NULL
)
837 /* this only makes sense on message bus connections */
840 print_names (c
, FALSE
);
843 if (opt_call_dest
== NULL
)
845 if (request_completion
)
846 g_print ("--dest \n");
848 g_printerr (_("Error: Destination is not specified\n"));
851 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
853 print_names (c
, g_str_has_prefix (opt_call_dest
, ":"));
858 /* validate and complete object path */
861 print_paths (c
, opt_call_dest
, "/");
864 if (opt_call_object_path
== NULL
)
866 if (request_completion
)
867 g_print ("--object-path \n");
869 g_printerr (_("Error: Object path is not specified\n"));
872 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
875 s
= g_strdup (opt_call_object_path
);
876 p
= strrchr (s
, '/');
883 print_paths (c
, opt_call_dest
, s
);
887 if (!request_completion
&& !g_variant_is_object_path (opt_call_object_path
))
889 g_printerr (_("Error: %s is not a valid object path\n"), opt_call_object_path
);
893 /* validate and complete method (interface + method name) */
894 if (complete_methods
)
896 print_methods (c
, opt_call_dest
, opt_call_object_path
);
899 if (opt_call_method
== NULL
)
901 if (request_completion
)
902 g_print ("--method \n");
904 g_printerr (_("Error: Method name is not specified\n"));
907 if (request_completion
&& g_strcmp0 ("--method", completion_prev
) == 0)
909 print_methods (c
, opt_call_dest
, opt_call_object_path
);
912 s
= strrchr (opt_call_method
, '.');
913 if (!request_completion
&& s
== NULL
)
915 g_printerr (_("Error: Method name `%s' is invalid\n"), opt_call_method
);
918 method_name
= g_strdup (s
+ 1);
919 interface_name
= g_strndup (opt_call_method
, s
- opt_call_method
);
921 /* All done with completion now */
922 if (request_completion
)
925 /* Introspect, for easy conversion - it's not fatal if we can't do this */
926 in_signature_types
= call_helper_get_method_in_signature (c
,
928 opt_call_object_path
,
932 if (in_signature_types
== NULL
)
934 //g_printerr ("Error getting introspection data: %s\n", error->message);
935 g_error_free (error
);
939 /* Read parameters */
940 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
941 for (n
= 1; n
< (guint
) *argc
; n
++)
947 if (in_signature_types
!= NULL
)
949 if (n
- 1 >= in_signature_types
->len
)
951 /* Only warn for the first param */
952 if (n
- 1 == in_signature_types
->len
)
954 g_printerr ("Warning: Introspection data indicates %d parameters but more was passed\n",
955 in_signature_types
->len
);
960 type
= in_signature_types
->pdata
[n
- 1];
965 value
= g_variant_parse (type
,
972 g_error_free (error
);
974 value
= _g_variant_parse_me_harder (type
, (*argv
)[n
], &error
);
979 s
= g_variant_type_dup_string (type
);
980 g_printerr (_("Error parsing parameter %d of type `%s': %s\n"),
988 g_printerr (_("Error parsing parameter %d: %s\n"),
992 g_error_free (error
);
993 g_variant_builder_clear (&builder
);
997 g_variant_builder_add_value (&builder
, value
);
999 parameters
= g_variant_builder_end (&builder
);
1001 if (parameters
!= NULL
)
1002 parameters
= g_variant_ref_sink (parameters
);
1003 result
= g_dbus_connection_call_sync (c
,
1005 opt_call_object_path
,
1010 G_DBUS_CALL_FLAGS_NONE
,
1011 opt_call_timeout
> 0 ? opt_call_timeout
* 1000 : opt_call_timeout
,
1016 g_printerr (_("Error: %s\n"), error
->message
);
1017 g_error_free (error
);
1018 if (in_signature_types
!= NULL
)
1021 s
= g_string_new (NULL
);
1022 for (n
= 0; n
< in_signature_types
->len
; n
++)
1024 GVariantType
*type
= in_signature_types
->pdata
[n
];
1025 g_string_append_len (s
,
1026 g_variant_type_peek_string (type
),
1027 g_variant_type_get_string_length (type
));
1029 g_printerr ("(According to introspection data, you need to pass `%s')\n", s
->str
);
1030 g_string_free (s
, TRUE
);
1035 s
= g_variant_print (result
, TRUE
);
1036 g_print ("%s\n", s
);
1042 if (in_signature_types
!= NULL
)
1043 g_ptr_array_unref (in_signature_types
);
1045 g_variant_unref (result
);
1048 if (parameters
!= NULL
)
1049 g_variant_unref (parameters
);
1050 g_free (interface_name
);
1051 g_free (method_name
);
1052 g_option_context_free (o
);
1056 /* ---------------------------------------------------------------------------------------------------- */
1058 static gchar
*opt_introspect_dest
= NULL
;
1059 static gchar
*opt_introspect_object_path
= NULL
;
1060 static gboolean opt_introspect_xml
= FALSE
;
1061 static gboolean opt_introspect_recurse
= FALSE
;
1062 static gboolean opt_introspect_only_properties
= FALSE
;
1065 dump_annotation (const GDBusAnnotationInfo
*o
,
1067 gboolean ignore_indent
)
1070 g_print ("%*s@%s(\"%s\")\n",
1071 ignore_indent
? 0 : indent
, "",
1074 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1075 dump_annotation (o
->annotations
[n
], indent
+ 2, FALSE
);
1079 dump_arg (const GDBusArgInfo
*o
,
1081 const gchar
*direction
,
1082 gboolean ignore_indent
,
1083 gboolean include_newline
)
1087 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1089 dump_annotation (o
->annotations
[n
], indent
, ignore_indent
);
1090 ignore_indent
= FALSE
;
1093 g_print ("%*s%s%s %s%s",
1094 ignore_indent
? 0 : indent
, "",
1098 include_newline
? ",\n" : "");
1102 count_args (GDBusArgInfo
**args
)
1108 while (args
[n
] != NULL
)
1115 dump_method (const GDBusMethodInfo
*o
,
1121 guint total_num_args
;
1123 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1124 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1126 g_print ("%*s%s(", indent
, "", o
->name
);
1127 name_len
= strlen (o
->name
);
1128 total_num_args
= count_args (o
->in_args
) + count_args (o
->out_args
);
1129 for (n
= 0, m
= 0; o
->in_args
!= NULL
&& o
->in_args
[n
] != NULL
; n
++, m
++)
1131 gboolean ignore_indent
= (m
== 0);
1132 gboolean include_newline
= (m
!= total_num_args
- 1);
1134 dump_arg (o
->in_args
[n
],
1135 indent
+ name_len
+ 1,
1140 for (n
= 0; o
->out_args
!= NULL
&& o
->out_args
[n
] != NULL
; n
++, m
++)
1142 gboolean ignore_indent
= (m
== 0);
1143 gboolean include_newline
= (m
!= total_num_args
- 1);
1144 dump_arg (o
->out_args
[n
],
1145 indent
+ name_len
+ 1,
1154 dump_signal (const GDBusSignalInfo
*o
,
1159 guint total_num_args
;
1161 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1162 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1164 g_print ("%*s%s(", indent
, "", o
->name
);
1165 name_len
= strlen (o
->name
);
1166 total_num_args
= count_args (o
->args
);
1167 for (n
= 0; o
->args
!= NULL
&& o
->args
[n
] != NULL
; n
++)
1169 gboolean ignore_indent
= (n
== 0);
1170 gboolean include_newline
= (n
!= total_num_args
- 1);
1171 dump_arg (o
->args
[n
],
1172 indent
+ name_len
+ 1,
1181 dump_property (const GDBusPropertyInfo
*o
,
1185 const gchar
*access
;
1188 if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_READABLE
)
1189 access
= "readonly";
1190 else if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
)
1191 access
= "writeonly";
1192 else if (o
->flags
== (G_DBUS_PROPERTY_INFO_FLAGS_READABLE
| G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
))
1193 access
= "readwrite";
1195 g_assert_not_reached ();
1197 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1198 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1202 gchar
*s
= g_variant_print (value
, FALSE
);
1203 g_print ("%*s%s %s %s = %s;\n", indent
, "", access
, o
->signature
, o
->name
, s
);
1208 g_print ("%*s%s %s %s;\n", indent
, "", access
, o
->signature
, o
->name
);
1213 dump_interface (GDBusConnection
*c
,
1215 const GDBusInterfaceInfo
*o
,
1217 const gchar
*object_path
)
1220 GHashTable
*properties
;
1222 properties
= g_hash_table_new_full (g_str_hash
,
1225 (GDestroyNotify
) g_variant_unref
);
1227 /* Try to get properties */
1228 if (c
!= NULL
&& name
!= NULL
&& object_path
!= NULL
&& o
->properties
!= NULL
)
1231 result
= g_dbus_connection_call_sync (c
,
1234 "org.freedesktop.DBus.Properties",
1236 g_variant_new ("(s)", o
->name
),
1238 G_DBUS_CALL_FLAGS_NONE
,
1244 if (g_variant_is_of_type (result
, G_VARIANT_TYPE ("(a{sv})")))
1248 g_variant_get (result
,
1251 while ((item
= g_variant_iter_next_value (iter
)))
1255 g_variant_get (item
,
1260 g_hash_table_insert (properties
, key
, g_variant_ref (value
));
1263 g_variant_unref (result
);
1268 for (n
= 0; o
->properties
!= NULL
&& o
->properties
[n
] != NULL
; n
++)
1270 result
= g_dbus_connection_call_sync (c
,
1273 "org.freedesktop.DBus.Properties",
1275 g_variant_new ("(ss)", o
->name
, o
->properties
[n
]->name
),
1276 G_VARIANT_TYPE ("(v)"),
1277 G_DBUS_CALL_FLAGS_NONE
,
1283 GVariant
*property_value
;
1284 g_variant_get (result
,
1287 g_hash_table_insert (properties
,
1288 g_strdup (o
->properties
[n
]->name
),
1289 g_variant_ref (property_value
));
1290 g_variant_unref (result
);
1296 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1297 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1299 g_print ("%*sinterface %s {\n", indent
, "", o
->name
);
1300 if (o
->methods
!= NULL
&& !opt_introspect_only_properties
)
1302 g_print ("%*s methods:\n", indent
, "");
1303 for (n
= 0; o
->methods
[n
] != NULL
; n
++)
1304 dump_method (o
->methods
[n
], indent
+ 4);
1306 if (o
->signals
!= NULL
&& !opt_introspect_only_properties
)
1308 g_print ("%*s signals:\n", indent
, "");
1309 for (n
= 0; o
->signals
[n
] != NULL
; n
++)
1310 dump_signal (o
->signals
[n
], indent
+ 4);
1312 if (o
->properties
!= NULL
)
1314 g_print ("%*s properties:\n", indent
, "");
1315 for (n
= 0; o
->properties
[n
] != NULL
; n
++)
1317 dump_property (o
->properties
[n
],
1319 g_hash_table_lookup (properties
, (o
->properties
[n
])->name
));
1325 g_hash_table_unref (properties
);
1329 introspect_do (GDBusConnection
*c
,
1330 const gchar
*object_path
,
1334 dump_node (GDBusConnection
*c
,
1336 const GDBusNodeInfo
*o
,
1338 const gchar
*object_path
,
1342 const gchar
*object_path_to_print
;
1344 object_path_to_print
= object_path
;
1345 if (o
->path
!= NULL
)
1346 object_path_to_print
= o
->path
;
1348 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1349 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1351 g_print ("%*snode %s", indent
, "", object_path_to_print
!= NULL
? object_path_to_print
: "(not set)");
1352 if (o
->interfaces
!= NULL
|| o
->nodes
!= NULL
)
1355 for (n
= 0; o
->interfaces
!= NULL
&& o
->interfaces
[n
] != NULL
; n
++)
1357 if (opt_introspect_only_properties
)
1359 if (o
->interfaces
[n
]->properties
!= NULL
&& o
->interfaces
[n
]->properties
[0] != NULL
)
1360 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1364 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1367 for (n
= 0; o
->nodes
!= NULL
&& o
->nodes
[n
] != NULL
; n
++)
1372 if (g_variant_is_object_path (o
->nodes
[n
]->path
))
1374 child_path
= g_strdup (o
->nodes
[n
]->path
);
1375 /* avoid infinite loops */
1376 if (g_str_has_prefix (child_path
, object_path
))
1378 introspect_do (c
, child_path
, indent
+ 2);
1382 g_print ("Skipping path %s that is not enclosed by parent %s\n",
1383 child_path
, object_path
);
1388 if (g_strcmp0 (object_path
, "/") == 0)
1389 child_path
= g_strdup_printf ("/%s", o
->nodes
[n
]->path
);
1391 child_path
= g_strdup_printf ("%s/%s", object_path
, o
->nodes
[n
]->path
);
1392 introspect_do (c
, child_path
, indent
+ 2);
1394 g_free (child_path
);
1398 dump_node (NULL
, NULL
, o
->nodes
[n
], indent
+ 2, NULL
, recurse
);
1410 static const GOptionEntry introspect_entries
[] =
1412 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_introspect_dest
, N_("Destination name to introspect"), NULL
},
1413 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_introspect_object_path
, N_("Object path to introspect"), NULL
},
1414 { "xml", 'x', 0, G_OPTION_ARG_NONE
, &opt_introspect_xml
, N_("Print XML"), NULL
},
1415 { "recurse", 'r', 0, G_OPTION_ARG_NONE
, &opt_introspect_recurse
, N_("Introspect children"), NULL
},
1416 { "only-properties", 'p', 0, G_OPTION_ARG_NONE
, &opt_introspect_only_properties
, N_("Only print properties"), NULL
},
1421 introspect_do (GDBusConnection
*c
,
1422 const gchar
*object_path
,
1427 GDBusNodeInfo
*node
;
1429 const gchar
*xml_data
;
1436 result
= g_dbus_connection_call_sync (c
,
1437 opt_introspect_dest
,
1439 "org.freedesktop.DBus.Introspectable",
1442 G_VARIANT_TYPE ("(s)"),
1443 G_DBUS_CALL_FLAGS_NONE
,
1449 g_printerr (_("Error: %s\n"), error
->message
);
1450 g_error_free (error
);
1453 g_variant_get (result
, "(&s)", &xml_data
);
1455 if (opt_introspect_xml
)
1457 g_print ("%s", xml_data
);
1462 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
1465 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
1466 g_error_free (error
);
1470 dump_node (c
, opt_introspect_dest
, node
, indent
, object_path
, opt_introspect_recurse
);
1477 g_dbus_node_info_unref (node
);
1479 g_variant_unref (result
);
1484 handle_introspect (gint
*argc
,
1486 gboolean request_completion
,
1487 const gchar
*completion_cur
,
1488 const gchar
*completion_prev
)
1495 gboolean complete_names
;
1496 gboolean complete_paths
;
1501 modify_argv0_for_command (argc
, argv
, "introspect");
1503 o
= g_option_context_new (NULL
);
1504 if (request_completion
)
1505 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1506 g_option_context_set_help_enabled (o
, FALSE
);
1507 g_option_context_set_summary (o
, _("Introspect a remote object."));
1508 g_option_context_add_main_entries (o
, introspect_entries
, GETTEXT_PACKAGE
);
1509 g_option_context_add_group (o
, connection_get_group ());
1511 complete_names
= FALSE
;
1512 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1514 complete_names
= TRUE
;
1515 remove_arg ((*argc
) - 1, argc
, argv
);
1518 complete_paths
= FALSE
;
1519 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1521 complete_paths
= TRUE
;
1522 remove_arg ((*argc
) - 1, argc
, argv
);
1525 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1527 if (!request_completion
)
1529 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1530 g_printerr ("%s", s
);
1537 c
= connection_get_dbus_connection (&error
);
1540 if (request_completion
)
1542 if (g_strcmp0 (completion_prev
, "--address") == 0)
1550 g_print ("--system \n--session \n--address \n");
1555 g_printerr (_("Error connecting: %s\n"), error
->message
);
1556 g_error_free (error
);
1561 if (g_dbus_connection_get_unique_name (c
) != NULL
)
1565 print_names (c
, FALSE
);
1568 /* this only makes sense on message bus connections */
1569 if (opt_introspect_dest
== NULL
)
1571 if (request_completion
)
1572 g_print ("--dest \n");
1574 g_printerr (_("Error: Destination is not specified\n"));
1577 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1579 print_names (c
, g_str_has_prefix (opt_introspect_dest
, ":"));
1585 print_paths (c
, opt_introspect_dest
, "/");
1588 if (opt_introspect_object_path
== NULL
)
1590 if (request_completion
)
1591 g_print ("--object-path \n");
1593 g_printerr (_("Error: Object path is not specified\n"));
1596 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1599 s
= g_strdup (opt_introspect_object_path
);
1600 p
= strrchr (s
, '/');
1607 print_paths (c
, opt_introspect_dest
, s
);
1611 if (!request_completion
&& !g_variant_is_object_path (opt_introspect_object_path
))
1613 g_printerr (_("Error: %s is not a valid object path\n"), opt_introspect_object_path
);
1617 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_recurse
)
1619 g_print ("--recurse \n");
1622 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_only_properties
)
1624 g_print ("--only-properties \n");
1627 /* All done with completion now */
1628 if (request_completion
)
1631 if (!introspect_do (c
, opt_introspect_object_path
, 0))
1639 g_option_context_free (o
);
1643 /* ---------------------------------------------------------------------------------------------------- */
1645 static gchar
*opt_monitor_dest
= NULL
;
1646 static gchar
*opt_monitor_object_path
= NULL
;
1648 static guint monitor_filter_id
= 0;
1651 monitor_signal_cb (GDBusConnection
*connection
,
1652 const gchar
*sender_name
,
1653 const gchar
*object_path
,
1654 const gchar
*interface_name
,
1655 const gchar
*signal_name
,
1656 GVariant
*parameters
,
1660 s
= g_variant_print (parameters
, TRUE
);
1661 g_print ("%s: %s.%s %s\n",
1670 monitor_on_name_appeared (GDBusConnection
*connection
,
1672 const gchar
*name_owner
,
1675 g_print ("The name %s is owned by %s\n", name
, name_owner
);
1676 g_assert (monitor_filter_id
== 0);
1677 monitor_filter_id
= g_dbus_connection_signal_subscribe (connection
,
1679 NULL
, /* any interface */
1680 NULL
, /* any member */
1681 opt_monitor_object_path
,
1683 G_DBUS_SIGNAL_FLAGS_NONE
,
1685 NULL
, /* user_data */
1686 NULL
); /* user_data destroy notify */
1690 monitor_on_name_vanished (GDBusConnection
*connection
,
1694 g_print ("The name %s does not have an owner\n", name
);
1696 if (monitor_filter_id
!= 0)
1698 g_dbus_connection_signal_unsubscribe (connection
, monitor_filter_id
);
1699 monitor_filter_id
= 0;
1703 static const GOptionEntry monitor_entries
[] =
1705 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_monitor_dest
, N_("Destination name to monitor"), NULL
},
1706 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_monitor_object_path
, N_("Object path to monitor"), NULL
},
1711 handle_monitor (gint
*argc
,
1713 gboolean request_completion
,
1714 const gchar
*completion_cur
,
1715 const gchar
*completion_prev
)
1723 GDBusNodeInfo
*node
;
1724 gboolean complete_names
;
1725 gboolean complete_paths
;
1733 modify_argv0_for_command (argc
, argv
, "monitor");
1735 o
= g_option_context_new (NULL
);
1736 if (request_completion
)
1737 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1738 g_option_context_set_help_enabled (o
, FALSE
);
1739 g_option_context_set_summary (o
, _("Monitor a remote object."));
1740 g_option_context_add_main_entries (o
, monitor_entries
, GETTEXT_PACKAGE
);
1741 g_option_context_add_group (o
, connection_get_group ());
1743 complete_names
= FALSE
;
1744 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1746 complete_names
= TRUE
;
1747 remove_arg ((*argc
) - 1, argc
, argv
);
1750 complete_paths
= FALSE
;
1751 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1753 complete_paths
= TRUE
;
1754 remove_arg ((*argc
) - 1, argc
, argv
);
1757 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1759 if (!request_completion
)
1761 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1762 g_printerr ("%s", s
);
1769 c
= connection_get_dbus_connection (&error
);
1772 if (request_completion
)
1774 if (g_strcmp0 (completion_prev
, "--address") == 0)
1782 g_print ("--system \n--session \n--address \n");
1787 g_printerr (_("Error connecting: %s\n"), error
->message
);
1788 g_error_free (error
);
1793 if (g_dbus_connection_get_unique_name (c
) != NULL
)
1797 print_names (c
, FALSE
);
1800 /* this only makes sense on message bus connections */
1801 if (opt_monitor_dest
== NULL
)
1803 if (request_completion
)
1804 g_print ("--dest \n");
1806 g_printerr (_("Error: Destination is not specified\n"));
1809 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1811 print_names (c
, g_str_has_prefix (opt_monitor_dest
, ":"));
1817 print_paths (c
, opt_monitor_dest
, "/");
1820 if (opt_monitor_object_path
== NULL
)
1822 if (request_completion
)
1824 g_print ("--object-path \n");
1827 /* it's fine to not have an object path */
1829 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1832 s
= g_strdup (opt_monitor_object_path
);
1833 p
= strrchr (s
, '/');
1840 print_paths (c
, opt_monitor_dest
, s
);
1844 if (!request_completion
&& (opt_monitor_object_path
!= NULL
&& !g_variant_is_object_path (opt_monitor_object_path
)))
1846 g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path
);
1850 /* All done with completion now */
1851 if (request_completion
)
1854 if (opt_monitor_object_path
!= NULL
)
1855 g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path
, opt_monitor_dest
);
1857 g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest
);
1859 loop
= g_main_loop_new (NULL
, FALSE
);
1860 g_bus_watch_name_on_connection (c
,
1862 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
1863 monitor_on_name_appeared
,
1864 monitor_on_name_vanished
,
1868 g_main_loop_run (loop
);
1869 g_main_loop_unref (loop
);
1875 g_dbus_node_info_unref (node
);
1877 g_variant_unref (result
);
1880 g_option_context_free (o
);
1884 /* ---------------------------------------------------------------------------------------------------- */
1887 pick_word_at (const gchar
*s
,
1889 gint
*out_word_begins_at
)
1896 if (out_word_begins_at
!= NULL
)
1897 *out_word_begins_at
= -1;
1901 if (g_ascii_isspace (s
[cursor
]) && ((cursor
> 0 && g_ascii_isspace(s
[cursor
-1])) || cursor
== 0))
1903 if (out_word_begins_at
!= NULL
)
1904 *out_word_begins_at
= cursor
;
1905 return g_strdup ("");
1908 while (!g_ascii_isspace (s
[cursor
- 1]) && cursor
> 0)
1913 while (!g_ascii_isspace (s
[end
]) && s
[end
] != '\0')
1916 if (out_word_begins_at
!= NULL
)
1917 *out_word_begins_at
= begin
;
1919 return g_strndup (s
+ begin
, end
- begin
);
1923 main (gint argc
, gchar
*argv
[])
1926 const gchar
*command
;
1927 gboolean request_completion
;
1928 gchar
*completion_cur
;
1929 gchar
*completion_prev
;
1931 setlocale (LC_ALL
, "");
1932 textdomain (GETTEXT_PACKAGE
);
1935 extern gchar
*_glib_get_locale_dir (void);
1936 gchar
*tmp
= _glib_get_locale_dir ();
1937 bindtextdomain (GETTEXT_PACKAGE
, tmp
);
1940 bindtextdomain (GETTEXT_PACKAGE
, GLIB_LOCALE_DIR
);
1943 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1944 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
1948 completion_cur
= NULL
;
1949 completion_prev
= NULL
;
1955 usage (&argc
, &argv
, FALSE
);
1959 request_completion
= FALSE
;
1961 //completion_debug ("---- argc=%d --------------------------------------------------------", argc);
1965 if (g_strcmp0 (command
, "help") == 0)
1967 if (request_completion
)
1973 usage (&argc
, &argv
, TRUE
);
1978 else if (g_strcmp0 (command
, "emit") == 0)
1980 if (handle_emit (&argc
,
1988 else if (g_strcmp0 (command
, "call") == 0)
1990 if (handle_call (&argc
,
1998 else if (g_strcmp0 (command
, "introspect") == 0)
2000 if (handle_introspect (&argc
,
2008 else if (g_strcmp0 (command
, "monitor") == 0)
2010 if (handle_monitor (&argc
,
2018 else if (g_strcmp0 (command
, "complete") == 0 && argc
== 4 && !request_completion
)
2020 const gchar
*completion_line
;
2021 gchar
**completion_argv
;
2022 gint completion_argc
;
2023 gint completion_point
;
2027 request_completion
= TRUE
;
2029 completion_line
= argv
[2];
2030 completion_point
= strtol (argv
[3], &endp
, 10);
2031 if (endp
== argv
[3] || *endp
!= '\0')
2035 completion_debug ("completion_point=%d", completion_point
);
2036 completion_debug ("----");
2037 completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
2038 completion_debug ("`%s'", completion_line
);
2039 completion_debug (" %*s^",
2040 completion_point
, "");
2041 completion_debug ("----");
2044 if (!g_shell_parse_argv (completion_line
,
2049 /* it's very possible the command line can't be parsed (for
2050 * example, missing quotes etc) - in that case, we just
2051 * don't autocomplete at all
2056 /* compute cur and prev */
2057 completion_prev
= NULL
;
2058 completion_cur
= pick_word_at (completion_line
, completion_point
, &cur_begin
);
2062 for (prev_end
= cur_begin
- 1; prev_end
>= 0; prev_end
--)
2064 if (!g_ascii_isspace (completion_line
[prev_end
]))
2066 completion_prev
= pick_word_at (completion_line
, prev_end
, NULL
);
2072 completion_debug (" cur=`%s'", completion_cur
);
2073 completion_debug ("prev=`%s'", completion_prev
);
2076 argc
= completion_argc
;
2077 argv
= completion_argv
;
2085 if (request_completion
)
2087 g_print ("help \nemit \ncall \nintrospect \nmonitor \n");
2093 g_printerr ("Unknown command `%s'\n", command
);
2094 usage (&argc
, &argv
, FALSE
);
2100 g_free (completion_cur
);
2101 g_free (completion_prev
);