[gnome-builder/wip/chergert/debugger: 23/100] mi2: use gvariant to parse protocol data from gdb
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/debugger: 23/100] mi2: use gvariant to parse protocol data from gdb
- Date: Fri, 14 Apr 2017 21:33:25 +0000 (UTC)
commit 15d0c11b7b1448e170fcc91186bfe03152ee5f8b
Author: Christian Hergert <chergert redhat com>
Date: Thu Mar 23 21:46:49 2017 -0700
mi2: use gvariant to parse protocol data from gdb
contrib/mi2/mi2-message.c | 57 ++++++++++++++-
contrib/mi2/mi2-message.h | 5 ++
contrib/mi2/mi2-reply-message.c | 40 +++++++++-
contrib/mi2/mi2-util.c | 150 ++++++++++++++++++++++++++++++++++++++-
contrib/mi2/mi2-util.h | 12 ++-
5 files changed, 249 insertions(+), 15 deletions(-)
---
diff --git a/contrib/mi2/mi2-message.c b/contrib/mi2/mi2-message.c
index 5d3ac0c..4c9c3b2 100644
--- a/contrib/mi2/mi2-message.c
+++ b/contrib/mi2/mi2-message.c
@@ -33,6 +33,12 @@ typedef struct
G_DEFINE_TYPE_WITH_PRIVATE (Mi2Message, mi2_message, G_TYPE_OBJECT)
+static GHashTable *
+make_hashtable (void)
+{
+ return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
+}
+
static void
mi2_message_finalize (GObject *object)
{
@@ -128,13 +134,14 @@ mi2_message_get_param_string (Mi2Message *self,
const gchar *name)
{
Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
+ GVariant *variant = NULL;
g_return_val_if_fail (MI2_IS_MESSAGE (self), NULL);
if (priv->params != NULL)
- return g_hash_table_lookup (priv->params, name);
+ variant = g_hash_table_lookup (priv->params, name);
- return NULL;
+ return variant == NULL ? NULL : g_variant_get_string (variant, NULL);
}
void
@@ -148,8 +155,50 @@ mi2_message_set_param_string (Mi2Message *self,
g_return_if_fail (name != NULL);
if (priv->params == NULL)
- priv->params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_insert (priv->params, g_strdup (name), g_strdup (value));
+ priv->params = make_hashtable ();
+
+ if (value == NULL)
+ g_hash_table_remove (priv->params, name);
+ else
+ g_hash_table_insert (priv->params,
+ g_strdup (name),
+ g_variant_ref_sink (g_variant_new_string (value)));
+}
+
+GVariant *
+mi2_message_get_param (Mi2Message *self,
+ const gchar *param)
+{
+ Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
+
+ g_return_val_if_fail (MI2_IS_MESSAGE (self), NULL);
+ g_return_val_if_fail (param != NULL, NULL);
+
+ if (priv->params)
+ return g_hash_table_lookup (priv->params, param);
+
+ return NULL;
+}
+
+void
+mi2_message_set_param (Mi2Message *self,
+ const gchar *param,
+ GVariant *variant)
+{
+ Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
+
+ g_return_if_fail (MI2_IS_MESSAGE (self));
+ g_return_if_fail (param != NULL);
+
+ if (priv->params == NULL)
+ priv->params = make_hashtable ();
+
+ if (variant == NULL)
+ g_hash_table_remove (priv->params, param);
+ else
+ g_hash_table_insert (priv->params,
+ g_strdup (param),
+ g_variant_ref_sink (variant));
}
/**
diff --git a/contrib/mi2/mi2-message.h b/contrib/mi2/mi2-message.h
index 261e866..dece0b7 100644
--- a/contrib/mi2/mi2-message.h
+++ b/contrib/mi2/mi2-message.h
@@ -48,6 +48,11 @@ Mi2Message *mi2_message_parse (const gchar *line,
GError **error);
GBytes *mi2_message_serialize (Mi2Message *self);
const gchar **mi2_message_get_params (Mi2Message *self);
+GVariant *mi2_message_get_param (Mi2Message *self,
+ const gchar *param);
+void mi2_message_set_param (Mi2Message *self,
+ const gchar *param,
+ GVariant *variant);
const gchar *mi2_message_get_param_string (Mi2Message *self,
const gchar *name);
void mi2_message_set_param_string (Mi2Message *self,
diff --git a/contrib/mi2/mi2-reply-message.c b/contrib/mi2/mi2-reply-message.c
index d941bdd..cb5209c 100644
--- a/contrib/mi2/mi2-reply-message.c
+++ b/contrib/mi2/mi2-reply-message.c
@@ -130,13 +130,45 @@ mi2_reply_message_new_from_string (const gchar *line)
while (line != NULL && *line != '\0')
{
g_autofree gchar *key = NULL;
- g_autofree gchar *value = NULL;
- if (!(key = mi2_util_parse_word (line, &line)) ||
- !(value = mi2_util_parse_string (line, &line)))
+ if (*line == ',')
+ line++;
+
+ key = mi2_util_parse_word (line, &line);
+ if (key == NULL)
break;
- mi2_message_set_param_string (MI2_MESSAGE (ret), key, value);
+ if (*line == '=')
+ line++;
+
+ if (*line == '"')
+ {
+ g_autofree gchar *value = NULL;
+
+ value = mi2_util_parse_string (line, &line);
+ mi2_message_set_param_string (MI2_MESSAGE (ret), key, value);
+ continue;
+ }
+ else if (*line == '{')
+ {
+ g_autoptr(GVariant) variant = NULL;
+
+ variant = mi2_util_parse_record (line, &line);
+ mi2_message_set_param (MI2_MESSAGE (ret), key, variant);
+ continue;
+ }
+ else if (*line == '[')
+ {
+ g_autoptr(GVariant) variant = NULL;
+
+ variant = mi2_util_parse_list (line, &line);
+ mi2_message_set_param (MI2_MESSAGE (ret), key, variant);
+ continue;
+ }
+
+ g_warning ("Failed to parse: %s\n", line);
+
+ break;
}
}
diff --git a/contrib/mi2/mi2-util.c b/contrib/mi2/mi2-util.c
index a279784..f5cefc6 100644
--- a/contrib/mi2/mi2-util.c
+++ b/contrib/mi2/mi2-util.c
@@ -101,11 +101,155 @@ mi2_util_parse_word (const gchar *line,
ret = g_strndup (begin, line - begin);
- if (*line)
- line++;
-
if (endptr)
*endptr = line;
return ret;
}
+
+GVariant *
+mi2_util_parse_record (const gchar *line,
+ const gchar **endptr)
+{
+ GVariantDict dict;
+
+ g_return_val_if_fail (line != NULL, NULL);
+ g_return_val_if_fail (*line == '{', NULL);
+
+ g_variant_dict_init (&dict, NULL);
+
+ /* move past { */
+ line++;
+
+ while (*line != '}')
+ {
+ g_autofree gchar *key = NULL;
+
+ if (*line == ',')
+ line++;
+
+ if (!(key = mi2_util_parse_word (line, &line)))
+ goto failure;
+
+ if (*line == '=')
+ line++;
+
+ if (*line == '"')
+ {
+ g_autofree gchar *value = NULL;
+
+ if (!(value = mi2_util_parse_string (line, &line)))
+ goto failure;
+
+ g_variant_dict_insert (&dict, key, "s", value);
+ }
+ else if (*line == '{')
+ {
+ g_autoptr(GVariant) v = NULL;
+
+ if (!(v = mi2_util_parse_record (line, &line)))
+ goto failure;
+
+ g_variant_dict_insert_value (&dict, key, v);
+ }
+ else if (*line == '[')
+ {
+ g_autoptr(GVariant) ar = NULL;
+
+ if (!(ar = mi2_util_parse_list (line, &line)))
+ goto failure;
+
+ g_variant_dict_insert_value (&dict, key, ar);
+ }
+ else
+ goto failure;
+
+ if (*line == ',')
+ line++;
+ }
+
+ g_assert (*line == '}');
+
+ line++;
+
+ if (endptr)
+ *endptr = line;
+
+ return g_variant_ref_sink (g_variant_dict_end (&dict));
+
+failure:
+ g_variant_dict_clear (&dict);
+ if (endptr)
+ *endptr = NULL;
+ return NULL;
+}
+
+GVariant *
+mi2_util_parse_list (const gchar *line,
+ const gchar **endptr)
+{
+ GVariantBuilder builder;
+
+ g_return_val_if_fail (line != NULL, NULL);
+ g_return_val_if_fail (*line == '[', NULL);
+
+ /* move past [ */
+ line++;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("v"));
+
+ while (*line != ']')
+ {
+ if (*line == '"')
+ {
+ g_autofree gchar *value = NULL;
+
+ if (!(value = mi2_util_parse_string (line, &line)))
+ goto failure;
+
+ g_variant_builder_add (&builder, "s", value);
+ }
+ else if (*line == '{')
+ {
+ g_autoptr(GVariant) v = NULL;
+
+ if (!(v = mi2_util_parse_record (line, &line)))
+ goto failure;
+
+ g_variant_builder_add_value (&builder, v);
+ }
+ else if (*line == '[')
+ {
+ g_autoptr(GVariant) ar = NULL;
+
+ if (!(ar = mi2_util_parse_list (line, &line)))
+ goto failure;
+
+ g_variant_builder_add_value (&builder, ar);
+ }
+ else
+ goto failure;
+
+
+ if (*line == ',')
+ line++;
+ }
+
+ g_assert (*line == ']');
+
+ line++;
+
+ if (endptr)
+ *endptr = line;
+
+ g_variant_builder_close (&builder);
+
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+
+failure:
+ g_variant_builder_clear (&builder);
+ if (endptr)
+ *endptr = NULL;
+ return NULL;
+}
diff --git a/contrib/mi2/mi2-util.h b/contrib/mi2/mi2-util.h
index da32968..e4bd582 100644
--- a/contrib/mi2/mi2-util.h
+++ b/contrib/mi2/mi2-util.h
@@ -23,10 +23,14 @@
G_BEGIN_DECLS
-gchar *mi2_util_parse_string (const gchar *line,
- const gchar **endptr);
-gchar *mi2_util_parse_word (const gchar *line,
- const gchar **endptr);
+gchar *mi2_util_parse_string (const gchar *line,
+ const gchar **endptr);
+gchar *mi2_util_parse_word (const gchar *line,
+ const gchar **endptr);
+GVariant *mi2_util_parse_record (const gchar *line,
+ const gchar **endptr);
+GVariant *mi2_util_parse_list (const gchar *line,
+ const gchar **endptr);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]