From patchwork Wed Jul 25 20:50:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 173286 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 86E632C0089 for ; Thu, 26 Jul 2012 07:29:52 +1000 (EST) Received: from localhost ([::1]:47659 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Su8Xu-0003uh-M6 for incoming@patchwork.ozlabs.org; Wed, 25 Jul 2012 16:51:02 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50406) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Su8XH-00029J-MR for qemu-devel@nongnu.org; Wed, 25 Jul 2012 16:50:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Su8XG-0004Ng-4c for qemu-devel@nongnu.org; Wed, 25 Jul 2012 16:50:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:19957) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Su8XF-0004Na-SX for qemu-devel@nongnu.org; Wed, 25 Jul 2012 16:50:22 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q6PKoKVr023547 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 25 Jul 2012 16:50:20 -0400 Received: from localhost (ovpn-113-89.phx2.redhat.com [10.3.113.89]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q6PKoJ1k028811; Wed, 25 Jul 2012 16:50:20 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Wed, 25 Jul 2012 17:50:25 -0300 Message-Id: <1343249431-9245-9-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1343249431-9245-1-git-send-email-lcapitulino@redhat.com> References: <1343249431-9245-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: pbonzini@redhat.com, aliguori@us.ibm.com, armbru@redhat.com, afaerber@suse.de, peter.maydell@linaro.org Subject: [Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_object_table[] X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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()