Re: Escaping in (#51382)
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Subject: Re: Escaping in (#51382)
- Date: 17 Mar 2001 19:50:10 -0500
Tim Janik <timj gtk org> writes:
> > > > * GScanner and hence RC files support C-string like
> > > > escaping with \n \r \t \b \f and octal escapes.
> > > >
> > > > This would imply:
> > > >
> > > > "/_File/\\/var\\/log\\/messages"
> > >
> > > we don't actually have an option here, the item factory
> > > dumps are supposed to be GScanner parsable, so we'll have
> > > to use this style.
> >
> > OK, I'll do that then.
>
> that's not much, i.e. it shouldn't be more than just:
> + name = g_strescape (string, NULL);
> + g_free (string);
> + string = name;
> data->print_func (data->func_data, string);
Well, considering that g_strescape() mangles UTF-8 pretty
badly, I just wrote my own escaper in a few lines.
Complete patch to:
- Allow / in GtkItemFactory
- Escape \n and " when dumping accelerators
- Fix problem with __ in item factory paths
is attached. With all the typical ugliness of multiple levels
of escaping, of course.
Regards,
Owen
Index: gtkitemfactory.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkitemfactory.c,v
retrieving revision 1.33
diff -u -r1.33 gtkitemfactory.c
--- gtkitemfactory.c 2001/03/07 14:49:19 1.33
+++ gtkitemfactory.c 2001/03/18 00:44:46
@@ -723,6 +723,37 @@
return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_item_path);
}
+static gchar *
+item_factory_escape_path (const gchar *path)
+{
+ GString *str = g_string_new (NULL);
+
+ while (*path)
+ {
+ gchar c = *path;
+
+ switch (c)
+ {
+ case '\n':
+ g_string_append (str, "\\n");
+ break;
+ case '\r':
+ g_string_append (str, "\\r");
+ break;
+ case '"':
+ case '\\':
+ g_string_append_c (str, '\\');
+ /* Fall through */
+ default:
+ g_string_append_c (str, c);
+ }
+
+ path++;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
static void
gtk_item_factory_foreach (gpointer hash_key,
gpointer value,
@@ -731,6 +762,7 @@
GtkItemFactoryItem *item;
GtkIFDumpData *data;
gchar *string;
+ gchar *path;
gchar *name;
gchar comment_prefix[2] = "\000\000";
@@ -742,14 +774,16 @@
comment_prefix[0] = gtk_item_factory_class->cpair_comment_single[0];
+ path = item_factory_escape_path (hash_key);
name = gtk_accelerator_name (item->accelerator_key, item->accelerator_mods);
string = g_strconcat (item->modified ? "" : comment_prefix,
"(menu-path \"",
- hash_key,
+ path,
"\" \"",
name,
"\")",
NULL);
+ g_free (path);
g_free (name);
data->print_func (data->func_data, string);
@@ -942,6 +976,60 @@
return GTK_IS_ITEM (widget) ? widget : NULL;
}
+static char *
+item_factory_find_separator_r (char *path)
+{
+ gchar *result = NULL;
+ gboolean escaped = FALSE;
+
+ while (*path)
+ {
+ if (escaped)
+ escaped = FALSE;
+ else
+ {
+ if (*path == '\\')
+ escaped = TRUE;
+ else if (*path == '/')
+ result = path;
+ }
+
+ path++;
+ }
+
+ return result;
+}
+
+static char *
+item_factory_unescape_label (const char *label)
+{
+ char *new = g_malloc (strlen (label) + 1);
+ char *p = new;
+ gboolean escaped = FALSE;
+
+ while (*label)
+ {
+ if (escaped)
+ {
+ *p++ = *label;
+ escaped = FALSE;
+ }
+ else
+ {
+ if (*label == '\\')
+ escaped = TRUE;
+ else
+ *p++ = *label;
+ }
+
+ label++;
+ }
+
+ *p = '\0';
+
+ return new;
+}
+
static gboolean
gtk_item_factory_parse_path (GtkItemFactory *ifactory,
gchar *str,
@@ -951,14 +1039,21 @@
{
gchar *translation;
gchar *p, *q;
-
+
*path = g_strdup (str);
- /* FIXME: This does not handle __ correctly !!! */
p = q = *path;
while (*p)
{
- if (*p != '_')
+ if (*p == '_')
+ {
+ if (p[1] == '_')
+ {
+ p++;
+ *q++ = '_';
+ }
+ }
+ else
{
*q++ = *p;
}
@@ -967,7 +1062,7 @@
*q = 0;
*parent_path = g_strdup (*path);
- p = strrchr (*parent_path, '/');
+ p = item_factory_find_separator_r (*parent_path);
if (!p)
{
g_warning ("GtkItemFactory: invalid entry path `%s'", str);
@@ -980,13 +1075,13 @@
else
translation = str;
- p = strrchr (translation, '/');
+ p = item_factory_find_separator_r (translation);
if (p)
p++;
else
p = translation;
- *item = g_strdup (p);
+ *item = item_factory_unescape_label (p);
return TRUE;
}
@@ -1077,7 +1172,7 @@
gchar *ppath, *p;
ppath = g_strdup (entry->path);
- p = strrchr (ppath, '/');
+ p = item_factory_find_separator_r (ppath);
g_return_if_fail (p != NULL);
*p = 0;
pentry.path = ppath;
Index: testgtk.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/testgtk.c,v
retrieving revision 1.228
diff -u -r1.228 testgtk.c
--- testgtk.c 2001/03/08 17:13:11 1.228
+++ testgtk.c 2001/03/18 00:44:46
@@ -2969,16 +2969,27 @@
g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
}
+static void
+dump_accels (gpointer callback_data,
+ guint callback_action,
+ GtkWidget *widget)
+{
+ gtk_item_factory_dump_items (NULL, FALSE, gtk_item_factory_print_func, stdout);
+}
+
static GtkItemFactoryEntry menu_items[] =
{
- { "/_File", NULL, 0, 0, "<Branch>" },
- { "/File/tearoff1", NULL, gtk_ifactory_cb, 0, "<Tearoff>" },
- { "/File/_New", "<control>N", gtk_ifactory_cb, 0 },
- { "/File/_Open", "<control>O", gtk_ifactory_cb, 0 },
- { "/File/_Save", "<control>S", gtk_ifactory_cb, 0 },
- { "/File/Save _As...", NULL, gtk_ifactory_cb, 0 },
- { "/File/sep1", NULL, gtk_ifactory_cb, 0, "<Separator>" },
- { "/File/_Quit", "<control>Q", gtk_ifactory_cb, 0 },
+ { "/_File", NULL, 0, 0, "<Branch>" },
+ { "/File/tearoff1", NULL, gtk_ifactory_cb, 0, "<Tearoff>" },
+ { "/File/_New", "<control>N", gtk_ifactory_cb, 0 },
+ { "/File/_Open", "<control>O", gtk_ifactory_cb, 0 },
+ { "/File/_Save", "<control>S", gtk_ifactory_cb, 0 },
+ { "/File/Save _As...", NULL, gtk_ifactory_cb, 0 },
+ { "/File/_Dump \"_Accels\"", NULL, dump_accels, 0 },
+ { "/File/\\/Test__Escaping/And\\/\n\tWei\\\\rdly",
+ NULL, gtk_ifactory_cb, 0 },
+ { "/File/sep1", NULL, gtk_ifactory_cb, 0, "<Separator>" },
+ { "/File/_Quit", "<control>Q", gtk_ifactory_cb, 0 },
{ "/_Preferences", NULL, 0, 0, "<Branch>" },
{ "/_Preferences/_Color", NULL, 0, 0, "<Branch>" },
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]