improve bloom filter on send
[platform/upstream/glib.git] / gio / gapplicationcommandline.c
index b2da4b1..d5e508a 100644 (file)
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- * USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors: Ryan Lortie <desrt@desrt.ca>
  */
 #include "gwin32inputstream.h"
 #endif
 
-G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
-
 /**
  * SECTION:gapplicationcommandline
  * @title: GApplicationCommandLine
  * @short_description: A command-line invocation of an application
+ * @include: gio/gio.h
  * @see_also: #GApplication
  *
  * #GApplicationCommandLine represents a command-line invocation of
@@ -60,7 +57,8 @@ G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJEC
  * The GApplicationCommandLine object can provide the @argc and @argv
  * parameters for use with the #GOptionContext command-line parsing API,
  * with the g_application_command_line_get_arguments() function. See
- * <xref linkend="gapplication-example-cmdline3"/> for an example.
+ * [gapplication-example-cmdline3.c][gapplication-example-cmdline3]
+ * for an example.
  *
  * The exit status of the originally-invoked process may be set and
  * messages can be printed to stdout or stderr of that process.  The
@@ -70,71 +68,143 @@ G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJEC
  *
  * The main use for #GApplicationCommandLine (and the
  * #GApplication::command-line signal) is 'Emacs server' like use cases:
- * You can set the <envar>EDITOR</envar> environment variable to have
- * e.g. git use your favourite editor to edit commit messages, and if you
- * already have an instance of the editor running, the editing will happen
+ * You can set the `EDITOR` environment variable to have e.g. git use
+ * your favourite editor to edit commit messages, and if you already
+ * have an instance of the editor running, the editing will happen
  * in the running instance, instead of opening a new one. An important
  * aspect of this use case is that the process that gets started by git
  * does not return until the editing is done.
  *
- * <example id="gapplication-example-cmdline"><title>Handling commandline arguments with GApplication</title>
- * <para>
- * A simple example where the commandline is completely handled
- * in the #GApplication::command-line handler. The launching instance exits
- * once the signal handler in the primary instance has returned, and the
- * return value of the signal handler becomes the exit status of the launching
- * instance.
- * </para>
- * <programlisting>
- * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gapplication-example-cmdline.c">
- *   <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
- * </xi:include>
- * </programlisting>
- * </example>
- *
- * <example id="gapplication-example-cmdline2"><title>Split commandline handling</title>
- * <para>
- * An example of split commandline handling. Options that start with
- * <literal>--local-</literal> are handled locally, all other options are
- * passed to the #GApplication::command-line handler which runs in the primary
+ * Normally, the commandline is completely handled in the
+ * #GApplication::command-line handler. The launching instance exits
+ * once the signal handler in the primary instance has returned, and
+ * the return value of the signal handler becomes the exit status
+ * of the launching instance.
+ * |[<!-- language="C" -->
+ * static int
+ * command_line (GApplication            *application,
+ *               GApplicationCommandLine *cmdline)
+ * {
+ *   gchar **argv;
+ *   gint argc;
+ *   gint i;
+ *
+ *   argv = g_application_command_line_get_arguments (cmdline, &argc);
+ *
+ *   g_application_command_line_print (cmdline,
+ *                                     "This text is written back\n"
+ *                                     "to stdout of the caller\n");
+ *
+ *   for (i = 0; i < argc; i++)
+ *     g_print ("argument %d: %s\n", i, argv[i]);
+ *
+ *   g_strfreev (argv);
+ *
+ *   return 0;
+ * }
+ * ]|
+ * The complete example can be found here: 
+ * [gapplication-example-cmdline.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline.c)
+ *
+ * In more complicated cases, the handling of the comandline can be
+ * split between the launcher and the primary instance.
+ * |[<!-- language="C" -->
+ * static gboolean
+ *  test_local_cmdline (GApplication   *application,
+ *                      gchar        ***arguments,
+ *                      gint           *exit_status)
+ * {
+ *   gint i, j;
+ *   gchar **argv;
+ *
+ *   argv = *arguments;
+ *
+ *   i = 1;
+ *   while (argv[i])
+ *     {
+ *       if (g_str_has_prefix (argv[i], "--local-"))
+ *         {
+ *           g_print ("handling argument %s locally\n", argv[i]);
+ *           g_free (argv[i]);
+ *           for (j = i; argv[j]; j++)
+ *             argv[j] = argv[j + 1];
+ *         }
+ *       else
+ *         {
+ *           g_print ("not handling argument %s locally\n", argv[i]);
+ *           i++;
+ *         }
+ *     }
+ *
+ *   *exit_status = 0;
+ *
+ *   return FALSE;
+ * }
+ *
+ * static void
+ * test_application_class_init (TestApplicationClass *class)
+ * {
+ *   G_APPLICATION_CLASS (class)->local_command_line = test_local_cmdline;
+ *
+ *   ...
+ * }
+ * ]|
+ * In this example of split commandline handling, options that start
+ * with `--local-` are handled locally, all other options are passed
+ * to the #GApplication::command-line handler which runs in the primary
  * instance.
- * </para>
- * <programlisting>
- * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gapplication-example-cmdline2.c">
- *   <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
- * </xi:include>
- * </programlisting>
- * </example>
- *
- * <example id="gapplication-example-cmdline3"><title>Deferred commandline handling</title>
- * <para>
- * An example of deferred commandline handling. Here, the commandline is
- * not completely handled before the #GApplication::command-line handler
- * returns. Instead, we keep a reference to the GApplicationCommandLine
- * object and handle it later(in this example, in an idle). Note that it
- * is necessary to hold the application until you are done with the
- * commandline.
- * </para>
- * <para>
- * This example also shows how to use #GOptionContext for parsing the
- * commandline arguments. Note that it is necessary to disable the
- * built-in help-handling of #GOptionContext, since it calls exit()
- * after printing help, which is not what you want to happen in
- * the primary instance.
- * </para>
- * <programlisting>
- * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gapplication-example-cmdline3.c">
- *   <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
- * </xi:include>
- * </programlisting>
- * </example>
- **/
+ *
+ * The complete example can be found here:
+ * [gapplication-example-cmdline2.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline2.c)
+ *
+ * If handling the commandline requires a lot of work, it may
+ * be better to defer it.
+ * |[<!-- language="C" -->
+ * static gboolean
+ * my_cmdline_handler (gpointer data)
+ * {
+ *   GApplicationCommandLine *cmdline = data;
+ *
+ *   // do the heavy lifting in an idle
+ *
+ *   g_application_command_line_set_exit_status (cmdline, 0);
+ *   g_object_unref (cmdline); // this releases the application
+ *
+ *   return G_SOURCE_REMOVE;
+ * }
+ *
+ * static int
+ * command_line (GApplication            *application,
+ *               GApplicationCommandLine *cmdline)
+ * {
+ *   // keep the application running until we are done with this commandline
+ *   g_application_hold (application);
+ *
+ *   g_object_set_data_full (G_OBJECT (cmdline),
+ *                           "application", application,
+ *                           (GDestroyNotify)g_application_release);
+ *
+ *   g_object_ref (cmdline);
+ *   g_idle_add (my_cmdline_handler, cmdline);
+ *
+ *   return 0;
+ * }
+ * ]|
+ * In this example the commandline is not completely handled before
+ * the #GApplication::command-line handler returns. Instead, we keep
+ * a reference to the #GApplicationCommandLine object and handle it
+ * later (in this example, in an idle). Note that it is necessary to
+ * hold the application until you are done with the commandline.
+ *
+ * The complete example can be found here:
+ * [gapplication-example-cmdline3.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline3.c)
+ */
 
 /**
  * GApplicationCommandLineClass:
  *
- * The <structname>GApplicationCommandLineClass</structname> structure
- * contains private data only
+ * The #GApplicationCommandLineClass-struct 
+ * contains private data only.
  *
  * Since: 2.28
  **/
