From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:32840) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QU1aP-0008Cu-1V for qemu-devel@nongnu.org; Tue, 07 Jun 2011 15:05:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QU1aL-00051o-Mu for qemu-devel@nongnu.org; Tue, 07 Jun 2011 15:05:08 -0400 Received: from mail-pw0-f45.google.com ([209.85.160.45]:38335) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QU1aJ-0004yS-Rk for qemu-devel@nongnu.org; Tue, 07 Jun 2011 15:05:04 -0400 Received: by pwi6 with SMTP id 6so21501pwi.4 for ; Tue, 07 Jun 2011 12:05:01 -0700 (PDT) Message-ID: <4DEE7658.4000607@codemonkey.ws> Date: Tue, 07 Jun 2011 14:04:56 -0500 From: Anthony Liguori MIME-Version: 1.0 References: <1307140399-9023-1-git-send-email-mdroth@linux.vnet.ibm.com> <1307140399-9023-5-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1307140399-9023-5-git-send-email-mdroth@linux.vnet.ibm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2][ 04/21] qapi: add ordereddict/qapi.py helper libraries List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Michael Roth Cc: Jes.Sorensen@redhat.com, agl@linux.vnet.ibm.com, qemu-devel@nongnu.org, lcapitulino@redhat.com On 06/03/2011 05:33 PM, Michael Roth wrote: > Signed-off-by: Michael Roth > --- > scripts/ordereddict.py | 128 ++++++++++++++++++++++++++++++++++ > scripts/qapi.py | 181 ++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 309 insertions(+), 0 deletions(-) > create mode 100644 scripts/ordereddict.py > create mode 100644 scripts/qapi.py > > diff --git a/scripts/ordereddict.py b/scripts/ordereddict.py > new file mode 100644 > index 0000000..e17269f > --- /dev/null > +++ b/scripts/ordereddict.py > @@ -0,0 +1,128 @@ > +# Copyright (c) 2009 Raymond Hettinger > +# > +# Permission is hereby granted, free of charge, to any person > +# obtaining a copy of this software and associated documentation files > +# (the "Software"), to deal in the Software without restriction, > +# including without limitation the rights to use, copy, modify, merge, > +# publish, distribute, sublicense, and/or sell copies of the Software, > +# and to permit persons to whom the Software is furnished to do so, > +# subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be Please make ordereddict.py a separate patch since this is external code. > diff --git a/scripts/qapi.py b/scripts/qapi.py > new file mode 100644 > index 0000000..422b6bd > --- /dev/null > +++ b/scripts/qapi.py > @@ -0,0 +1,181 @@ Can you add a copyright/license to this? GPLv2. Regards, Anthony Liguori > +from ordereddict import OrderedDict > + > +def tokenize(data): > + while len(data): > + if data[0] in ['{', '}', ':', ',', '[', ']']: > + yield data[0] > + data = data[1:] > + elif data[0] in ' \n': > + data = data[1:] > + elif data[0] == "'": > + data = data[1:] > + string = '' > + while data[0] != "'": > + string += data[0] > + data = data[1:] > + data = data[1:] > + yield string > + > +def parse(tokens): > + if tokens[0] == '{': > + ret = OrderedDict() > + tokens = tokens[1:] > + while tokens[0] != '}': > + key = tokens[0] > + tokens = tokens[1:] > + > + tokens = tokens[1:] # : > + > + value, tokens = parse(tokens) > + > + if tokens[0] == ',': > + tokens = tokens[1:] > + > + ret[key] = value > + tokens = tokens[1:] > + return ret, tokens > + elif tokens[0] == '[': > + ret = [] > + tokens = tokens[1:] > + while tokens[0] != ']': > + value, tokens = parse(tokens) > + if tokens[0] == ',': > + tokens = tokens[1:] > + ret.append(value) > + tokens = tokens[1:] > + return ret, tokens > + else: > + return tokens[0], tokens[1:] > + > +def evaluate(string): > + return parse(map(lambda x: x, tokenize(string)))[0] > + > +def parse_schema(fp): > + exprs = [] > + expr = '' > + > + for line in fp: > + if line.startswith('#') or line == '\n': > + continue > + > + if line.startswith(' '): > + expr += line > + elif expr: > + exprs.append(evaluate(expr)) > + expr = line > + else: > + expr += line > + > + if expr: > + exprs.append(evaluate(expr)) > + > + return exprs > + > +def parse_args(typeinfo): > + for member in typeinfo: > + argname = member > + argentry = typeinfo[member] > + optional = False > + structured = False > + if member.startswith('*'): > + argname = member[1:] > + optional = True > + if isinstance(argentry, OrderedDict): > + structured = True > + yield (argname, argentry, optional, structured) > + > +def de_camel_case(name): > + new_name = '' > + for ch in name: > + if ch.isupper() and new_name: > + new_name += '_' > + if ch == '-': > + new_name += '_' > + else: > + new_name += ch.lower() > + return new_name > + > +def camel_case(name): > + new_name = '' > + first = True > + for ch in name: > + if ch in ['_', '-']: > + first = True > + elif first: > + new_name += ch.upper() > + first = False > + else: > + new_name += ch.lower() > + return new_name > + > +def c_var(name): > + return '_'.join(name.split('-')).lstrip("*") > + > +def c_list_type(name): > + return '%sList' % name > + > +def type_name(name): > + if type(name) == list: > + return c_list_type(name[0]) > + return name > + > +enum_types = [] > + > +def add_enum(name): > + global enum_types > + enum_types.append(name) > + > +def is_enum(name): > + global enum_types > + return (name in enum_types) > + > +def c_type(name): > + if name == 'str': > + return 'char *' > + elif name == 'int': > + return 'int64_t' > + elif name == 'bool': > + return 'bool' > + elif name == 'number': > + return 'double' > + elif type(name) == list: > + return '%s *' % c_list_type(name[0]) > + elif is_enum(name): > + return name > + elif name == None or len(name) == 0: > + return 'void' > + elif name == name.upper(): > + return '%sEvent *' % camel_case(name) > + else: > + return '%s *' % name > + > +def genindent(count): > + ret = "" > + for i in range(count): > + ret += " " > + return ret > + > +indent_level = 0 > + > +def push_indent(indent_amount=4): > + global indent_level > + indent_level += indent_amount > + > +def pop_indent(indent_amount=4): > + global indent_level > + indent_level -= indent_amount > + > +def cgen(code, **kwds): > + indent = genindent(indent_level) > + lines = code.split('\n') > + lines = map(lambda x: indent + x, lines) > + return '\n'.join(lines) % kwds + '\n' > + > +def mcgen(code, **kwds): > + return cgen('\n'.join(code.split('\n')[1:-1]), **kwds) > + > +def basename(filename): > + return filename.split("/")[-1] > + > +def guardname(filename): > + return filename.replace("/", "_").replace("-", "_").split(".")[0].upper()