[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_obje
From: |
Luiz Capitulino |
Subject: |
[Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_object_table[] |
Date: |
Wed, 25 Jul 2012 17:50:25 -0300 |
In the near future, the QERR_ macros (which are json strings today) will
be turned into an enumeration. When we get there, build_error_dict()
will be used to (guess what) build an error dict by:
1. Using the error class as an index to error_object_table[], which
contains all QMP errors as json strings (with default values)
2. Use the human error string to construct the error object data member.
For example, an error message like:
"Parameter name=brain has not been found"
Will construct the following data member:
'data': { 'name': 'brain' } }
Signed-off-by: Luiz Capitulino <address@hidden>
---
qerror.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++
qerror.h | 1 +
scripts/qapi-errors.py | 39 +++++++++++++++++++++++
3 files changed, 126 insertions(+)
diff --git a/qerror.c b/qerror.c
index 42e8687..267545e 100644
--- a/qerror.c
+++ b/qerror.c
@@ -38,6 +38,92 @@ static QError *qerror_new(void)
return qerr;
}
+static bool iscchar(int c)
+{
+ return (isalpha(c) || isdigit(c) || c == '_');
+}
+
+static char *get_key(const char *str)
+{
+ char *p, *ret;
+
+ ret = p = g_strdup(str);
+
+ while (!iscchar(*p)) {
+ p++;
+ }
+ memmove(ret, p, strlen(ret));
+
+ p = ret;
+ while (iscchar(*p)) {
+ p++;
+ }
+ *p = '\0';
+
+ return ret;
+}
+
+static char *get_value(const char *str)
+{
+ char *p, *ret;
+
+ p = strchr(str, '=');
+ while (!iscchar(*p)) {
+ p++;
+ }
+ p = ret = g_strdup(p);
+ while (iscchar(*p)) {
+ p++;
+ }
+ *p = '\0';
+
+ return ret;
+}
+
+static void set_dict_data(const char *msg, QDict *data_dict)
+{
+ char *str, *msg2, *saveptr = NULL;
+
+ msg2 = g_strdup(msg);
+ str = strtok_r(msg2, " ", &saveptr);
+ while (str) {
+ if (strchr(str, '=')) {
+ char *key = get_key(str);
+ char *value = get_value(str);
+
+ /* FIXME: handle ints */
+ if (qdict_haskey(data_dict, key)) {
+ qdict_put(data_dict, key, qstring_from_str(value));
+ }
+
+ g_free(key);
+ g_free(value);
+ }
+ str = strtok_r(NULL, " ", &saveptr);
+ }
+
+ g_free(msg2);
+}
+
+QDict *build_error_dict(int err_class, const char *msg)
+{
+ QDict *err_dict;
+ QObject *obj;
+
+ assert(msg[0] != '\0');
+
+ obj = qobject_from_json(error_object_table[err_class]);
+ assert(obj);
+ assert(qobject_type(obj) == QTYPE_QDICT);
+
+ err_dict = qobject_to_qdict(obj);
+ assert(qdict_haskey(err_dict, "data"));
+
+ set_dict_data(msg, qdict_get_qdict(err_dict, "data"));
+
+ return err_dict;
+}
+
static QDict *error_object_from_fmt(const char *fmt, va_list *va)
{
QObject *obj;
diff --git a/qerror.h b/qerror.h
index 16401ff..c4f6053 100644
--- a/qerror.h
+++ b/qerror.h
@@ -36,5 +36,6 @@ void qerror_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void qerror_report_err(Error *err);
void assert_no_error(Error *err);
char *qerror_format(const char *fmt, QDict *error);
+QDict *build_error_dict(int err_class, const char *msg);
#endif /* QERROR_H */
diff --git a/scripts/qapi-errors.py b/scripts/qapi-errors.py
index 59cf426..5f8723e 100644
--- a/scripts/qapi-errors.py
+++ b/scripts/qapi-errors.py
@@ -85,6 +85,42 @@ static const QErrorStringTable qerror_table[] = {
return ret
+def gen_error_data_obj(data):
+ colon = ''
+ data_str = ''
+ for k, v in data.items():
+ data_str += colon + "'%s': " % k
+ if v == 'str':
+ data_str += "'unknown'"
+ elif v == 'int':
+ data_str += '0'
+ else:
+ sys.exit("unknown data type '%s' for error '%s'" % (v, name))
+ colon = ', '
+ return data_str
+
+def gen_error_obj_table(exprs):
+ ret = mcgen('''
+static const char *error_object_table[] = {
+''')
+
+ for err in exprs:
+ data = gen_error_data_obj({})
+ if err.has_key('data'):
+ data = gen_error_data_obj(err['data'])
+ ret += mcgen('''
+ "{ 'class': '%(error_class)s', 'data': { %(error_data)s } }",
+''',
+ error_class=err['error'], error_data=data)
+
+ ret += mcgen('''
+ NULL,
+};
+
+''')
+
+ return ret;
+
def gen_error_macro_data_str(data):
colon = ''
data_str = ''
@@ -173,5 +209,8 @@ if __name__ == '__main__':
ret = gen_error_def_table(exprs)
fdef.write(ret)
+ ret = gen_error_obj_table(exprs)
+ fdef.write(ret)
+
fdef.flush()
fdef.close()
--
1.7.11.2.249.g31c7954.dirty
- [Qemu-devel] [PATCH 01/14] monitor: drop unused monitor debug code, (continued)
- [Qemu-devel] [PATCH 01/14] monitor: drop unused monitor debug code, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 02/14] qerror: reduce public exposure, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 03/14] qerror: drop qerror_abort(), Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 04/14] qerror: drop qerror_report_internal(), Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 05/14] qerror: qerror_format(): return an allocated string, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 06/14] qerror: don't delay error message construction, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 07/14] error: don't delay error message construction, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_object_table[],
Luiz Capitulino <=
- [Qemu-devel] [PATCH 09/14] qerror: qerror_report(): take an index and a human error message, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 11/14] qerror: drop qerror_table[] for good, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 12/14] error: turn QERR_ macros into an enumeration, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 13/14] qerror: change all qerror_report() calls to use the ErrClass enum, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 10/14] error: error_set(): take an index and a human error message, Luiz Capitulino, 2012/07/25
- [Qemu-devel] [PATCH 14/14] error: change all error_set() calls to use the ErrClass enum, Luiz Capitulino, 2012/07/25
- Re: [Qemu-devel] [RFC 00/14]: add printf-like human msg to error_set(), Anthony Liguori, 2012/07/25