From 47299262de424af0cb69965d082e5e70b2314183 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 14 May 2015 06:50:47 -0600 Subject: qapi: Fix C identifiers generated for names containing '.' c_fun() maps '.' to '_', c_var() doesn't. Nothing prevents '.' in QAPI names that get passed to c_var(). Which QAPI names get passed to c_fun(), to c_var(), or to both is not obvious. Names of command parameters and struct type members get passed to c_var(). c_var() strips a leading '*', but this cannot happen. c_fun() doesn't. Fix c_var() to work exactly like c_fun(). Perhaps they should be replaced by a single mapping function. Signed-off-by: Markus Armbruster [add 'import string'] Signed-off-by: Eric Blake Reviewed-by: Alberto Garcia --- scripts/qapi.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 166b74f644..4b07805d72 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -15,6 +15,7 @@ import re from ordereddict import OrderedDict import os import sys +import string builtin_types = { 'str': 'QTYPE_QSTRING', @@ -752,6 +753,8 @@ def camel_case(name): new_name += ch.lower() return new_name +c_var_trans = string.maketrans('.-', '__') + def c_var(name, protect=True): # ANSI X3J11/88-090, 3.1.1 c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue', @@ -781,10 +784,10 @@ def c_var(name, protect=True): polluted_words = set(['unix', 'errno']) if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words): return "q_" + name - return name.replace('-', '_').lstrip("*") + return name.translate(c_var_trans) def c_fun(name, protect=True): - return c_var(name, protect).replace('.', '_') + return c_var(name, protect) def c_list_type(name): return '%sList' % name -- cgit v1.2.3 From 18df515ebbefa9f13474b128b8050d5fa346ea1e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 14 May 2015 06:50:48 -0600 Subject: qapi: Rename identical c_fun()/c_var() into c_name() Now that the two functions are identical, we only need one of them, and we might as well give it a more descriptive name. Basically, the function serves as the translation from a QAPI name into a (portion of a) C identifier, without regards to whether it is a variable or function name. Signed-off-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qapi.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 4b07805d72..a4701ca4ed 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -753,9 +753,9 @@ def camel_case(name): new_name += ch.lower() return new_name -c_var_trans = string.maketrans('.-', '__') +c_name_trans = string.maketrans('.-', '__') -def c_var(name, protect=True): +def c_name(name, protect=True): # ANSI X3J11/88-090, 3.1.1 c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double', 'else', 'enum', 'extern', 'float', @@ -784,10 +784,7 @@ def c_var(name, protect=True): polluted_words = set(['unix', 'errno']) if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words): return "q_" + name - return name.translate(c_var_trans) - -def c_fun(name, protect=True): - return c_var(name, protect) + return name.translate(c_name_trans) def c_list_type(name): return '%sList' % name @@ -945,7 +942,7 @@ def guardend(name): # ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2 # ENUM24_Name -> ENUM24_NAME def _generate_enum_string(value): - c_fun_str = c_fun(value, False) + c_fun_str = c_name(value, False) if value.isupper(): return c_fun_str -- cgit v1.2.3 From fa6068a1e8ef3c878ac9ee2399bb01eeaf61c366 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 14 May 2015 06:50:49 -0600 Subject: qapi: Rename _generate_enum_string() to camel_to_upper() Signed-off-by: Markus Armbruster Signed-off-by: Eric Blake --- scripts/qapi.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index a4701ca4ed..7330f7cc64 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -538,7 +538,7 @@ def check_union(expr, expr_info): # Otherwise, check for conflicts in the generated enum else: - c_key = _generate_enum_string(key) + c_key = camel_to_upper(key) if c_key in values: raise QAPIExprError(expr_info, "Union '%s' member '%s' clashes with '%s'" @@ -556,7 +556,7 @@ def check_alternate(expr, expr_info): check_name(expr_info, "Member of alternate '%s'" % name, key) # Check for conflicts in the generated enum - c_key = _generate_enum_string(key) + c_key = camel_to_upper(key) if c_key in values: raise QAPIExprError(expr_info, "Alternate '%s' member '%s' clashes with '%s'" @@ -587,7 +587,7 @@ def check_enum(expr, expr_info): for member in members: check_name(expr_info, "Member of enum '%s'" %name, member, enum_member=True) - key = _generate_enum_string(member) + key = camel_to_upper(member) if key in values: raise QAPIExprError(expr_info, "Enum '%s' member '%s' clashes with '%s'" @@ -941,7 +941,7 @@ def guardend(name): # ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1 # ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2 # ENUM24_Name -> ENUM24_NAME -def _generate_enum_string(value): +def camel_to_upper(value): c_fun_str = c_name(value, False) if value.isupper(): return c_fun_str @@ -961,6 +961,6 @@ def _generate_enum_string(value): return new_name.lstrip('_').upper() def generate_enum_full_value(enum_name, enum_value): - abbrev_string = _generate_enum_string(enum_name) - value_string = _generate_enum_string(enum_value) + abbrev_string = camel_to_upper(enum_name) + value_string = camel_to_upper(enum_value) return "%s_%s" % (abbrev_string, value_string) -- cgit v1.2.3 From 7c81c61f9c2274f66ba947eafd9618d60da838a6 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 14 May 2015 06:50:50 -0600 Subject: qapi: Rename generate_enum_full_value() to c_enum_const() Signed-off-by: Markus Armbruster Signed-off-by: Eric Blake --- scripts/qapi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 7330f7cc64..1258f762ba 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -960,7 +960,7 @@ def camel_to_upper(value): new_name += c return new_name.lstrip('_').upper() -def generate_enum_full_value(enum_name, enum_value): - abbrev_string = camel_to_upper(enum_name) - value_string = camel_to_upper(enum_value) +def c_enum_const(type_name, const_name): + abbrev_string = camel_to_upper(type_name) + value_string = camel_to_upper(const_name) return "%s_%s" % (abbrev_string, value_string) -- cgit v1.2.3 From 02e20c7e593363c564aae96e3c5bdc58630ce584 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 14 May 2015 06:50:51 -0600 Subject: qapi: Simplify c_enum_const() Signed-off-by: Markus Armbruster Signed-off-by: Eric Blake --- scripts/qapi.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 1258f762ba..b917cadf75 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -961,6 +961,4 @@ def camel_to_upper(value): return new_name.lstrip('_').upper() def c_enum_const(type_name, const_name): - abbrev_string = camel_to_upper(type_name) - value_string = camel_to_upper(const_name) - return "%s_%s" % (abbrev_string, value_string) + return camel_to_upper(type_name + '_' + const_name) -- cgit v1.2.3 From b42e91484df9772bb0c26aa0f05390a92d564d6f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 14 May 2015 06:50:52 -0600 Subject: qapi: Use c_enum_const() in generate_alternate_qtypes() Missed in commit b0b5819. Signed-off-by: Markus Armbruster Signed-off-by: Eric Blake --- scripts/qapi.py | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index b917cadf75..3757a91346 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -729,17 +729,6 @@ def parse_args(typeinfo): # value of an optional argument. yield (argname, argentry, optional) -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 -- cgit v1.2.3 From 849bc5382e42b3b9590c6a50ba30c2fd2450308c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 14 May 2015 06:50:53 -0600 Subject: qapi: Move camel_to_upper(), c_enum_const() to closely related code Signed-off-by: Markus Armbruster Signed-off-by: Eric Blake --- scripts/qapi.py | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 3757a91346..cc33355a91 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -742,6 +742,31 @@ def camel_case(name): new_name += ch.lower() return new_name +# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1 +# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2 +# ENUM24_Name -> ENUM24_NAME +def camel_to_upper(value): + c_fun_str = c_name(value, False) + if value.isupper(): + return c_fun_str + + new_name = '' + l = len(c_fun_str) + for i in range(l): + c = c_fun_str[i] + # When c is upper and no "_" appears before, do more checks + if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_": + # Case 1: next string is lower + # Case 2: previous string is digit + if (i < (l - 1) and c_fun_str[i + 1].islower()) or \ + c_fun_str[i - 1].isdigit(): + new_name += '_' + new_name += c + return new_name.lstrip('_').upper() + +def c_enum_const(type_name, const_name): + return camel_to_upper(type_name + '_' + const_name) + c_name_trans = string.maketrans('.-', '__') def c_name(name, protect=True): @@ -926,28 +951,3 @@ def guardend(name): ''', name=guardname(name)) - -# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1 -# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2 -# ENUM24_Name -> ENUM24_NAME -def camel_to_upper(value): - c_fun_str = c_name(value, False) - if value.isupper(): - return c_fun_str - - new_name = '' - l = len(c_fun_str) - for i in range(l): - c = c_fun_str[i] - # When c is upper and no "_" appears before, do more checks - if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_": - # Case 1: next string is lower - # Case 2: previous string is digit - if (i < (l - 1) and c_fun_str[i + 1].islower()) or \ - c_fun_str[i - 1].isdigit(): - new_name += '_' - new_name += c - return new_name.lstrip('_').upper() - -def c_enum_const(type_name, const_name): - return camel_to_upper(type_name + '_' + const_name) -- cgit v1.2.3 From d557344628e32771f07e5b6a2a818ee3d8e7a65f Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 14 May 2015 06:50:54 -0600 Subject: qapi: Tidy c_type() logic c_type() is designed to be called on both string names and on array designations, so 'name' is a bit misleading because it operates on more than strings. Also, no caller ever passes an empty string. Finally, + notation is a bit nicer to read than '%s' % value for string concatenation. Signed-off-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qapi.py | 58 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 28 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index cc33355a91..ecab87907c 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -801,12 +801,12 @@ def c_name(name, protect=True): return name.translate(c_name_trans) def c_list_type(name): - return '%sList' % name + return name + 'List' -def type_name(name): - if type(name) == list: - return c_list_type(name[0]) - return name +def type_name(value): + if type(value) == list: + return c_list_type(value[0]) + return value def add_name(name, info, meta, implicit = False): global all_names @@ -863,42 +863,44 @@ def is_enum(name): return find_enum(name) != None eatspace = '\033EATSPACE.' +pointer_suffix = ' *' + eatspace # A special suffix is added in c_type() for pointer types, and it's # stripped in mcgen(). So please notice this when you check the return # value of c_type() outside mcgen(). -def c_type(name, is_param=False): - if name == 'str': +def c_type(value, is_param=False): + if value == 'str': if is_param: - return 'const char *' + eatspace - return 'char *' + eatspace + return 'const char' + pointer_suffix + return 'char' + pointer_suffix - elif name == 'int': + elif value == 'int': return 'int64_t' - elif (name == 'int8' or name == 'int16' or name == 'int32' or - name == 'int64' or name == 'uint8' or name == 'uint16' or - name == 'uint32' or name == 'uint64'): - return name + '_t' - elif name == 'size': + elif (value == 'int8' or value == 'int16' or value == 'int32' or + value == 'int64' or value == 'uint8' or value == 'uint16' or + value == 'uint32' or value == 'uint64'): + return value + '_t' + elif value == 'size': return 'uint64_t' - elif name == 'bool': + elif value == 'bool': return 'bool' - elif name == 'number': + elif value == 'number': return 'double' - elif type(name) == list: - return '%s *%s' % (c_list_type(name[0]), eatspace) - elif is_enum(name): - return name - elif name == None or len(name) == 0: + elif type(value) == list: + return c_list_type(value[0]) + pointer_suffix + elif is_enum(value): + return value + elif value == None: return 'void' - elif name in events: - return '%sEvent *%s' % (camel_case(name), eatspace) + elif value in events: + return camel_case(value) + 'Event' + pointer_suffix else: - return '%s *%s' % (name, eatspace) + # complex type name + assert isinstance(value, str) and value != "" + return value + pointer_suffix -def is_c_ptr(name): - suffix = "*" + eatspace - return c_type(name).endswith(suffix) +def is_c_ptr(value): + return c_type(value).endswith(pointer_suffix) def genindent(count): ret = "" -- cgit v1.2.3 From c6405b54b7b09a876f2f2fba2aa6f8ac87189cb9 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 14 May 2015 06:50:55 -0600 Subject: qapi: Make c_type() consistently convert qapi names Continuing the string of cleanups for supporting downstream names containing '.', this patch focuses on ensuring c_type() can handle a downstream name. This patch alone does not fix the places where generator output should be calling this function but was open-coding things instead, but it gets us a step closer. In particular, the changes to c_list_type() and type_name() mean that type_name(FOO) now handles the case when FOO contains '.', '-', or is a ticklish identifier other than a builtin (builtins are exempted because ['int'] must remain mapped to 'intList' and not 'q_intList'). Meanwhile, ['unix'] now maps to 'q_unixList' rather than 'unixList', to match the fact that 'unix' is ticklish; however, our naming conventions state that complex types should start with a capital, so no type name following conventions will ever have the 'q_' prepended. Likewise, changes to c_type() mean that c_type(FOO) properly handles an enum or complex type FOO with '.' or '-' in the name, or is a ticklish identifier (again, a ticklish identifier as a type name violates conventions). Signed-off-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qapi.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index ecab87907c..273afedc3d 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -769,6 +769,15 @@ def c_enum_const(type_name, const_name): c_name_trans = string.maketrans('.-', '__') +# Map @name to a valid C identifier. +# If @protect, avoid returning certain ticklish identifiers (like +# C keywords) by prepending "q_". +# +# Used for converting 'name' from a 'name':'type' qapi definition +# into a generated struct member, as well as converting type names +# into substrings of a generated C function name. +# '__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo' +# protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int' def c_name(name, protect=True): # ANSI X3J11/88-090, 3.1.1 c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue', @@ -800,13 +809,25 @@ def c_name(name, protect=True): return "q_" + name return name.translate(c_name_trans) +# Map type @name to the C typedef name for the list form. +# +# ['Name'] -> 'NameList', ['x-Foo'] -> 'x_FooList', ['int'] -> 'intList' def c_list_type(name): - return name + 'List' + return type_name(name) + 'List' +# Map type @value to the C typedef form. +# +# Used for converting 'type' from a 'member':'type' qapi definition +# into the alphanumeric portion of the type for a generated C parameter, +# as well as generated C function names. See c_type() for the rest of +# the conversion such as adding '*' on pointer types. +# 'int' -> 'int', '[x-Foo]' -> 'x_FooList', '__a.b_c' -> '__a_b_c' def type_name(value): if type(value) == list: return c_list_type(value[0]) - return value + if value in builtin_types.keys(): + return value + return c_name(value) def add_name(name, info, meta, implicit = False): global all_names @@ -865,6 +886,10 @@ def is_enum(name): eatspace = '\033EATSPACE.' pointer_suffix = ' *' + eatspace +# Map type @name to its C type expression. +# If @is_param, const-qualify the string type. +# +# This function is used for computing the full C type of 'member':'name'. # A special suffix is added in c_type() for pointer types, and it's # stripped in mcgen(). So please notice this when you check the return # value of c_type() outside mcgen(). @@ -889,7 +914,7 @@ def c_type(value, is_param=False): elif type(value) == list: return c_list_type(value[0]) + pointer_suffix elif is_enum(value): - return value + return c_name(value) elif value == None: return 'void' elif value in events: @@ -897,7 +922,7 @@ def c_type(value, is_param=False): else: # complex type name assert isinstance(value, str) and value != "" - return value + pointer_suffix + return c_name(value) + pointer_suffix def is_c_ptr(value): return c_type(value).endswith(pointer_suffix) -- cgit v1.2.3 From 2114f5a98d0d80774306279e1694de074ca86aa0 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 2 Apr 2015 13:12:21 +0200 Subject: qapi: Factor parse_command_line() out of the generators Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 273afedc3d..b97dd0b14a 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -13,6 +13,7 @@ import re from ordereddict import OrderedDict +import getopt import os import sys import string @@ -978,3 +979,42 @@ def guardend(name): ''', name=guardname(name)) + +def parse_command_line(extra_options = "", extra_long_options = []): + + try: + opts, args = getopt.gnu_getopt(sys.argv[1:], + "chp:i:o:" + extra_options, + ["source", "header", "prefix=", + "input-file=", "output-dir="] + + extra_long_options) + except getopt.GetoptError, err: + print str(err) + sys.exit(1) + + output_dir = "" + prefix = "" + do_c = False + do_h = False + extra_opts = [] + + for oa in opts: + o, a = oa + if o in ("-p", "--prefix"): + prefix = a + elif o in ("-i", "--input-file"): + input_file = a + elif o in ("-o", "--output-dir"): + output_dir = a + "/" + elif o in ("-c", "--source"): + do_c = True + elif o in ("-h", "--header"): + do_h = True + else: + extra_opts.append(oa) + + if not do_c and not do_h: + do_c = True + do_h = True + + return (input_file, output_dir, do_c, do_h, prefix, extra_opts) -- cgit v1.2.3 From b45409683e829770000a4560ed21e704f87df74c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 2 Apr 2015 13:17:34 +0200 Subject: qapi: Fix generators to report command line errors decently Report to stderr, prefix with the program name. Also reject extra arguments. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index b97dd0b14a..df6e5aa381 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -989,7 +989,7 @@ def parse_command_line(extra_options = "", extra_long_options = []): "input-file=", "output-dir="] + extra_long_options) except getopt.GetoptError, err: - print str(err) + print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err)) sys.exit(1) output_dir = "" @@ -1017,4 +1017,8 @@ def parse_command_line(extra_options = "", extra_long_options = []): do_c = True do_h = True + if len(args) != 0: + print >>sys.stderr, "%s: too many arguments" % sys.argv[0] + sys.exit(1) + return (input_file, output_dir, do_c, do_h, prefix, extra_opts) -- cgit v1.2.3 From 16d80f61814745bd3f5bb9f47ae3b00edf9e1e45 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 2 Apr 2015 13:32:16 +0200 Subject: qapi: Turn generators' mandatory option -i into an argument Mandatory option is silly, and the error handling is missing: the programs crash when -i isn't supplied. Make it an argument, and check it properly. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index df6e5aa381..186ec3b39f 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -984,10 +984,9 @@ def parse_command_line(extra_options = "", extra_long_options = []): try: opts, args = getopt.gnu_getopt(sys.argv[1:], - "chp:i:o:" + extra_options, + "chp:o:" + extra_options, ["source", "header", "prefix=", - "input-file=", "output-dir="] - + extra_long_options) + "output-dir="] + extra_long_options) except getopt.GetoptError, err: print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err)) sys.exit(1) @@ -1002,8 +1001,6 @@ def parse_command_line(extra_options = "", extra_long_options = []): o, a = oa if o in ("-p", "--prefix"): prefix = a - elif o in ("-i", "--input-file"): - input_file = a elif o in ("-o", "--output-dir"): output_dir = a + "/" elif o in ("-c", "--source"): @@ -1017,8 +1014,9 @@ def parse_command_line(extra_options = "", extra_long_options = []): do_c = True do_h = True - if len(args) != 0: - print >>sys.stderr, "%s: too many arguments" % sys.argv[0] + if len(args) != 1: + print >>sys.stderr, "%s: need exactly one argument" % sys.argv[0] sys.exit(1) + input_file = args[0] return (input_file, output_dir, do_c, do_h, prefix, extra_opts) -- cgit v1.2.3 From 12f8e1b9ff57e99dafbb13f89cd5a99ad5c28527 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 2 Apr 2015 14:46:39 +0200 Subject: qapi: Factor open_output(), close_output() out of generators Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 186ec3b39f..fbfe0508a0 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -13,6 +13,7 @@ import re from ordereddict import OrderedDict +import errno import getopt import os import sys @@ -1020,3 +1021,52 @@ def parse_command_line(extra_options = "", extra_long_options = []): input_file = args[0] return (input_file, output_dir, do_c, do_h, prefix, extra_opts) + +def open_output(output_dir, do_c, do_h, prefix, c_file, h_file, + c_comment, h_comment): + c_file = output_dir + prefix + c_file + h_file = output_dir + prefix + h_file + + try: + os.makedirs(output_dir) + except os.error, e: + if e.errno != errno.EEXIST: + raise + + def maybe_open(really, name, opt): + if really: + return open(name, opt) + else: + import StringIO + return StringIO.StringIO() + + fdef = maybe_open(do_c, c_file, 'w') + fdecl = maybe_open(do_h, h_file, 'w') + + fdef.write(mcgen(''' +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ +%(comment)s +''', + comment = c_comment)) + + fdecl.write(mcgen(''' +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ +%(comment)s +#ifndef %(guard)s +#define %(guard)s + +''', + comment = h_comment, guard = guardname(h_file))) + + return (fdef, fdecl) + +def close_output(fdef, fdecl): + fdecl.write(''' +#endif +''') + + fdecl.flush() + fdecl.close() + + fdef.flush() + fdef.close() -- cgit v1.2.3 From 09896d3f48078a93e3d2dbd8ef86436b85ebda7c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 2 Apr 2015 14:49:29 +0200 Subject: qapi: Drop pointless flush() before close() Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index fbfe0508a0..f96a7772e5 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1064,9 +1064,5 @@ def close_output(fdef, fdecl): fdecl.write(''' #endif ''') - - fdecl.flush() fdecl.close() - - fdef.flush() fdef.close() -- cgit v1.2.3