@@ -142,6 +212,7 @@ enum
 {
   PROP_NONE,
   PROP_ARGUMENTS,
+  PROP_OPTIONS,
   PROP_PLATFORM_DATA,
   PROP_IS_REMOTE
 };
@@ -150,12 +221,16 @@ struct _GApplicationCommandLinePrivate
 {
   GVariant *platform_data;
   GVariant *arguments;
+  GVariant *options;
+  GVariantDict *options_dict;
   gchar *cwd;
 
   gchar **environ;
   gint exit_status;
 };
 
+G_DEFINE_TYPE_WITH_PRIVATE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
+
 /* All subclasses represent remote invocations of some kind. */
 #define IS_REMOTE(cmdline) (G_TYPE_FROM_INSTANCE (cmdline) != \
                             G_TYPE_APPLICATION_COMMAND_LINE)
@@ -182,6 +257,12 @@ grok_platform_data (GApplicationCommandLine *cmdline)
           cmdline->priv->environ =
             g_variant_dup_bytestring_array (value, NULL);
       }
+
+    else if (strcmp (key, "options") == 0)
+      {
+        if (!cmdline->priv->options)
+          cmdline->priv->options = g_variant_ref (value);
+      }
 }
 
 static void
@@ -250,6 +331,11 @@ g_application_command_line_set_property (GObject      *object,
       cmdline->priv->arguments = g_value_dup_variant (value);
       break;
 
+    case PROP_OPTIONS:
+      g_assert (cmdline->priv->options == NULL);
+      cmdline->priv->options = g_value_dup_variant (value);
+      break;
+
     case PROP_PLATFORM_DATA:
       g_assert (cmdline->priv->platform_data == NULL);
       cmdline->priv->platform_data = g_value_dup_variant (value);
@@ -267,6 +353,12 @@ g_application_command_line_finalize (GObject *object)
 {
   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
 
+  if (cmdline->priv->options_dict)
+    g_variant_dict_unref (cmdline->priv->options_dict);
+
+  if (cmdline->priv->options)
+      g_variant_unref (cmdline->priv->options);
+
   if (cmdline->priv->platform_data)
     g_variant_unref (cmdline->priv->platform_data);
   if (cmdline->priv->arguments)
@@ -282,10 +374,7 @@ g_application_command_line_finalize (GObject *object)
 static void
 g_application_command_line_init (GApplicationCommandLine *cmdline)
 {
-  cmdline->priv =
-    G_TYPE_INSTANCE_GET_PRIVATE (cmdline,
-                                 G_TYPE_APPLICATION_COMMAND_LINE,
-                                 GApplicationCommandLinePrivate);
+  cmdline->priv = g_application_command_line_get_instance_private (cmdline);
 }
 
 static void
@@ -326,6 +415,13 @@ g_application_command_line_class_init (GApplicationCommandLineClass *class)
                           G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
                           G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (object_class, PROP_OPTIONS,
+    g_param_spec_variant ("options",
+                          P_("Options"),
+                          P_("The options sent along with the commandline"),
+                          G_VARIANT_TYPE_VARDICT, NULL, G_PARAM_WRITABLE |
+                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
     g_param_spec_variant ("platform-data",
                           P_("Platform data"),
@@ -340,8 +436,6 @@ g_application_command_line_class_init (GApplicationCommandLineClass *class)
                           P_("TRUE if this is a remote commandline"),
                           FALSE,
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  g_type_class_add_private (class, sizeof (GApplicationCommandLinePrivate));
 }
 
 
@@ -352,7 +446,12 @@ g_application_command_line_class_init (GApplicationCommandLineClass *class)
  *
  * Gets the list of arguments that was passed on the command line.
  *
- * The strings in the array may contain non-utf8 data.
+ * The strings in the array may contain non-UTF-8 data on UNIX (such as
+ * filenames or arguments given in the system locale) but are always in
+ * UTF-8 on Windows.
+ *
+ * If you wish to use the return value with #GOptionContext, you must
+ * use g_option_context_parse_strv().
  *
  * The return value is %NULL-terminated and should be freed using
  * g_strfreev().
@@ -380,7 +479,36 @@ g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
 }
 
 /**
- * g_application_command_line_get_stdin_data:
+ * g_application_command_line_get_options_dict:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Gets the options there were passed to g_application_command_line().
+ *
+ * If you did not override local_command_line() then these are the same
+ * options that were parsed according to the #GOptionEntrys added to the
+ * application with g_application_add_main_option_entries() and possibly
+ * modified from your GApplication::handle-local-options handler.
+ *
+ * If no options were sent then an empty dictionary is returned so that
+ * you don't need to check for %NULL.
+ *
+ * Returns: (transfer none): a #GVariantDict with the options
+ *
+ * Since: 2.40
+ **/
+GVariantDict *
+g_application_command_line_get_options_dict (GApplicationCommandLine *cmdline)
+{
+  g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
+
+  if (!cmdline->priv->options_dict)
+    cmdline->priv->options_dict = g_variant_dict_new (cmdline->priv->options);
+
+  return cmdline->priv->options_dict;
+}
+
+/**
+ * g_application_command_line_get_stdin:
  * @cmdline: a #GApplicationCommandLine
  *
  * Gets the stdin of the invoking process.
@@ -652,7 +780,7 @@ g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline)
  *
  * For local invocation, it will be %NULL.
  *
- * Returns: (allow-none): the platform data, or %NULL
+ * Returns: (nullable): the platform data, or %NULL
  *
  * Since: 2.28
  **/