From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mw0eg-00013l-W2 for qemu-devel@nongnu.org; Thu, 08 Oct 2009 17:36:12 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mw0eZ-0000vh-Rj for qemu-devel@nongnu.org; Thu, 08 Oct 2009 17:36:07 -0400 Received: from [199.232.76.173] (port=34336 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mw0eZ-0000vQ-7D for qemu-devel@nongnu.org; Thu, 08 Oct 2009 17:36:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:5780) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mw0eY-0002xd-HH for qemu-devel@nongnu.org; Thu, 08 Oct 2009 17:36:02 -0400 From: Luiz Capitulino Date: Thu, 8 Oct 2009 18:35:38 -0300 Message-Id: <1255037747-3340-2-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1255037747-3340-1-git-send-email-lcapitulino@redhat.com> References: <1255037747-3340-1-git-send-email-lcapitulino@redhat.com> Subject: [Qemu-devel] [PATCH 01/10] Introduce qmisc module List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com This module provides miscellania QObject functions. Currently it exports qobject_from_fmt(), which is somewhat based on Python's Py_BuildValue() function. It is capable of creating QObjects from a specified string format. For example, to create a QDict with mixed data-types one could do: QObject *obj = qobject_from_fmt("{ s: [ i, s ], s: i }", ... ); Signed-off-by: Luiz Capitulino --- Makefile | 2 +- qmisc.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qmisc.h | 19 +++++ 3 files changed, 242 insertions(+), 1 deletions(-) create mode 100644 qmisc.c create mode 100644 qmisc.h diff --git a/Makefile b/Makefile index d96fb4b..182f176 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,7 @@ obj-y += buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o obj-y += qemu-char.o aio.o net-checksum.o savevm.o obj-y += msmouse.o ps2.o obj-y += qdev.o qdev-properties.o ssi.o -obj-y += qint.o qstring.o qdict.o qlist.o qemu-config.o +obj-y += qint.o qstring.o qdict.o qlist.o qmisc.o qemu-config.o obj-$(CONFIG_BRLAPI) += baum.o obj-$(CONFIG_WIN32) += tap-win32.o diff --git a/qmisc.c b/qmisc.c new file mode 100644 index 0000000..42b6f22 --- /dev/null +++ b/qmisc.c @@ -0,0 +1,222 @@ +/* + * Misc QObject functions. + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ +#include "qmisc.h" +#include "qint.h" +#include "qlist.h" +#include "qdict.h" +#include "qstring.h" +#include "qobject.h" +#include "qemu-common.h" + +/* + * qobject_from_fmt() and related functions are based on the Python's + * Py_BuildValue() and are subject to the Python Software Foundation + * License Version 2. + * + * Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Python + * Software Foundation. + */ +static QObject *build_qobject(const char **fmt, va_list *args); + +static QObject *do_mkdict(const char **fmt, va_list *args, int endchar, + int nr_elems) +{ + int i; + QDict *qdict; + + if (nr_elems < 0) + return NULL; + + qdict = qdict_new(); + + for (i = 0; i < nr_elems; i += 2) { + QString *qs; + QObject *obj, *key; + + key = build_qobject(fmt, args); + if (!key) + goto err; + + obj = build_qobject(fmt, args); + if (!obj) { + qobject_decref(key); + goto err; + } + + qs = qobject_to_qstring(key); + qdict_put_obj(qdict, qstring_get_str(qs), obj); + QDECREF(qs); + } + + while (**fmt == ' ') + (*fmt)++; + + if (**fmt != endchar) + goto err; + + if (endchar) + ++*fmt; + + return QOBJECT(qdict); + +err: + QDECREF(qdict); + return NULL; +} + +static QObject *do_mklist(const char **fmt, va_list *args, int endchar, + int nr_elems) +{ + int i; + QList *qlist; + + if (nr_elems < 0) + return NULL; + + qlist = qlist_new(); + + for (i = 0; i < nr_elems; i++) { + QObject *obj = build_qobject(fmt, args); + if (!obj) + goto err; + qlist_append_obj(qlist, obj); + } + + while (**fmt == ' ') + (*fmt)++; + + if (**fmt != endchar) + goto err; + + if (endchar) + ++*fmt; + + return QOBJECT(qlist); + +err: + QDECREF(qlist); + return NULL; +} + +static int +count_format(const char *format, int endchar) +{ + int count = 0; + int level = 0; + + while (level > 0 || *format != endchar) { + switch (*format) { + case '\0': + /* Premature end */ + return -1; + case '[': + case '{': + if (level == 0) + count++; + level++; + break; + case ']': + case '}': + level--; + break; + case ',': + case ':': + case ' ': + case '\t': + break; + default: + if (level == 0) + count++; + } + format++; + } + return count; +} + +static QObject *build_qobject(const char **fmt, va_list *args) +{ + for (;;) { + switch (*(*fmt)++) { + case 'i': + { + QInt *qi = qint_from_int((int64_t) va_arg(*args, int64_t)); + return QOBJECT(qi); + } + case 's': + { + QString *qs = qstring_from_str((char *) va_arg(*args, char *)); + return QOBJECT(qs); + } + case '[': + return do_mklist(fmt, args, ']', count_format(*fmt, ']')); + case '{': + return do_mkdict(fmt, args, '}', count_format(*fmt, '}')); + case ',': + case ':': + case ' ': + case '\t': + break; + default: + return NULL; + } + } +} + +/** + * qobject_from_fmt(): build QObjects from a specified format. + * + * Valid characters of the format: + * + * i integer, map to QInt + * s string, map to QString + * [] list, map to QList + * {} dictionary, map to QDict + * + * Examples: + * + * - Create a QInt + * + * qobject_from_fmt("i", 42); + * + * - Create a QList of QStrings + * + * qobject_from_fmt("[ i, i, i ]", 0, 1 , 2); + * + * - Create a QDict with mixed data-types + * + * qobject_from_fmt("{ s: [ i, s ], s: i }", ... ); + * + * Return a strong reference to a QObject on success, NULL otherwise. + */ +QObject *qobject_from_fmt(const char *fmt, ...) +{ + va_list args; + QObject *obj; + + va_start(args, fmt); + switch (*fmt) { + case '[': + fmt++; + obj = do_mklist(&fmt, &args, ']', count_format(fmt, ']')); + break; + case '{': + fmt++; + obj = do_mkdict(&fmt, &args, '}', count_format(fmt, '}')); + break; + default: + obj = build_qobject(&fmt, &args); + break; + } + va_end(args); + + return obj; +} diff --git a/qmisc.h b/qmisc.h new file mode 100644 index 0000000..ac481fe --- /dev/null +++ b/qmisc.h @@ -0,0 +1,19 @@ +/* + * QMisc header file. + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ +#ifndef QMISC_H +#define QMISC_H + +#include "qobject.h" + +QObject *qobject_from_fmt(const char *fmt, ...); + +#endif /* QMISC_H */ -- 1.6.5.rc2.17.gdbc1b