[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_object_table[] |
Date: |
Thu, 26 Jul 2012 14:52:04 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.0.97 (gnu/linux) |
Luiz Capitulino <address@hidden> writes:
> 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 == '_');
> +}
Depends on locale, which may not be what you want.
Beware of passing negative arguments to ctype.h functions.
> +
> +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;
> +}
Suggest something like
static char *get_key(const char *str)
{
char *beg, *end;
for (beg = str; !iscchar(*beg); beg++) ;
for (end = beg; iscchar(*end); end++) ;
return g_strndup(beg, end - beg);
}
> +
> +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;
> +}
Likewise.
> +
> +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
colon is either empty or ', ', but never a colon. What about calling it
sep, for separator?
> +
> +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()
- [Qemu-devel] [PATCH 02/14] qerror: reduce public exposure, (continued)
- [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, 2012/07/25
- Re: [Qemu-devel] [PATCH 08/14] qerror: add build_error_dict() and error_object_table[],
Markus Armbruster <=
- [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