From 9ce6a21aaa76cd40c95ebbcb5fc6e48a8f5dfdb9 Mon Sep 17 00:00:00 2001 From: Paul Vinciguerra Date: Wed, 12 Sep 2018 13:40:13 -0700 Subject: Fix: vppapigen make build fails on fresh install Steps to reproduce: vagrant@localhost:/vagrant$ build-root/vagrant/build.sh ... @@@@ Building vpp in /vagrant/build-root/build-vpp-native/vpp @@@@ [51/1169] Generating API header /vagrant/build-root/build-vpp-native/vpp/vlibmemory/memclnt.api.json FAILED: cd /vagrant/build-root/build-vpp-native/vpp/vlibmemory && mkdir -p /vagrant/build-root/build-vpp-native/vpp/vlibmemory && /vagrant/src/tools/vppapigen/vppapigen --includedir /vagrant/src --input /vagrant/src/vlibmemory/memclnt.api JSON --output /vagrant/build-root/build-vpp-native/vpp/vlibmemory/memclnt.api.json AttributeError: 'module' object has no attribute 'dumps' This seems to be due to JSON.py namespace colliding with the standard lib json.py Change-Id: If389e4e05ef0c166b0c2b3bef7ec0185298679a8 Signed-off-by: Paul Vinciguerra --- src/tools/vppapigen/C.py | 286 ---------------------------------- src/tools/vppapigen/CMakeLists.txt | 2 +- src/tools/vppapigen/JSON.py | 69 -------- src/tools/vppapigen/vppapigen.py | 4 +- src/tools/vppapigen/vppapigen_c.py | 286 ++++++++++++++++++++++++++++++++++ src/tools/vppapigen/vppapigen_json.py | 69 ++++++++ 6 files changed, 358 insertions(+), 358 deletions(-) delete mode 100644 src/tools/vppapigen/C.py delete mode 100644 src/tools/vppapigen/JSON.py create mode 100644 src/tools/vppapigen/vppapigen_c.py create mode 100644 src/tools/vppapigen/vppapigen_json.py (limited to 'src') diff --git a/src/tools/vppapigen/C.py b/src/tools/vppapigen/C.py deleted file mode 100644 index b56e0722122..00000000000 --- a/src/tools/vppapigen/C.py +++ /dev/null @@ -1,286 +0,0 @@ -# C generation -import datetime -import os -import time - -datestring = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) -input_filename = 'inputfil' -top_boilerplate = '''\ -/* - * VLIB API definitions {datestring} - * Input file: {input_filename} - * Automatically generated: please edit the input file NOT this file! - */ - -#if defined(vl_msg_id)||defined(vl_union_id) \\ - || defined(vl_printfun) ||defined(vl_endianfun) \\ - || defined(vl_api_version)||defined(vl_typedefs) \\ - || defined(vl_msg_name)||defined(vl_msg_name_crc_list) \\ - || defined(vl_api_version_tuple) -/* ok, something was selected */ -#else -#warning no content included from {input_filename} -#endif - -#define VL_API_PACKED(x) x __attribute__ ((packed)) -''' - -bottom_boilerplate = '''\ -/****** API CRC (whole file) *****/ - -#ifdef vl_api_version -vl_api_version({input_filename}, {file_crc:#08x}) - -#endif -''' - - -def msg_ids(s): - output = '''\ - -/****** Message ID / handler enum ******/ - -#ifdef vl_msg_id -''' - - for t in s['Define']: - output += "vl_msg_id(VL_API_%s, vl_api_%s_t_handler)\n" % \ - (t.name.upper(), t.name) - output += "#endif" - - return output - - -def msg_names(s): - output = '''\ - -/****** Message names ******/ - -#ifdef vl_msg_name -''' - - for t in s['Define']: - dont_trace = 0 if t.dont_trace else 1 - output += "vl_msg_name(vl_api_%s_t, %d)\n" % (t.name, dont_trace) - output += "#endif" - - return output - - -def msg_name_crc_list(s, suffix): - output = '''\ - -/****** Message name, crc list ******/ - -#ifdef vl_msg_name_crc_list -''' - output += "#define foreach_vl_msg_name_crc_%s " % suffix - - for t in s['Define']: - output += "\\\n_(VL_API_%s, %s, %08x) " % \ - (t.name.upper(), t.name, t.crc) - output += "\n#endif" - - return output - - -def duplicate_wrapper_head(name): - s = "#ifndef defined_%s\n" % name - s += "#define defined_%s\n" % name - return s - - -def duplicate_wrapper_tail(): - return '#endif\n\n' - - -def typedefs(objs, filename): - name = filename.replace('.', '_') - output = '''\ - - -/****** Typedefs ******/ - -#ifdef vl_typedefs -#ifndef included_{module} -#define included_{module} -''' - output = output.format(module=name) - for o in objs: - tname = o.__class__.__name__ - output += duplicate_wrapper_head(o.name) - if tname == 'Enum': - output += "typedef enum {\n" - for b in o.block: - output += " %s = %s,\n" % (b[0], b[1]) - output += '} vl_api_%s_t;\n' % o.name - else: - if tname == 'Union': - output += "typedef VL_API_PACKED(union _vl_api_%s {\n" % o.name - else: - output += "typedef VL_API_PACKED(struct _vl_api_%s {\n" % o.name - for b in o.block: - if b.type == 'Field': - output += " %s %s;\n" % (b.fieldtype, b.fieldname) - elif b.type == 'Array': - if b.lengthfield: - output += " %s %s[0];\n" % (b.fieldtype, b.fieldname) - else: - output += " %s %s[%s];\n" % (b.fieldtype, b.fieldname, - b.length) - else: - raise ValueError("Error in processing array type %s" % b) - - output += '}) vl_api_%s_t;\n' % o.name - output += duplicate_wrapper_tail() - - output += "\n#endif" - output += "\n#endif\n\n" - - return output - - -format_strings = {'u8': '%u', - 'i8': '%d', - 'u16': '%u', - 'i16': '%d', - 'u32': '%u', - 'i32': '%ld', - 'u64': '%llu', - 'i64': '%llu', - 'f64': '%.2f', } - - -def printfun(objs): - output = '''\ -/****** Print functions *****/ -#ifdef vl_printfun - -#ifdef LP64 -#define _uword_fmt \"%lld\" -#define _uword_cast (long long) -#else -#define _uword_fmt \"%ld\" -#define _uword_cast long -#endif - -''' - for t in objs: - if t.__class__.__name__ == 'Enum': - continue - if t.manual_print: - output += "/***** manual: vl_api_%s_t_print *****/\n\n" % t.name - continue - output += duplicate_wrapper_head(t.name + '_t_print') - output += "static inline void *vl_api_%s_t_print (vl_api_%s_t *a," % \ - (t.name, t.name) - output += "void *handle)\n{\n" - output += " vl_print(handle, \"vl_api_%s_t:\\n\");\n" % t.name - - for o in t.block: - if o.type != 'Field': - continue - if o.fieldtype in format_strings: - output += " vl_print(handle, \"%s: %s\\n\", a->%s);\n" % \ - (o.fieldname, format_strings[o.fieldtype], - o.fieldname) - - output += ' return handle;\n' - output += '}\n\n' - output += duplicate_wrapper_tail() - - output += "\n#endif /* vl_printfun */\n" - - return output - - -endian_strings = { - 'u16': 'clib_net_to_host_u16', - 'u32': 'clib_net_to_host_u32', - 'u64': 'clib_net_to_host_u64', - 'i16': 'clib_net_to_host_u16', - 'i32': 'clib_net_to_host_u32', - 'i64': 'clib_net_to_host_u64', -} - - -def endianfun(objs): - output = '''\ - -/****** Endian swap functions *****/\n\ -#ifdef vl_endianfun - -#undef clib_net_to_host_uword -#ifdef LP64 -#define clib_net_to_host_uword clib_net_to_host_u64 -#else -#define clib_net_to_host_uword clib_net_to_host_u32 -#endif - -''' - - for t in objs: - if t.__class__.__name__ == 'Enum': - continue - if t.manual_endian: - output += "/***** manual: vl_api_%s_t_endian *****/\n\n" % t.name - continue - output += duplicate_wrapper_head(t.name + '_t_endian') - output += "static inline void vl_api_%s_t_endian (vl_api_%s_t *a)" % \ - (t.name, t.name) - output += "\n{\n" - - for o in t.block: - if o.type != 'Field': - continue - if o.fieldtype in endian_strings: - output += " a->%s = %s(a->%s);\n" % \ - (o.fieldname, endian_strings[o.fieldtype], o.fieldname) - else: - output += " /* a->%s = a->%s (no-op) */\n" % \ - (o.fieldname, o.fieldname) - - output += '}\n\n' - output += duplicate_wrapper_tail() - output += "\n#endif /* vl_endianfun */\n\n" - - return output - - -def version_tuple(s, module): - output = '''\ -/****** Version tuple *****/ - -#ifdef vl_api_version_tuple - -''' - if 'version' in s['Option']: - v = s['Option']['version'] - (major, minor, patch) = v.split('.') - output += "vl_api_version_tuple(%s, %s, %s, %s)\n" % \ - (module, major, minor, patch) - - output += "\n#endif /* vl_api_version_tuple */\n\n" - - return output - - -# -# Plugin entry point -# -def run(input_filename, s, file_crc): - basename = os.path.basename(input_filename) - filename, file_extension = os.path.splitext(basename) - output = top_boilerplate.format(datestring=datestring, - input_filename=basename) - output += msg_ids(s) - output += msg_names(s) - output += msg_name_crc_list(s, filename) - output += typedefs(s['types'] + s['Define'], filename + file_extension) - output += printfun(s['types'] + s['Define']) - output += endianfun(s['types'] + s['Define']) - output += version_tuple(s, basename) - output += bottom_boilerplate.format(input_filename=basename, - file_crc=file_crc) - - return output diff --git a/src/tools/vppapigen/CMakeLists.txt b/src/tools/vppapigen/CMakeLists.txt index 0d982fe29f8..ce25cb0c9e7 100644 --- a/src/tools/vppapigen/CMakeLists.txt +++ b/src/tools/vppapigen/CMakeLists.txt @@ -21,4 +21,4 @@ install( COMPONENT vpp-dev ) -install(FILES C.py JSON.py DESTINATION share/vpp COMPONENT vpp-dev) +install(FILES vppapigen_c.py vppapigen_json.py DESTINATION share/vpp COMPONENT vpp-dev) diff --git a/src/tools/vppapigen/JSON.py b/src/tools/vppapigen/JSON.py deleted file mode 100644 index 2991bec57ac..00000000000 --- a/src/tools/vppapigen/JSON.py +++ /dev/null @@ -1,69 +0,0 @@ -# JSON generation -import json - - -def walk_enums(s): - r = [] - for e in s: - d = [] - d.append(e.name) - for b in e.block: - d.append(b) - d.append({'enumtype': e.enumtype}) - r.append(d) - return r - - -def walk_services(s): - r = {} - for e in s: - d = {'reply': e.reply} - if e.stream: - d['stream'] = True - if e.events: - d['events'] = e.events - r[e.caller] = d - return r - - -def walk_defs(s): - r = [] - for t in s: - d = [] - d.append(t.name) - for b in t.block: - f = [] - if b.type == 'Field': - f = [b.fieldtype, b.fieldname] - elif b.type == 'Array': - if b.lengthfield: - f = [b.fieldtype, b.fieldname, b.length, b.lengthfield] - else: - f = [b.fieldtype, b.fieldname, b.length] - elif b.type == 'Union': - print('UNION') - else: - raise ValueError("Error in processing array type %s" % b) - d.append(f) - if t.crc: - c = {} - c['crc'] = "{0:#0{1}x}".format(t.crc, 10) - d.append(c) - - r.append(d) - return r - - -# -# Plugin entry point -# -def run(filename, s, file_crc): - j = {} - - j['types'] = walk_defs([o for o in s['types'] if o.__class__.__name__ == 'Typedef']) - j['messages'] = walk_defs(s['Define']) - j['unions'] = walk_defs([o for o in s['types'] if o.__class__.__name__ == 'Union']) - j['enums'] = walk_enums([o for o in s['types'] if o.__class__.__name__ == 'Enum']) - j['services'] = walk_services(s['Service']) - j['vl_api_version'] = hex(file_crc) - return json.dumps(j, indent=4, separators=(',', ': ')) diff --git a/src/tools/vppapigen/vppapigen.py b/src/tools/vppapigen/vppapigen.py index f3094ec0a84..9d04ec24cfc 100755 --- a/src/tools/vppapigen/vppapigen.py +++ b/src/tools/vppapigen/vppapigen.py @@ -785,14 +785,14 @@ def main(): '/../share/vpp/') for c in cand: c += '/' - if os.path.isfile(c + args.output_module + '.py'): + if os.path.isfile('{}vppapigen_{}.py'.format(c, args.output_module.lower())): pluginpath = c break else: pluginpath = args.pluginpath + '/' if pluginpath == '': raise Exception('Output plugin not found') - module_path = pluginpath + args.output_module + '.py' + module_path = '{}vppapigen_{}.py'.format(pluginpath, args.output_module.lower()) try: plugin = imp.load_source(args.output_module, module_path) diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py new file mode 100644 index 00000000000..b56e0722122 --- /dev/null +++ b/src/tools/vppapigen/vppapigen_c.py @@ -0,0 +1,286 @@ +# C generation +import datetime +import os +import time + +datestring = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) +input_filename = 'inputfil' +top_boilerplate = '''\ +/* + * VLIB API definitions {datestring} + * Input file: {input_filename} + * Automatically generated: please edit the input file NOT this file! + */ + +#if defined(vl_msg_id)||defined(vl_union_id) \\ + || defined(vl_printfun) ||defined(vl_endianfun) \\ + || defined(vl_api_version)||defined(vl_typedefs) \\ + || defined(vl_msg_name)||defined(vl_msg_name_crc_list) \\ + || defined(vl_api_version_tuple) +/* ok, something was selected */ +#else +#warning no content included from {input_filename} +#endif + +#define VL_API_PACKED(x) x __attribute__ ((packed)) +''' + +bottom_boilerplate = '''\ +/****** API CRC (whole file) *****/ + +#ifdef vl_api_version +vl_api_version({input_filename}, {file_crc:#08x}) + +#endif +''' + + +def msg_ids(s): + output = '''\ + +/****** Message ID / handler enum ******/ + +#ifdef vl_msg_id +''' + + for t in s['Define']: + output += "vl_msg_id(VL_API_%s, vl_api_%s_t_handler)\n" % \ + (t.name.upper(), t.name) + output += "#endif" + + return output + + +def msg_names(s): + output = '''\ + +/****** Message names ******/ + +#ifdef vl_msg_name +''' + + for t in s['Define']: + dont_trace = 0 if t.dont_trace else 1 + output += "vl_msg_name(vl_api_%s_t, %d)\n" % (t.name, dont_trace) + output += "#endif" + + return output + + +def msg_name_crc_list(s, suffix): + output = '''\ + +/****** Message name, crc list ******/ + +#ifdef vl_msg_name_crc_list +''' + output += "#define foreach_vl_msg_name_crc_%s " % suffix + + for t in s['Define']: + output += "\\\n_(VL_API_%s, %s, %08x) " % \ + (t.name.upper(), t.name, t.crc) + output += "\n#endif" + + return output + + +def duplicate_wrapper_head(name): + s = "#ifndef defined_%s\n" % name + s += "#define defined_%s\n" % name + return s + + +def duplicate_wrapper_tail(): + return '#endif\n\n' + + +def typedefs(objs, filename): + name = filename.replace('.', '_') + output = '''\ + + +/****** Typedefs ******/ + +#ifdef vl_typedefs +#ifndef included_{module} +#define included_{module} +''' + output = output.format(module=name) + for o in objs: + tname = o.__class__.__name__ + output += duplicate_wrapper_head(o.name) + if tname == 'Enum': + output += "typedef enum {\n" + for b in o.block: + output += " %s = %s,\n" % (b[0], b[1]) + output += '} vl_api_%s_t;\n' % o.name + else: + if tname == 'Union': + output += "typedef VL_API_PACKED(union _vl_api_%s {\n" % o.name + else: + output += "typedef VL_API_PACKED(struct _vl_api_%s {\n" % o.name + for b in o.block: + if b.type == 'Field': + output += " %s %s;\n" % (b.fieldtype, b.fieldname) + elif b.type == 'Array': + if b.lengthfield: + output += " %s %s[0];\n" % (b.fieldtype, b.fieldname) + else: + output += " %s %s[%s];\n" % (b.fieldtype, b.fieldname, + b.length) + else: + raise ValueError("Error in processing array type %s" % b) + + output += '}) vl_api_%s_t;\n' % o.name + output += duplicate_wrapper_tail() + + output += "\n#endif" + output += "\n#endif\n\n" + + return output + + +format_strings = {'u8': '%u', + 'i8': '%d', + 'u16': '%u', + 'i16': '%d', + 'u32': '%u', + 'i32': '%ld', + 'u64': '%llu', + 'i64': '%llu', + 'f64': '%.2f', } + + +def printfun(objs): + output = '''\ +/****** Print functions *****/ +#ifdef vl_printfun + +#ifdef LP64 +#define _uword_fmt \"%lld\" +#define _uword_cast (long long) +#else +#define _uword_fmt \"%ld\" +#define _uword_cast long +#endif + +''' + for t in objs: + if t.__class__.__name__ == 'Enum': + continue + if t.manual_print: + output += "/***** manual: vl_api_%s_t_print *****/\n\n" % t.name + continue + output += duplicate_wrapper_head(t.name + '_t_print') + output += "static inline void *vl_api_%s_t_print (vl_api_%s_t *a," % \ + (t.name, t.name) + output += "void *handle)\n{\n" + output += " vl_print(handle, \"vl_api_%s_t:\\n\");\n" % t.name + + for o in t.block: + if o.type != 'Field': + continue + if o.fieldtype in format_strings: + output += " vl_print(handle, \"%s: %s\\n\", a->%s);\n" % \ + (o.fieldname, format_strings[o.fieldtype], + o.fieldname) + + output += ' return handle;\n' + output += '}\n\n' + output += duplicate_wrapper_tail() + + output += "\n#endif /* vl_printfun */\n" + + return output + + +endian_strings = { + 'u16': 'clib_net_to_host_u16', + 'u32': 'clib_net_to_host_u32', + 'u64': 'clib_net_to_host_u64', + 'i16': 'clib_net_to_host_u16', + 'i32': 'clib_net_to_host_u32', + 'i64': 'clib_net_to_host_u64', +} + + +def endianfun(objs): + output = '''\ + +/****** Endian swap functions *****/\n\ +#ifdef vl_endianfun + +#undef clib_net_to_host_uword +#ifdef LP64 +#define clib_net_to_host_uword clib_net_to_host_u64 +#else +#define clib_net_to_host_uword clib_net_to_host_u32 +#endif + +''' + + for t in objs: + if t.__class__.__name__ == 'Enum': + continue + if t.manual_endian: + output += "/***** manual: vl_api_%s_t_endian *****/\n\n" % t.name + continue + output += duplicate_wrapper_head(t.name + '_t_endian') + output += "static inline void vl_api_%s_t_endian (vl_api_%s_t *a)" % \ + (t.name, t.name) + output += "\n{\n" + + for o in t.block: + if o.type != 'Field': + continue + if o.fieldtype in endian_strings: + output += " a->%s = %s(a->%s);\n" % \ + (o.fieldname, endian_strings[o.fieldtype], o.fieldname) + else: + output += " /* a->%s = a->%s (no-op) */\n" % \ + (o.fieldname, o.fieldname) + + output += '}\n\n' + output += duplicate_wrapper_tail() + output += "\n#endif /* vl_endianfun */\n\n" + + return output + + +def version_tuple(s, module): + output = '''\ +/****** Version tuple *****/ + +#ifdef vl_api_version_tuple + +''' + if 'version' in s['Option']: + v = s['Option']['version'] + (major, minor, patch) = v.split('.') + output += "vl_api_version_tuple(%s, %s, %s, %s)\n" % \ + (module, major, minor, patch) + + output += "\n#endif /* vl_api_version_tuple */\n\n" + + return output + + +# +# Plugin entry point +# +def run(input_filename, s, file_crc): + basename = os.path.basename(input_filename) + filename, file_extension = os.path.splitext(basename) + output = top_boilerplate.format(datestring=datestring, + input_filename=basename) + output += msg_ids(s) + output += msg_names(s) + output += msg_name_crc_list(s, filename) + output += typedefs(s['types'] + s['Define'], filename + file_extension) + output += printfun(s['types'] + s['Define']) + output += endianfun(s['types'] + s['Define']) + output += version_tuple(s, basename) + output += bottom_boilerplate.format(input_filename=basename, + file_crc=file_crc) + + return output diff --git a/src/tools/vppapigen/vppapigen_json.py b/src/tools/vppapigen/vppapigen_json.py new file mode 100644 index 00000000000..2991bec57ac --- /dev/null +++ b/src/tools/vppapigen/vppapigen_json.py @@ -0,0 +1,69 @@ +# JSON generation +import json + + +def walk_enums(s): + r = [] + for e in s: + d = [] + d.append(e.name) + for b in e.block: + d.append(b) + d.append({'enumtype': e.enumtype}) + r.append(d) + return r + + +def walk_services(s): + r = {} + for e in s: + d = {'reply': e.reply} + if e.stream: + d['stream'] = True + if e.events: + d['events'] = e.events + r[e.caller] = d + return r + + +def walk_defs(s): + r = [] + for t in s: + d = [] + d.append(t.name) + for b in t.block: + f = [] + if b.type == 'Field': + f = [b.fieldtype, b.fieldname] + elif b.type == 'Array': + if b.lengthfield: + f = [b.fieldtype, b.fieldname, b.length, b.lengthfield] + else: + f = [b.fieldtype, b.fieldname, b.length] + elif b.type == 'Union': + print('UNION') + else: + raise ValueError("Error in processing array type %s" % b) + d.append(f) + if t.crc: + c = {} + c['crc'] = "{0:#0{1}x}".format(t.crc, 10) + d.append(c) + + r.append(d) + return r + + +# +# Plugin entry point +# +def run(filename, s, file_crc): + j = {} + + j['types'] = walk_defs([o for o in s['types'] if o.__class__.__name__ == 'Typedef']) + j['messages'] = walk_defs(s['Define']) + j['unions'] = walk_defs([o for o in s['types'] if o.__class__.__name__ == 'Union']) + j['enums'] = walk_enums([o for o in s['types'] if o.__class__.__name__ == 'Enum']) + j['services'] = walk_services(s['Service']) + j['vl_api_version'] = hex(file_crc) + return json.dumps(j, indent=4, separators=(',', ': ')) -- cgit 1.2.3-korg