diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | hardinfo/gg_strescape.c | 138 | ||||
-rw-r--r-- | hardinfo/info.c | 9 | ||||
-rw-r--r-- | includes/hardinfo.h | 7 | ||||
-rw-r--r-- | includes/shell.h | 5 | ||||
-rw-r--r-- | shell/shell.c | 30 |
6 files changed, 184 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 657d3106..3b9af705 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,6 +281,7 @@ add_executable(hardinfo hardinfo/socket.c hardinfo/util.c hardinfo/gg_key_file_parse_string_as_value.c + hardinfo/gg_strescape.c hardinfo/problem_marker.c hardinfo/hinote_util.c hardinfo/vendor.c @@ -320,6 +321,7 @@ add_executable(hardinfo hardinfo/socket.c hardinfo/util.c hardinfo/gg_key_file_parse_string_as_value.c + hardinfo/gg_strescape.c hardinfo/problem_marker.c hardinfo/hinote_util.c hardinfo/vendor.c diff --git a/hardinfo/gg_strescape.c b/hardinfo/gg_strescape.c new file mode 100644 index 00000000..ada9cf89 --- /dev/null +++ b/hardinfo/gg_strescape.c @@ -0,0 +1,138 @@ +/* Base on: GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <glib.h> + +guchar excmap_def[256] = {1,0}; +static void make_excmap_def() { + int i; + for(i=0; i<256; i++){ + switch ((guchar)i) + { + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + case '\\': + case '"': + excmap_def[i] = 0; + break; + default: + if ((i < ' ') || (i >= 0177)) + excmap_def[i] = 0; + else + excmap_def[i] = 1; + break; + } + } +} + +gchar * +gg_strescape (const gchar *source, + const gchar *exceptions, + const gchar *extra) +{ + const guchar *p; + gchar *dest; + gchar *q; + guchar excmap[256]; + + g_return_val_if_fail (source != NULL, NULL); + + if (excmap_def[0]) /* [0] should be 0 or it isn't initialized */ + make_excmap_def(); + + memcpy(excmap, excmap_def, 256); + + p = (guchar *) source; + /* Each source byte needs maximally four destination chars (\777) */ + q = dest = g_malloc (strlen (source) * 4 + 1); + + if (exceptions) + { + guchar *e = (guchar *) exceptions; + + while (*e) + { + excmap[*e] = 1; + e++; + } + } + + if (extra) + { + guchar *e = (guchar *) extra; + + while (*e) + { + excmap[*e] = 0; + e++; + } + } + + while (*p) + { + if (excmap[*p]) + *q++ = *p; + else + { + switch (*p) + { + case '\b': + *q++ = '\\'; + *q++ = 'b'; + break; + case '\f': + *q++ = '\\'; + *q++ = 'f'; + break; + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + case '\\': + *q++ = '\\'; + *q++ = '\\'; + break; + case '"': + *q++ = '\\'; + *q++ = '"'; + break; + default: + *q++ = '\\'; + *q++ = '0' + (((*p) >> 6) & 07); + *q++ = '0' + (((*p) >> 3) & 07); + *q++ = '0' + ((*p) & 07); + break; + } + } + p++; + } + *q = 0; + return dest; +} diff --git a/hardinfo/info.c b/hardinfo/info.c index 2d1d4159..5dd33b9c 100644 --- a/hardinfo/info.c +++ b/hardinfo/info.c @@ -496,8 +496,8 @@ struct Info *info_unflatten(const gchar *str) for (k = 0; keys[k]; k++) { struct InfoField field = {}; - gchar *flags, *tag, *name; - key_get_components(keys[k], &flags, &tag, &name, NULL, NULL, TRUE); + gchar *flags, *tag, *name, *label, *dis; + key_get_components(keys[k], &flags, &tag, &name, &label, &dis, TRUE); gchar *value = g_key_file_get_value(key_file, group_name, keys[k], NULL); field.tag = tag; @@ -511,8 +511,13 @@ struct Info *info_unflatten(const gchar *str) field.highlight = TRUE; if (key_value_has_vendor_string(flags)) field.value_has_vendor = TRUE; + if (key_label_is_escaped(flags)) { + //TODO:... + } g_free(flags); + g_free(label); + g_free(dis); g_array_append_val(group.fields, field); } g_array_append_val(info->groups, group); diff --git a/includes/hardinfo.h b/includes/hardinfo.h index 19eb88fb..010af922 100644 --- a/includes/hardinfo.h +++ b/includes/hardinfo.h @@ -213,6 +213,13 @@ gboolean hardinfo_spawn_command_line_sync(const gchar *command_line, /* a marker in text to point out problems, using markup where possible */ const char *problem_marker(); +/* a version of g_strescape() that allows escaping extra characters. + * use with g_strcompress() as normal. */ +gchar * +gg_strescape (const gchar *source, + const gchar *exceptions, + const gchar *extra); + /* hinote helpers */ #define note_max_len 512 #define note_printf(note_buff, fmt, ...) \ diff --git a/includes/shell.h b/includes/shell.h index b70b963e..927a9adf 100644 --- a/includes/shell.h +++ b/includes/shell.h @@ -227,11 +227,16 @@ void shell_set_remote_label(Shell *shell, gchar *label); * ! = show details (moreinfo) in reports * * = highlight/select this row * ^ = value is/has a vendor string + * @ = label is escaped with key_label_escape() */ gboolean key_is_flagged(const gchar *key); /* has $[<flags>][<tag>]$ at the start of the key */ gboolean key_is_highlighted(const gchar *key); /* flag '*' = select/highlight */ gboolean key_wants_details(const gchar *key); /* flag '!' = report should include the "moreinfo" */ gboolean key_value_has_vendor_string(const gchar *key); /* flag '^' = try and match the value to a vendor */ +#define key_label_escape(LBL) (gg_strescape(LBL, NULL, "=$#")) +gboolean key_label_is_escaped(const gchar *key); /* flag '@' = the label part is key_label_escape()-d and + * needs to be g_strcompress()-ed before use. + * key_get_components() will do this automatically for label. */ gchar *key_mi_tag(const gchar *key); /* moreinfo lookup tag */ const gchar *key_get_name(const gchar *key); /* get the key's name, flagged or not */ /* diff --git a/shell/shell.c b/shell/shell.c index 09a86dae..c0fc011e 100644 --- a/shell/shell.c +++ b/shell/shell.c @@ -1319,14 +1319,16 @@ static void group_handle_normal(GKeyFile *key_file, 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); + gchar *flags, *tag, *name, *label; + key_get_components(key, &flags, &tag, &name, &label, NULL, TRUE); if (flags) { - gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, name, + //TODO: name was formerly used where label is here. Check all uses + //for problems. + gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, label, INFO_TREE_COL_DATA, flags, -1); g_hash_table_insert(update_tbl, tag, item); - g_free(name); + g_free(label); } else { gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, key, INFO_TREE_COL_DATA, NULL, -1); @@ -2255,8 +2257,18 @@ gboolean key_value_has_vendor_string(const gchar *key) { return FALSE; } +gboolean key_label_is_escaped(const gchar *key) { + gchar *flags; + key_get_components(key, &flags, NULL, NULL, NULL, NULL, TRUE); + if (flags && strchr(flags, '@')) { + g_free(flags); + return TRUE; + } + return FALSE; +} + gchar *key_mi_tag(const gchar *key) { - static char flag_list[] = "*!^"; + static char flag_list[] = "*!^@"; gchar *p = (gchar*)key, *l, *t; if (key_is_flagged(key)) { @@ -2328,5 +2340,13 @@ void key_get_components(const gchar *key, *lbp = 0; if (lbp && dis) *dis = g_strdup(lbp + 1); + + if (flags && *flags && strchr(*flags, '@')) { + printf("flag@: %s\n", *label); + gchar *ol = *label; + *label = g_strcompress(ol); + g_free(ol); + printf("..... %s\n", *label); + } } } |