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); |