SF.net SVN: geany:[4550] branches/sm/src
statc at users.sourceforge.net
statc at xxxxx
Sun Jan 24 20:25:17 UTC 2010
Revision: 4550
http://geany.svn.sourceforge.net/geany/?rev=4550&view=rev
Author: statc
Date: 2010-01-24 20:25:17 +0000 (Sun, 24 Jan 2010)
Log Message:
-----------
Add "reverse parser" of GOptionEntry. Handle all command-line options.
Modified Paths:
--------------
branches/sm/src/main.c
branches/sm/src/main.h
branches/sm/src/sm.c
branches/sm/src/utils.c
branches/sm/src/utils.h
Modified: branches/sm/src/main.c
===================================================================
--- branches/sm/src/main.c 2010-01-24 20:24:52 UTC (rev 4549)
+++ branches/sm/src/main.c 2010-01-24 20:25:17 UTC (rev 4550)
@@ -118,8 +118,15 @@
static gboolean dummy = FALSE;
static gchar * libsm_client_id = NULL;
+/* WARNING: Do not change values of variables where values of command-line options are stored!
+ * This is, they must remain unchanged after `g_option_context_parse' returns.
+ * Otherwise, "restart command" for X session management will be filled improperly.
+ *
+ * NOTE: Currently optentries of type G_OPTION_ARG_CALLBACK are not supported by
+ * X session management support implementation.
+ */
/* in alphabetical order of short options */
-static GOptionEntry entries[] =
+GOptionEntry optentries[] =
{
{ "column", 0, 0, G_OPTION_ARG_INT, &cl_options.goto_column, N_("Set initial column number for the first opened file (useful in conjunction with --line)"), NULL },
{ "config", 'c', 0, G_OPTION_ARG_FILENAME, &alternate_config, N_("Use an alternate configuration directory"), NULL },
@@ -146,10 +153,39 @@
{ "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Show version and exit"), NULL },
{ "dummy", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &dummy, NULL, NULL }, /* for +NNN line number arguments */
{ "libsm-client-id", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &libsm_client_id, NULL, NULL },
+ /* add new options here and in `optentries_aux' below */
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
+GeanyOptionEntryAux optentries_aux[] = {
+ {FALSE}, /* "column" */
+ {TRUE}, /* "config" */
+ {FALSE}, /* "ft-names */
+ {FALSE}, /* "generate-tags" */
+ {FALSE}, /* "no-preprocessing" */
+#ifdef HAVE_SOCKET
+ {TRUE}, /* "new-instance" */
+ {TRUE}, /* "socket-file" */
+#endif
+ {FALSE}, /* "line" */
+ {TRUE}, /* "no-msgwin" */
+ {TRUE}, /* "no-ctags" */
+#ifdef HAVE_PLUGINS
+ {TRUE}, /* "no-plugins" */
+#endif
+ {FALSE}, /* "print-prefix" */
+ {TRUE}, /* "no-session" */
+#ifdef HAVE_VTE
+ {TRUE}, /* "no-terminal" */
+ {TRUE}, /* "vte-lib" */
+#endif
+ {TRUE}, /* "verbose" */
+ {FALSE}, /* "version" */
+ {FALSE}, /* "dummy" */
+ {FALSE}, /* "libsm-client-id" option is handled separately */
+};
+
static void setup_window_position(void)
{
/* interprets the saved window geometry */
@@ -489,7 +525,7 @@
}
context = g_option_context_new(_("[FILES...]"));
- g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE);
+ g_option_context_add_main_entries(context, optentries, GETTEXT_PACKAGE);
g_option_group_set_translation_domain(g_option_context_get_main_group(context), GETTEXT_PACKAGE);
g_option_context_add_group(context, gtk_get_option_group(FALSE));
g_option_context_parse(context, argc, argv, &error);
Modified: branches/sm/src/main.h
===================================================================
--- branches/sm/src/main.h 2010-01-24 20:24:52 UTC (rev 4549)
+++ branches/sm/src/main.h 2010-01-24 20:25:17 UTC (rev 4550)
@@ -25,8 +25,22 @@
#ifndef GEANY_MAIN_H
#define GEANY_MAIN_H
+/** Information about command line entries that can not be stored in GOptionEntry. */
typedef struct
{
+ /**
+ * Indicates whether the value of a command-line option should go to "restart command".
+ * See X session management support implementation in sm.{c,h}.
+ */
+ gboolean persist_upon_restart;
+}
+GeanyOptionEntryAux;
+
+extern GOptionEntry optentries[];
+extern GeanyOptionEntryAux optentries_aux[];
+
+typedef struct
+{
gboolean new_instance;
gchar *socket_filename;
gboolean load_session;
Modified: branches/sm/src/sm.c
===================================================================
--- branches/sm/src/sm.c 2010-01-24 20:24:52 UTC (rev 4549)
+++ branches/sm/src/sm.c 2010-01-24 20:25:17 UTC (rev 4550)
@@ -390,54 +390,38 @@
*/
static void sm_set_runtime_props(SmcConn smcon)
{
- const gint page_count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
+ GArray * arr = g_array_new(FALSE, FALSE, sizeof(SmPropValue));
+ gint arr_filenames_begin = -1;
- GArray * arr;
- gint arr_real_len, arr_filenames_begin;
-
- SmProp restart_command_prop, clone_command_prop;
- SmPropValue * val;
+ GOptionEntry * optentry;
+ SmPropValue val;
SmProp * prop;
+ SmProp restart_command_prop, clone_command_prop;
gint i;
- /*
- * Allocate space for `page_count+5' elements:
- * * two elements for program name and client ID;
- * * possibly one element for "--no-session" option;
- * * possibly one element for "--new-instance" option;
- * * possible one element for "--" to separate options and filenames;
- * * max `page_count' elements for file paths.
- * The number of actually used elements is saved in `arr_real_len'.
- * Variable `arr_filenames_begin' stores the index in the array where
- * the list of filenames begin. If there are no filenames in `arr',
- * the value is -1.
- */
- arr = g_array_sized_new(FALSE, FALSE, sizeof(SmPropValue), page_count + 5);
- arr_real_len = 0;
- arr_filenames_begin = -1;
-
- ((SmPropValue *)arr->data)[arr_real_len++] = sm_program_val;
- ((SmPropValue *)arr->data)[arr_real_len++] = sm_client_id_arg_val;
-
- if (!cl_options.load_session)
+ g_array_append_val(arr, sm_program_val);
+ /* "libsm-client-id" option requires special handling */
+ g_array_append_val(arr, sm_client_id_arg_val);
+ /* handle other command-line options */
+ for (i = 0, optentry = optentries; optentry->long_name; i++, optentry++)
{
- val = ((SmPropValue *)arr->data) + arr_real_len++;
- val->length = 2; /* length of "-s" */
- val->value = "-s";
+ if (optentries_aux[i].persist_upon_restart)
+ {
+ GArray * arr2 = utils_option_entry_reverse_parse(optentry);
+ gchar ** ss = (gchar **)arr2->data;
+ for (; *ss; ss++)
+ {
+ val.length = strlen(*ss);
+ val.value = *ss;
+ g_array_append_val(arr, val);
+ }
+ /* elements are freed after `arr' is used */
+ g_array_free(arr2, TRUE);
+ }
}
-#ifdef HAVE_SOCKET
- if (cl_options.new_instance)
- {
- val = ((SmPropValue *)arr->data) + arr_real_len++;
- val->length = 2; /* length of "-i" */
- val->value = "-i";
- }
-#endif
- /* TODO: handle other command-line options */
-
if (cl_options.load_session && !cl_options.new_instance)
{
/*
@@ -448,13 +432,13 @@
else
{
/* Specify file names in the command line */
+ const gint page_count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
- val = ((SmPropValue *)arr->data) + arr_real_len++;
- val->length = 2; /* length of "--" */
- val->value = "--";
+ val.length = 2;
+ val.value = "--";
+ g_array_append_val(arr, val);
+ arr_filenames_begin = arr->len;
- arr_filenames_begin = arr_real_len;
-
/*
* NOTE: compare this cycle with the one inside
* configuration_save_session_files() function in keyfile.c.
@@ -464,12 +448,12 @@
GeanyDocument * doc = document_get_from_page(i);
if (doc && doc->real_path)
{
- /* this string will be freed when `arr' is no longer needed */
+ /* freed after `arr' is used */
gchar * locale_filename = utils_get_locale_from_utf8(doc->file_name);
- val = ((SmPropValue *)arr->data) + arr_real_len++;
- val->length = strlen(locale_filename);
- val->value = locale_filename;
+ val.length = strlen(locale_filename);
+ val.value = locale_filename;
+ g_array_append_val(arr, val);
}
}
}
@@ -477,7 +461,7 @@
restart_command_prop.name = SmRestartCommand;
restart_command_prop.type = SmLISTofARRAY8;
- restart_command_prop.num_vals = arr_real_len;
+ restart_command_prop.num_vals = arr->len;
restart_command_prop.vals = (SmPropValue *)arr->data;
prop = &restart_command_prop;
SmcSetProperties(smcon, 1, &prop);
@@ -489,14 +473,15 @@
((SmPropValue *)arr->data)[1] = sm_program_val;
clone_command_prop.name = SmCloneCommand;
clone_command_prop.type = SmLISTofARRAY8;
- clone_command_prop.num_vals = arr_real_len - 1;
+ clone_command_prop.num_vals = arr->len - 1;
clone_command_prop.vals = ((SmPropValue *)arr->data) + 1;
prop = &clone_command_prop;
SmcSetProperties(smcon, 1, &prop);
- if (arr_filenames_begin != -1)
- for (i = arr_filenames_begin; i < arr_real_len; i++)
+ /* free allocated strings storing command-line options and file names */
+ for (i = 2; i < arr->len; i++)
+ if (i != (arr_filenames_begin - 1))
g_free(((SmPropValue *)arr->data)[i].value);
g_array_free(arr, TRUE);
}
Modified: branches/sm/src/utils.c
===================================================================
--- branches/sm/src/utils.c 2010-01-24 20:24:52 UTC (rev 4549)
+++ branches/sm/src/utils.c 2010-01-24 20:25:17 UTC (rev 4550)
@@ -1885,7 +1885,7 @@
g_free(uri);
uri = g_strconcat(GEANY_HOMEPAGE, "manual/", VERSION, "/index.html", NULL);
}
-
+
if (suffix != NULL)
{
setptr(uri, g_strconcat(uri, suffix, NULL));
@@ -1894,3 +1894,69 @@
return uri;
}
+
+GArray * utils_option_entry_reverse_parse(const GOptionEntry * optentry)
+{
+ GArray * ret = g_array_new(TRUE, TRUE, sizeof(gchar *));
+ gchar * s;
+ gchar ** ss;
+
+ switch (optentry->arg)
+ {
+ case G_OPTION_ARG_NONE:
+ {
+ gboolean val = *(gboolean *)optentry->arg_data;
+ gboolean reverse = (optentry->flags & G_OPTION_FLAG_REVERSE);
+ if ((val && !reverse) || (!val && reverse)) /* logical XOR */
+ {
+ s = g_strdup_printf("--%s", optentry->long_name);
+ g_array_append_val(ret, s);
+ }
+ }
+ break;
+
+ case G_OPTION_ARG_INT:
+ s = g_strdup_printf("--%s=%d",
+ optentry->long_name, *(gint *)optentry->arg_data);
+ g_array_append_val(ret, s);
+ break;
+#if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 12
+ case G_OPTION_ARG_INT64:
+ s = g_strdup_printf("--%s=%" G_GINT64_MODIFIER "d",
+ optentry->long_name, *(gint64 *)optentry->arg_data);
+ g_array_append_val(ret, s);
+ break;
+ case G_OPTION_ARG_DOUBLE:
+ s = g_strdup_printf("--%s=%f",
+ optentry->long_name, *(gdouble *)optentry->arg_data);
+ g_array_append_val(ret, s);
+ break;
+#endif
+
+ case G_OPTION_ARG_STRING:
+ case G_OPTION_ARG_FILENAME:
+ if (*(gchar **)optentry->arg_data)
+ {
+ s = g_strdup_printf("--%s=%s", optentry->long_name, *(gchar **)optentry->arg_data);
+ g_array_append_val(ret, s);
+ }
+ break;
+ case G_OPTION_ARG_STRING_ARRAY:
+ case G_OPTION_ARG_FILENAME_ARRAY:
+ for (ss = *(gchar ***)optentry->arg_data; *ss; ss++)
+ {
+ s = g_strdup_printf("--%s=%s", optentry->long_name, *ss);
+ g_array_append_val(ret, s);
+ }
+ break;
+
+ case G_OPTION_ARG_CALLBACK:
+ g_warning("%s: %s\n", G_STRFUNC,
+ "Cannot reverse parse option entries of type G_OPTION_ARG_CALLBACK");
+ break;
+ default:
+ g_warning("%s: %s: %d\n", G_STRFUNC, "Unknown option entry type", optentry->arg);
+ break;
+ }
+ return ret;
+}
Modified: branches/sm/src/utils.h
===================================================================
--- branches/sm/src/utils.h 2010-01-24 20:24:52 UTC (rev 4549)
+++ branches/sm/src/utils.h 2010-01-24 20:25:17 UTC (rev 4550)
@@ -229,4 +229,20 @@
gchar *utils_str_remove_chars(gchar *string, const gchar *chars);
+
+/**
+ * "Reverse parse" @c GOptionEntry
+ *
+ * @param optentry Object to parse.
+ * @return Null-terminated array of strings (@c gchar*).
+ *
+ * Function takes the information about the option entry stored in @c optentry
+ * and the option's value by the address stored in @c optentry. It returns an array
+ * of strings such that it specifies the option's value when used like @c argv.
+ *
+ * Elements of the resulting array must be freed with @c g_free(). The array
+ * itself must be freed with @c g_array_free().
+ */
+GArray * utils_option_entry_reverse_parse(const GOptionEntry * optentry);
+
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list