[gnome-builder/wip/chergert/debugger: 15/46] mi2: implement command and replies
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/debugger: 15/46] mi2: implement command and replies
- Date: Sun, 26 Mar 2017 00:07:05 +0000 (UTC)
commit 5c765ecbb0440bd263da71704f3856c775edff25
Author: Christian Hergert <chergert redhat com>
Date: Thu Mar 23 18:08:23 2017 -0700
mi2: implement command and replies
contrib/mi2/Makefile.am | 4 +
contrib/mi2/mi2-client.c | 41 ++++++++-
contrib/mi2/mi2-command-message.c | 28 ++++++
contrib/mi2/mi2-error.c | 25 +++++
contrib/mi2/mi2-error.h | 38 ++++++++
contrib/mi2/mi2-event-message.c | 44 +---------
contrib/mi2/mi2-event-message.h | 14 +--
contrib/mi2/mi2-message.c | 101 ++++++++++++--------
contrib/mi2/mi2-message.h | 14 ++-
contrib/mi2/mi2-reply-message.c | 188 +++++++++++++++++++++++++++++++++++++
contrib/mi2/mi2-reply-message.h | 39 ++++++++
contrib/mi2/test-client.c | 29 ++++++-
12 files changed, 463 insertions(+), 102 deletions(-)
---
diff --git a/contrib/mi2/Makefile.am b/contrib/mi2/Makefile.am
index 059878f..c7e3b3b 100644
--- a/contrib/mi2/Makefile.am
+++ b/contrib/mi2/Makefile.am
@@ -17,12 +17,16 @@ libmi2_glib_la_public_sources = \
mi2-console-message.h \
mi2-event-message.c \
mi2-event-message.h \
+ mi2-error.c \
+ mi2-error.h \
mi2-info-message.c \
mi2-info-message.h \
mi2-input-stream.c \
mi2-input-stream.h \
mi2-message.c \
mi2-message.h \
+ mi2-reply-message.c \
+ mi2-reply-message.h \
mi2-output-stream.c \
mi2-output-stream.h \
mi2-util.c \
diff --git a/contrib/mi2/mi2-client.c b/contrib/mi2/mi2-client.c
index b6a69c5..184fe6a 100644
--- a/contrib/mi2/mi2-client.c
+++ b/contrib/mi2/mi2-client.c
@@ -21,9 +21,11 @@
#include "mi2-client.h"
#include "mi2-command-message.h"
#include "mi2-console-message.h"
+#include "mi2-error.h"
#include "mi2-event-message.h"
#include "mi2-input-stream.h"
#include "mi2-output-stream.h"
+#include "mi2-reply-message.h"
typedef struct
{
@@ -31,8 +33,9 @@ typedef struct
Mi2InputStream *input_stream;
Mi2OutputStream *output_stream;
GCancellable *read_loop_cancellable;
+ GTask *current_exec;
- guint is_listening : 1;
+ guint is_listening : 1;
} Mi2ClientPrivate;
enum {
@@ -204,8 +207,13 @@ mi2_client_exec_write_message_cb (GObject *object,
if (!mi2_output_stream_write_message_finish (stream, result, &error))
g_task_return_error (task, g_steal_pointer (&error));
- else
- g_task_return_boolean (task, TRUE);
+
+ /*
+ * Do not successfully complete request here.
+ *
+ * Successful completion of the task must come from a reply
+ * sent to us by the peer looking something like ^running.
+ */
}
void
@@ -232,10 +240,21 @@ mi2_client_exec_async (Mi2Client *self,
return;
}
+ if (priv->current_exec != NULL)
+ {
+ g_task_return_new_error (task,
+ MI2_ERROR,
+ MI2_ERROR_EXEC_PENDING,
+ "An operation is already pending");
+ return;
+ }
+
message = g_object_new (MI2_TYPE_COMMAND_MESSAGE,
"command", command,
NULL);
+ priv->current_exec = g_object_ref (task);
+
mi2_output_stream_write_message_async (priv->output_stream,
message,
cancellable,
@@ -258,6 +277,8 @@ static void
mi2_client_dispatch (Mi2Client *self,
Mi2Message *message)
{
+ Mi2ClientPrivate *priv = mi2_client_get_instance_private (self);
+
g_return_if_fail (MI2_IS_CLIENT (self));
g_return_if_fail (MI2_IS_MESSAGE (message));
@@ -275,6 +296,20 @@ mi2_client_dispatch (Mi2Client *self,
g_signal_emit (self, signals [EVENT], detail, message);
}
+ else if (MI2_IS_REPLY_MESSAGE (message))
+ {
+ g_autoptr(GTask) task = g_steal_pointer (&priv->current_exec);
+
+ if (task != NULL)
+ {
+ g_autoptr(GError) error = NULL;
+
+ if (mi2_reply_message_check_error (MI2_REPLY_MESSAGE (message), &error))
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_boolean (task, TRUE);
+ }
+ }
else
g_print ("Got message of type %s\n", G_OBJECT_TYPE_NAME (message));
}
diff --git a/contrib/mi2/mi2-command-message.c b/contrib/mi2/mi2-command-message.c
index 2f01ce9..25b73cd 100644
--- a/contrib/mi2/mi2-command-message.c
+++ b/contrib/mi2/mi2-command-message.c
@@ -39,6 +39,31 @@ G_DEFINE_TYPE (Mi2CommandMessage, mi2_command_message, MI2_TYPE_MESSAGE)
static GParamSpec *properties [N_PROPS];
+static GBytes *
+mi2_command_message_serialize (Mi2Message *message)
+{
+ Mi2CommandMessage *self = (Mi2CommandMessage *)message;
+ GString *str;
+
+ g_assert (MI2_IS_COMMAND_MESSAGE (self));
+
+ if (!self->command || !*self->command)
+ return NULL;
+
+ str = g_string_new (NULL);
+
+ if (*self->command == '-')
+ g_string_append (str, self->command);
+ else
+ g_string_append_printf (str, "-%s", self->command);
+
+ /* TODO: Params? */
+
+ g_string_append_c (str, '\n');
+
+ return g_string_free_to_bytes (str);
+}
+
static void
mi2_command_message_finalize (GObject *object)
{
@@ -91,11 +116,14 @@ static void
mi2_command_message_class_init (Mi2CommandMessageClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ Mi2MessageClass *message_class = MI2_MESSAGE_CLASS (klass);
object_class->finalize = mi2_command_message_finalize;
object_class->get_property = mi2_command_message_get_property;
object_class->set_property = mi2_command_message_set_property;
+ message_class->serialize = mi2_command_message_serialize;
+
properties [PROP_COMMAND] =
g_param_spec_string ("command", NULL, NULL, NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
diff --git a/contrib/mi2/mi2-error.c b/contrib/mi2/mi2-error.c
new file mode 100644
index 0000000..9e81263
--- /dev/null
+++ b/contrib/mi2/mi2-error.c
@@ -0,0 +1,25 @@
+/* mi2-error.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mi2-error.h"
+
+GQuark
+mi2_error_quark (void)
+{
+ return g_quark_from_static_string ("mi2-error-domain");
+}
diff --git a/contrib/mi2/mi2-error.h b/contrib/mi2/mi2-error.h
new file mode 100644
index 0000000..8975fd2
--- /dev/null
+++ b/contrib/mi2/mi2-error.h
@@ -0,0 +1,38 @@
+/* mi2-error.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MI2_ERROR_H
+#define MI2_ERROR_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define MI2_ERROR (mi2_error_quark())
+
+typedef enum
+{
+ MI2_ERROR_UNKNOWN_ERROR,
+ MI2_ERROR_EXEC_PENDING,
+} Mi2Error;
+
+GQuark mi2_error_quark (void);
+
+G_END_DECLS
+
+#endif /* MI2_ERROR_H */
diff --git a/contrib/mi2/mi2-event-message.c b/contrib/mi2/mi2-event-message.c
index a074df1..e909a4a 100644
--- a/contrib/mi2/mi2-event-message.c
+++ b/contrib/mi2/mi2-event-message.c
@@ -24,9 +24,7 @@
struct _Mi2EventMessage
{
Mi2Message parent_instance;
-
gchar *name;
- GHashTable *params;
};
enum {
@@ -45,7 +43,6 @@ mi2_event_mesage_finalize (GObject *object)
Mi2EventMessage *self = (Mi2EventMessage *)object;
g_clear_pointer (&self->name, g_free);
- g_clear_pointer (&self->params, g_hash_table_unref);
G_OBJECT_CLASS (mi2_event_mesage_parent_class)->finalize (object);
}
@@ -110,7 +107,6 @@ mi2_event_mesage_class_init (Mi2EventMessageClass *klass)
static void
mi2_event_mesage_init (Mi2EventMessage *self)
{
- self->params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}
/**
@@ -139,7 +135,7 @@ mi2_event_message_new_from_string (const gchar *line)
!(value = mi2_util_parse_string (line, &line)))
break;
- g_hash_table_insert (ret->params, g_steal_pointer (&key), g_steal_pointer (&value));
+ mi2_message_set_param_string (MI2_MESSAGE (ret), key, value);
}
}
@@ -165,41 +161,3 @@ mi2_event_message_set_name (Mi2EventMessage *self,
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NAME]);
}
}
-
-const gchar *
-mi2_event_message_get_param_string (Mi2EventMessage *self,
- const gchar *name)
-{
- g_return_val_if_fail (MI2_IS_EVENT_MESSAGE (self), NULL);
-
- return g_hash_table_lookup (self->params, name);
-}
-
-void
-mi2_event_message_set_param_string (Mi2EventMessage *self,
- const gchar *name,
- const gchar *value)
-{
- g_return_if_fail (MI2_IS_EVENT_MESSAGE (self));
- g_return_if_fail (name != NULL);
-
- g_hash_table_insert (self->params, g_strdup (name), g_strdup (value));
-}
-
-/**
- * mi2_event_message_get_params:
- * @self: An #Mi2EventMessage
- *
- * Gets the keys for params that are stored in the message, free the
- * result with g_free() as ownership of the fields is owned by the
- * #Mi2EventMessage.
- *
- * Returns: (transfer container): A %NULL-terminated array of param names.
- */
-const gchar **
-mi2_event_message_get_params (Mi2EventMessage *self)
-{
- g_return_val_if_fail (MI2_IS_EVENT_MESSAGE (self), NULL);
-
- return (const gchar **)g_hash_table_get_keys_as_array (self->params, NULL);
-}
diff --git a/contrib/mi2/mi2-event-message.h b/contrib/mi2/mi2-event-message.h
index 8edd7e6..a9b62f5 100644
--- a/contrib/mi2/mi2-event-message.h
+++ b/contrib/mi2/mi2-event-message.h
@@ -27,16 +27,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (Mi2EventMessage, mi2_event_mesage, MI2, EVENT_MESSAGE, Mi2Message)
-Mi2Message *mi2_event_message_new_from_string (const gchar *line);
-const gchar *mi2_event_message_get_name (Mi2EventMessage *self);
-void mi2_event_message_set_name (Mi2EventMessage *self,
- const gchar *name);
-const gchar **mi2_event_message_get_params (Mi2EventMessage *self);
-const gchar *mi2_event_message_get_param_string (Mi2EventMessage *self,
- const gchar *name);
-void mi2_event_message_set_param_string (Mi2EventMessage *self,
- const gchar *name,
- const gchar *value);
+Mi2Message *mi2_event_message_new_from_string (const gchar *line);
+const gchar *mi2_event_message_get_name (Mi2EventMessage *self);
+void mi2_event_message_set_name (Mi2EventMessage *self,
+ const gchar *name);
G_END_DECLS
diff --git a/contrib/mi2/mi2-message.c b/contrib/mi2/mi2-message.c
index 3485674..5d3ac0c 100644
--- a/contrib/mi2/mi2-message.c
+++ b/contrib/mi2/mi2-message.c
@@ -24,58 +24,24 @@
#include "mi2-console-message.h"
#include "mi2-event-message.h"
#include "mi2-info-message.h"
+#include "mi2-reply-message.h"
typedef struct
{
- gpointer dummy;
+ GHashTable *params;
} Mi2MessagePrivate;
-enum {
- PROP_0,
- N_PROPS
-};
-
G_DEFINE_TYPE_WITH_PRIVATE (Mi2Message, mi2_message, G_TYPE_OBJECT)
-static GParamSpec *properties [N_PROPS];
-
static void
mi2_message_finalize (GObject *object)
{
Mi2Message *self = (Mi2Message *)object;
Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
- G_OBJECT_CLASS (mi2_message_parent_class)->finalize (object);
-}
-
-static void
-mi2_message_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- Mi2Message *self = MI2_MESSAGE (object);
+ g_clear_pointer (&priv->params, g_hash_table_unref);
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-mi2_message_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- Mi2Message *self = MI2_MESSAGE (object);
-
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ G_OBJECT_CLASS (mi2_message_parent_class)->finalize (object);
}
static void
@@ -84,8 +50,6 @@ mi2_message_class_init (Mi2MessageClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = mi2_message_finalize;
- object_class->get_property = mi2_message_get_property;
- object_class->set_property = mi2_message_set_property;
}
static void
@@ -123,9 +87,12 @@ mi2_message_parse (const gchar *line,
ret = mi2_info_message_new_from_string (line);
break;
+ case '^':
+ ret = mi2_reply_message_new_from_string (line);
+ break;
+
case '=':
case '*':
- case '^':
ret = mi2_event_message_new_from_string (line);
break;
@@ -155,3 +122,55 @@ mi2_message_serialize (Mi2Message *self)
return MI2_MESSAGE_GET_CLASS (self)->serialize (self);
}
+
+const gchar *
+mi2_message_get_param_string (Mi2Message *self,
+ const gchar *name)
+{
+ Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
+
+ g_return_val_if_fail (MI2_IS_MESSAGE (self), NULL);
+
+ if (priv->params != NULL)
+ return g_hash_table_lookup (priv->params, name);
+
+ return NULL;
+}
+
+void
+mi2_message_set_param_string (Mi2Message *self,
+ const gchar *name,
+ const gchar *value)
+{
+ Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
+
+ g_return_if_fail (MI2_IS_MESSAGE (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));
+}
+
+/**
+ * mi2_message_get_params:
+ * @self: An #Mi2Message
+ *
+ * Gets the keys for params that are stored in the message, free the
+ * result with g_free() as ownership of the fields is owned by the
+ * #Mi2Message.
+ *
+ * Returns: (transfer container): A %NULL-terminated array of param names.
+ */
+const gchar **
+mi2_message_get_params (Mi2Message *self)
+{
+ Mi2MessagePrivate *priv = mi2_message_get_instance_private (self);
+
+ g_return_val_if_fail (MI2_IS_MESSAGE (self), NULL);
+
+ if (priv->params != NULL)
+ return (const gchar **)g_hash_table_get_keys_as_array (priv->params, NULL);
+
+ return (const gchar **)g_new0 (gchar *, 1);
+}
diff --git a/contrib/mi2/mi2-message.h b/contrib/mi2/mi2-message.h
index 68429eb..261e866 100644
--- a/contrib/mi2/mi2-message.h
+++ b/contrib/mi2/mi2-message.h
@@ -43,10 +43,16 @@ struct _Mi2MessageClass
gpointer _reserved8;
};
-Mi2Message *mi2_message_parse (const gchar *line,
- gsize len,
- GError **error);
-GBytes *mi2_message_serialize (Mi2Message *self);
+Mi2Message *mi2_message_parse (const gchar *line,
+ gsize len,
+ GError **error);
+GBytes *mi2_message_serialize (Mi2Message *self);
+const gchar **mi2_message_get_params (Mi2Message *self);
+const gchar *mi2_message_get_param_string (Mi2Message *self,
+ const gchar *name);
+void mi2_message_set_param_string (Mi2Message *self,
+ const gchar *name,
+ const gchar *value);
G_END_DECLS
diff --git a/contrib/mi2/mi2-reply-message.c b/contrib/mi2/mi2-reply-message.c
new file mode 100644
index 0000000..d941bdd
--- /dev/null
+++ b/contrib/mi2/mi2-reply-message.c
@@ -0,0 +1,188 @@
+/* mi2-reply-mesage.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "mi2-reply-message"
+
+#include "mi2-error.h"
+#include "mi2-reply-message.h"
+#include "mi2-util.h"
+
+struct _Mi2ReplyMessage
+{
+ Mi2Message parent_instance;
+ gchar *name;
+};
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ N_PROPS
+};
+
+G_DEFINE_TYPE (Mi2ReplyMessage, mi2_reply_mesage, MI2_TYPE_MESSAGE)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+mi2_reply_mesage_finalize (GObject *object)
+{
+ Mi2ReplyMessage *self = (Mi2ReplyMessage *)object;
+
+ g_clear_pointer (&self->name, g_free);
+
+ G_OBJECT_CLASS (mi2_reply_mesage_parent_class)->finalize (object);
+}
+
+static void
+mi2_reply_mesage_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ Mi2ReplyMessage *self = MI2_REPLY_MESSAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, mi2_reply_message_get_name (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+mi2_reply_mesage_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ Mi2ReplyMessage *self = MI2_REPLY_MESSAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ mi2_reply_message_set_name (self, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+mi2_reply_mesage_class_init (Mi2ReplyMessageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = mi2_reply_mesage_finalize;
+ object_class->get_property = mi2_reply_mesage_get_property;
+ object_class->set_property = mi2_reply_mesage_set_property;
+
+ properties [PROP_NAME] =
+ g_param_spec_string ("name",
+ "Name",
+ "Name",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+mi2_reply_mesage_init (Mi2ReplyMessage *self)
+{
+}
+
+/**
+ * mi2_reply_message_new_from_string:
+ * @line: the string to be parsed
+ *
+ * Returns: (transfer full): An #Mi2Message
+ */
+Mi2Message *
+mi2_reply_message_new_from_string (const gchar *line)
+{
+ Mi2ReplyMessage *ret;
+
+ ret = g_object_new (MI2_TYPE_REPLY_MESSAGE, NULL);
+
+ if (line && *line)
+ {
+ ret->name = mi2_util_parse_word (&line[1], &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)))
+ break;
+
+ mi2_message_set_param_string (MI2_MESSAGE (ret), key, value);
+ }
+ }
+
+ return MI2_MESSAGE (ret);
+}
+
+const gchar *
+mi2_reply_message_get_name (Mi2ReplyMessage *self)
+{
+ g_return_val_if_fail (MI2_IS_REPLY_MESSAGE (self), NULL);
+
+ return self->name;
+}
+
+void
+mi2_reply_message_set_name (Mi2ReplyMessage *self,
+ const gchar *name)
+{
+ if (name != self->name)
+ {
+ g_free (self->name);
+ self->name = g_strdup (name);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NAME]);
+ }
+}
+
+gboolean
+mi2_reply_message_check_error (Mi2ReplyMessage *self,
+ GError **error)
+{
+ g_return_val_if_fail (MI2_IS_REPLY_MESSAGE (self), FALSE);
+
+ if (g_strcmp0 (self->name, "error") == 0)
+ {
+ const gchar *msg = mi2_message_get_param_string (MI2_MESSAGE (self), "msg");
+
+ if (msg == NULL || *msg == '\0')
+ msg = "An unknown error occrred";
+
+ g_set_error_literal (error,
+ MI2_ERROR,
+ MI2_ERROR_UNKNOWN_ERROR,
+ msg);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/contrib/mi2/mi2-reply-message.h b/contrib/mi2/mi2-reply-message.h
new file mode 100644
index 0000000..d5c80e0
--- /dev/null
+++ b/contrib/mi2/mi2-reply-message.h
@@ -0,0 +1,39 @@
+/* mi2-reply-mesage.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MI2_REPLY_MESAGE_H
+#define MI2_REPLY_MESAGE_H
+
+#include "mi2-message.h"
+
+G_BEGIN_DECLS
+
+#define MI2_TYPE_REPLY_MESSAGE (mi2_reply_mesage_get_type())
+
+G_DECLARE_FINAL_TYPE (Mi2ReplyMessage, mi2_reply_mesage, MI2, REPLY_MESSAGE, Mi2Message)
+
+Mi2Message *mi2_reply_message_new_from_string (const gchar *line);
+const gchar *mi2_reply_message_get_name (Mi2ReplyMessage *self);
+void mi2_reply_message_set_name (Mi2ReplyMessage *self,
+ const gchar *name);
+gboolean mi2_reply_message_check_error (Mi2ReplyMessage *self,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* MI2_REPLY_MESAGE_H */
diff --git a/contrib/mi2/test-client.c b/contrib/mi2/test-client.c
index 04c933d..045e578 100644
--- a/contrib/mi2/test-client.c
+++ b/contrib/mi2/test-client.c
@@ -17,6 +17,7 @@
*/
#include "mi2-client.h"
+#include "mi2-error.h"
static GMainLoop *main_loop;
@@ -46,7 +47,7 @@ static void
log_handler (Mi2Client *client,
const gchar *log)
{
- //g_print ("%s", log);
+ g_print ("%s", log);
}
static void
@@ -64,6 +65,26 @@ event (Mi2Client *client,
g_print ("EVENT: %s\n", mi2_event_message_get_name (message));
}
+static void
+stack_info_frame_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ Mi2Client *client = (Mi2Client *)object;
+ g_autoptr(GError) error = NULL;
+ gboolean r;
+
+ g_assert (MI2_IS_CLIENT (client));
+ g_assert (G_IS_ASYNC_RESULT (result));
+
+ r = mi2_client_exec_finish (client, result, &error);
+ g_assert_error (error, MI2_ERROR, MI2_ERROR_UNKNOWN_ERROR);
+ g_assert_cmpstr (error->message, ==, "No registers.");
+ g_assert_cmpint (r, ==, FALSE);
+
+ g_main_loop_quit (main_loop);
+}
+
gint
main (gint argc,
gchar *argv[])
@@ -81,6 +102,12 @@ main (gint argc,
mi2_client_start_listening (client);
+ mi2_client_exec_async (client,
+ "stack-info-frame",
+ NULL,
+ stack_info_frame_cb,
+ NULL);
+
g_main_loop_run (main_loop);
g_main_loop_unref (main_loop);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]