diff options
| -rw-r--r-- | hardinfo/gg_key_file_parse_string_as_value.c | 109 | ||||
| -rw-r--r-- | hardinfo/info.c | 10 | ||||
| -rw-r--r-- | shell/shell.c | 106 | 
3 files changed, 170 insertions, 55 deletions
diff --git a/hardinfo/gg_key_file_parse_string_as_value.c b/hardinfo/gg_key_file_parse_string_as_value.c new file mode 100644 index 00000000..496b1d35 --- /dev/null +++ b/hardinfo/gg_key_file_parse_string_as_value.c @@ -0,0 +1,109 @@ +/* From: gkeyfile.c - key file parser + * + *  Copyright 2004  Red Hat, Inc. + *  Copyright 2009-2010  Collabora Ltd. + *  Copyright 2009  Nokia Corporation + * + * Written by Ray Strode <rstrode@redhat.com> + *            Matthias Clasen <mclasen@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * 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, see <http://www.gnu.org/licenses/>. + */ + +static gchar * +gg_key_file_parse_string_as_value (const gchar *string, const gchar list_separator) +{ +  gchar *value, *p, *q; +  gsize length; +  gboolean parsing_leading_space; + +  length = strlen (string) + 1; + +  /* Worst case would be that every character needs to be escaped. +   * In other words every character turns to two characters. */ +  value = g_new (gchar, 2 * length); + +  p = (gchar *) string; +  q = value; +  parsing_leading_space = TRUE; +  while (p < (string + length - 1)) +    { +      gchar escaped_character[3] = { '\\', 0, 0 }; + +      switch (*p) +        { +        case ' ': +          if (parsing_leading_space) +            { +              escaped_character[1] = 's'; +              strcpy (q, escaped_character); +              q += 2; +            } +          else +            { +	      *q = *p; +	      q++; +            } +          break; +        case '\t': +          if (parsing_leading_space) +            { +              escaped_character[1] = 't'; +              strcpy (q, escaped_character); +              q += 2; +            } +          else +            { +	      *q = *p; +	      q++; +            } +          break; +        case '\n': +          escaped_character[1] = 'n'; +          strcpy (q, escaped_character); +          q += 2; +          break; +        case '\r': +          escaped_character[1] = 'r'; +          strcpy (q, escaped_character); +          q += 2; +          break; +        case '\\': +          escaped_character[1] = '\\'; +          strcpy (q, escaped_character); +          q += 2; +          parsing_leading_space = FALSE; +          break; +        default: +	  if (list_separator && *p == list_separator) +	    { +	      escaped_character[1] = list_separator; +	      strcpy (q, escaped_character); +	      q += 2; +              parsing_leading_space = TRUE; +	    } +	  else +	    { +	      *q = *p; +	      q++; +              parsing_leading_space = FALSE; +	    } +          break; +        } +      p++; +    } +  *q = '\0'; + +  return value; +} diff --git a/hardinfo/info.c b/hardinfo/info.c index bfc11fc2..ac18e0d9 100644 --- a/hardinfo/info.c +++ b/hardinfo/info.c @@ -18,6 +18,12 @@  #include "hardinfo.h" +/* Using a slightly modified gg_key_file_parse_string_as_value() + * from GLib in flatten(), to escape characters and the separator. + * The function is not public in GLib and we don't have a GKeyFile + * to pass it anyway. */ +#include "gg_key_file_parse_string_as_value.c" +  static const gchar *info_column_titles[] = {      "TextValue", "Value", "Progress", "Extra1", "Extra2"  }; @@ -267,7 +273,9 @@ static void flatten_group(GString *output, const struct InfoGroup *group, guint                      tp);              } -            g_string_append_printf(output, "%s=%s\n", field->name, field->value); +            gchar *escaped_value = gg_key_file_parse_string_as_value(field->value, '|'); +            g_string_append_printf(output, "%s=%s\n", field->name, escaped_value); +            g_free(escaped_value);          }      } else if (group->computed) {          g_string_append_printf(output, "%s\n", group->computed); diff --git a/shell/shell.c b/shell/shell.c index 31836d62..106f6722 100644 --- a/shell/shell.c +++ b/shell/shell.c @@ -1271,70 +1271,68 @@ static void group_handle_normal(GKeyFile *key_file,          g_free(tmp);      } +    g_key_file_set_list_separator(key_file, '|'); +      for (i = 0; keys[i]; i++) {          gchar *key = keys[i]; -        gchar *value; +        gchar **values; +        gsize vcount = 0;          GtkTreeIter child; -        value = g_key_file_get_value(key_file, group, key, NULL); -        if (entry->fieldfunc && value && g_str_equal(value, "...")) { -            g_free(value); -            value = entry->fieldfunc(key); -        } - -        if ((key && value) && g_utf8_validate(key, -1, NULL) && -            g_utf8_validate(value, -1, NULL)) { -            if (ngroups == 1) { -                gtk_tree_store_append(store, &child, NULL); -            } else { -                gtk_tree_store_append(store, &child, &parent); -            } - -            /* FIXME: use g_key_file_get_string_list? */ -            if (g_utf8_strchr(value, -1, '|')) { -                gchar **columns = g_strsplit(value, "|", 0); - -                gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, -                                   columns[0], -1); -                if (columns[1]) { -                    gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA1, -                                       columns[1], -1); -                    if (columns[2]) { -                        gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA2, -                                           columns[2], -1); -                    } -                } - -                g_strfreev(columns); +        values = g_key_file_get_string_list(key_file, group, key, &vcount, NULL); +        if (!vcount) { +            /* Check for empty value */ +            values = g_new0(gchar*, 2); +            values[0] = g_key_file_get_string(key_file, group, key, NULL); +            if (values[0]) { +                vcount = 1;              } else { -                gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, value, -                                   -1); +                g_strfreev(values); +                continue;              } +        } -            strend(key, '#'); - -            struct UpdateTableItem *item = g_new0(struct UpdateTableItem, 1); -            item->is_iter = TRUE; -            item->iter = gtk_tree_iter_copy(&child); -            gchar *flags, *tag, *name; -            key_get_components(key, &flags, &tag, &name, NULL, NULL, TRUE); +        if (entry->fieldfunc && values[0] && g_str_equal(values[0], "...")) { +            g_free(values[0]); +            values[0] = entry->fieldfunc(key); +        } -            if (flags) { -                gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, name, -                                   INFO_TREE_COL_DATA, flags, -1); -                g_hash_table_insert(update_tbl, tag, item); -                g_free(name); -            } else { -                gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, key, -                                   INFO_TREE_COL_DATA, NULL, -1); -                g_hash_table_insert(update_tbl, name, item); -                g_free(tag); -            } -            g_free(flags); +        if (ngroups == 1) { +            gtk_tree_store_append(store, &child, NULL); +        } else { +            gtk_tree_store_append(store, &child, &parent); +        } +        if (vcount > 0) +            gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, +                               values[0], -1); +        if (vcount > 1) +            gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA1, +                               values[1], -1); +        if (vcount > 2) +            gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA2, +                               values[2], -1); + +        struct UpdateTableItem *item = g_new0(struct UpdateTableItem, 1); +        item->is_iter = TRUE; +        item->iter = gtk_tree_iter_copy(&child); +        gchar *flags, *tag, *name; +        key_get_components(key, &flags, &tag, &name, NULL, NULL, TRUE); + +        if (flags) { +            gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, name, +                               INFO_TREE_COL_DATA, flags, -1); +            g_hash_table_insert(update_tbl, tag, item); +            g_free(name); +        } else { +            gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, key, +                               INFO_TREE_COL_DATA, NULL, -1); +            g_hash_table_insert(update_tbl, name, item); +            g_free(tag);          } +        g_free(flags); -        g_free(value); +        g_strfreev(values);      }  } @@ -1564,7 +1562,7 @@ static void module_selected_show_info_detail(GKeyFile *key_file,                  gchar *name, *label, *tag;                  key_get_components(keys[j], NULL, &tag, &name, &label, NULL, TRUE); -                value = g_key_file_get_value(key_file, groups[i], keys[j], NULL); +                value = g_key_file_get_string(key_file, groups[i], keys[j], NULL);                  if (entry && entry->fieldfunc && value && g_str_equal(value, "...")) {                      g_free(value);  | 
