From: Ole Troan Date: Thu, 1 Dec 2016 20:49:03 +0000 (+0100) Subject: API: Packaging of JSON files. X-Git-Tag: v17.01-rc1~143 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;ds=sidebyside;h=f14e3bf7b297f3b9eea87af412929bb8f277b315;p=vpp.git API: Packaging of JSON files. Change-Id: If041b6faf1a091d4758b514f0a8cd800ee0e6a89 Signed-off-by: Ole Troan Signed-off-by: Ole Troan Signed-off-by: Ole Troan --- diff --git a/build-data/platforms.mk b/build-data/platforms.mk index 16e61e3f641..a568c7a06a3 100644 --- a/build-data/platforms.mk +++ b/build-data/platforms.mk @@ -28,6 +28,10 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES)) | sed -e 's:.*:../& /usr/bin:' \ > deb/debian/vpp.install ; \ \ + : core api definitions ; \ + ./scripts/find-api-core-contents $(INSTALL_PREFIX)$(ARCH) \ + deb/debian/vpp.install ; \ + \ : need symbolic links in the lib pkg ; \ find $(INSTALL_PREFIX)$(ARCH)/*/lib* \( -type f -o -type l \) \ -print | egrep -e '*\.so\.*\.*\.*' \ @@ -35,6 +39,10 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES)) | sed -e 's:.*:../& /usr/lib/x86_64-linux-gnu:' \ > deb/debian/vpp-lib.install ; \ \ + : vnet api definitions ; \ + ./scripts/find-api-lib-contents $(INSTALL_PREFIX)$(ARCH) \ + deb/debian/vpp-lib.install ; \ + \ : dev package ; \ ./scripts/find-dev-contents $(INSTALL_PREFIX)$(ARCH) \ deb/debian/vpp-dev.install ; \ @@ -62,8 +70,6 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES)) : dev package needs a couple of additions ; \ echo ../build-tool-native/vppapigen/vppapigen /usr/bin \ >> deb/debian/vpp-dev.install ; \ - echo ../../vppapigen/pyvppapigen.py /usr/bin \ - >> deb/debian/vpp-dev.install ; \ echo ../../vpp-api/java/jvpp/gen/jvpp_gen.py /usr/bin \ >> deb/debian/vpp-dev.install ; \ for i in $$(ls ../vpp-api/java/jvpp/gen/jvppgen/*.py); do \ diff --git a/build-data/suffix-rules.mk b/build-data/suffix-rules.mk index 95069297fa5..e3eeb9220bf 100644 --- a/build-data/suffix-rules.mk +++ b/build-data/suffix-rules.mk @@ -20,4 +20,8 @@ $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ | vppapigen --input - --output $@ --show-name $@ - +%.api.json: %.api + @echo " JSON APIGEN " $@ ; \ + mkdir -p `dirname $@` ; \ + $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ + | vppapigen --input - --json $@ diff --git a/build-root/rpm/vpp.spec b/build-root/rpm/vpp.spec index 0620234d0a5..5db0c4bd7c1 100644 --- a/build-root/rpm/vpp.spec +++ b/build-root/rpm/vpp.spec @@ -98,7 +98,12 @@ mkdir -p -m755 %{buildroot}%{_bindir} mkdir -p -m755 %{buildroot}%{_unitdir} install -p -m 755 %{_mu_build_dir}/%{_vpp_install_dir}/*/bin/* %{buildroot}%{_bindir} install -p -m 755 %{_mu_build_dir}/%{_vpp_build_dir}/vppapigen/vppapigen %{buildroot}%{_bindir} -install -p -m 755 %{_mu_build_dir}/../vppapigen/pyvppapigen.py %{buildroot}%{_bindir} + +# core api +mkdir -p -m755 %{buildroot}/usr/share/vpp/api +install -p -m 755 %{_mu_build_dir}/%{_vpp_install_dir}/vpp/vpp-api/vpe.api.json %{buildroot}/usr/share/vpp/api +install -p -m 755 %{_mu_build_dir}/%{_vpp_install_dir}/vlib-api/vlibmemory/memclnt.api.json %{buildroot}/usr/share/vpp/api + # # configs # @@ -123,6 +128,10 @@ do ( cd %{buildroot}%{_libdir} && ln -fs $file $(echo $file | sed -e 's/\(\.so\)\.[0-9]\+.*/\1/') ) done +for file in $(find %{_mu_build_dir}/%{_vpp_install_dir}/vnet -type f -name '*.api.json' -print ) +do + install -p -m 644 $file %{buildroot}/usr/share/vpp/api +done # Python bindings mkdir -p -m755 %{buildroot}%{python2_sitelib}/vpp_papi @@ -178,6 +187,11 @@ do %{buildroot}/usr/lib/vpp_api_test_plugins/$file done +for file in $(find %{_mu_build_dir}/%{_vpp_install_dir}/plugins -type f -name '*.api.json' -print ) +do + install -p -m 644 $file %{buildroot}/usr/share/vpp/api +done + %post sysctl --system %systemd_post vpp.service @@ -214,12 +228,14 @@ fi /usr/bin/elftool %config /etc/sysctl.d/80-vpp.conf %config /etc/vpp/startup.conf +/usr/share/vpp/api/* %files lib %defattr(-,bin,bin) %exclude %{_libdir}/vpp_plugins %exclude %{_libdir}/vpp_api_test_plugins %{_libdir}/* +/usr/share/vpp/api/* %files python-api %defattr(644,root,root) @@ -229,7 +245,6 @@ fi %defattr(-,bin,bin) /usr/bin/vppapigen /usr/bin/jvpp_gen.py -/usr/bin/pyvppapigen.py %{_includedir}/* %{python2_sitelib}/jvppgen/* /usr/share/doc/vpp/examples/sample-plugin @@ -238,3 +253,4 @@ fi %defattr(-,bin,bin) /usr/lib/vpp_plugins/* /usr/lib/vpp_api_test_plugins/* +/usr/share/vpp/api/* diff --git a/build-root/scripts/find-api-core-contents b/build-root/scripts/find-api-core-contents new file mode 100755 index 00000000000..f1f96f1f12a --- /dev/null +++ b/build-root/scripts/find-api-core-contents @@ -0,0 +1,9 @@ +#!/bin/bash + +for i in $(find ${1}/vpp -name *.api.json -type f -print); do + echo ../${i} /usr/share/vpp/api/ >> ${2} +done +for i in $(find ${1}/vlib-api -name *.api.json -type f -print); do + echo ../${i} /usr/share/vpp/api/ >> ${2} +done + diff --git a/build-root/scripts/find-api-lib-contents b/build-root/scripts/find-api-lib-contents new file mode 100755 index 00000000000..562db7b8446 --- /dev/null +++ b/build-root/scripts/find-api-lib-contents @@ -0,0 +1,6 @@ +#!/bin/bash + +for i in $(find ${1}/vnet -name *.api.json -type f -print); do + echo ../${i} /usr/share/vpp/api/ >> ${2} +done + diff --git a/build-root/scripts/find-plugins-contents b/build-root/scripts/find-plugins-contents index 8d1a4d5ae29..a5a52acf337 100755 --- a/build-root/scripts/find-plugins-contents +++ b/build-root/scripts/find-plugins-contents @@ -9,3 +9,7 @@ done for i in ${1}/plugins/lib64/vpp_api_test_plugins/*.so; do echo ../${i} /usr/lib/vpp_api_test_plugins >> ${2} done + +for i in $(find ${1}/plugins -name *.api.json -type f -print); do + echo ../${i} /usr/share/vpp/api/ >> ${2} +done diff --git a/plugins/flowperpkt-plugin/Makefile.am b/plugins/flowperpkt-plugin/Makefile.am index fe0d8b27c7b..1df758ed6f4 100644 --- a/plugins/flowperpkt-plugin/Makefile.am +++ b/plugins/flowperpkt-plugin/Makefile.am @@ -28,15 +28,26 @@ flowperpkt_plugin_la_SOURCES = flowperpkt/flowperpkt.c \ flowperpkt/flowperpkt_plugin.api.h flowperpkt_plugin_la_LDFLAGS = -module -BUILT_SOURCES = flowperpkt/flowperpkt.api.h +BUILT_SOURCES = \ + flowperpkt/flowperpkt.api.h \ + flowperpkt/flowperpkt.api.json -SUFFIXES = .api.h .api +SUFFIXES = .api.h .api .api.json %.api.h: %.api mkdir -p `dirname $@` ; \ $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ | vppapigen --input - --output $@ --show-name $@ +%.api.json: %.api + @echo " JSON APIGEN " $@ ; \ + mkdir -p `dirname $@` ; \ + $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ + | vppapigen --input - --json $@ + +apidir = $(prefix)/flowperpkt/ +api_DATA = flowperpkt/flowperpkt.api.json + noinst_HEADERS = \ flowperpkt/flowperpkt_all_api_h.h \ flowperpkt/flowperpkt_msg_enum.h \ diff --git a/plugins/ioam-plugin/Makefile.am b/plugins/ioam-plugin/Makefile.am index c66c6cd5e7a..a9ed4ab46fa 100644 --- a/plugins/ioam-plugin/Makefile.am +++ b/plugins/ioam-plugin/Makefile.am @@ -28,7 +28,8 @@ ioam_pot_plugin_la_SOURCES = \ ioam/lib-pot/pot_api.c BUILT_SOURCES = \ - ioam/lib-pot/pot.api.h ioam/lib-pot/pot.py + ioam/lib-pot/pot.api.h \ + ioam/lib-pot/pot.api.json SUFFIXES = .api.h .api @@ -37,14 +38,17 @@ SUFFIXES = .api.h .api $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ | vppapigen --input - --output $@ --show-name $@ -%.py: %.api - $(info Creating Python binding for $@) - $(CC) $(CPPFLAGS) -E -P -C -x c $< \ - | vppapigen --input - --python - \ - | pyvppapigen.py --input - > $@ +%.api.json: %.api + @echo " JSON APIGEN " $@ ; \ + mkdir -p `dirname $@` ; \ + $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ + | vppapigen --input - --json $@ -pyapidir = ${prefix}/vpp_papi_plugins -pyapi_DATA = ioam/lib-pot/pot.py +apidir = $(prefix)/ioam/ +api_DATA = \ + ioam/lib-pot/pot.api.json \ + ioam/lib-trace/trace.api.json \ + ioam/export/ioam_export.api.json noinst_HEADERS = \ ioam/lib-pot/pot_all_api_h.h \ @@ -73,7 +77,9 @@ ioam/export/node.c \ ioam/export/ioam_export.api.h \ ioam/export/ioam_export_thread.c -BUILT_SOURCES += ioam/export/ioam_export.api.h +BUILT_SOURCES += \ + ioam/export/ioam_export.api.h \ + ioam/export/ioam_export.api.json noinst_HEADERS += \ ioam/export/ioam_export_all_api_h.h \ @@ -96,10 +102,9 @@ ioam_trace_plugin_la_SOURCES = \ ioam/lib-trace/trace_util.h \ ioam/lib-trace/trace_api.c -BUILT_SOURCES += \ - ioam/lib-trace/trace.api.h ioam/lib-trace/trace.py - -pyapi_DATA += ioam/lib-trace/trace.py +BUILT_SOURCES += \ + ioam/lib-trace/trace.api.h \ + ioam/lib-trace/trace.api.json noinst_HEADERS += \ ioam/export/ioam_export_all_api_h.h \ diff --git a/plugins/lb-plugin/Makefile.am b/plugins/lb-plugin/Makefile.am index 8d92ff1dfc4..8e36027949e 100644 --- a/plugins/lb-plugin/Makefile.am +++ b/plugins/lb-plugin/Makefile.am @@ -24,13 +24,26 @@ vppplugins_LTLIBRARIES = lb_plugin.la lb_plugin_la_SOURCES = lb/lb.c lb/node.c lb/cli.c lb/util.c lb/refcount.c lb/api.c -SUFFIXES = .api.h .api +BUILT_SOURCES = \ + lb/lb.api.h \ + lb/lb.api.json + +SUFFIXES = .api.h .api .api.json %.api.h: %.api mkdir -p `dirname $@` ; \ $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ | vppapigen --input - --output $@ --show-name $@ +%.api.json: %.api + @echo " JSON APIGEN " $@ ; \ + mkdir -p `dirname $@` ; \ + $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ + | vppapigen --input - --json $@ + +apidir = $(prefix)/lb/ +api_DATA = lb/lb.api.json + noinst_HEADERS = lb/lb.h lb/util.h lb/refcount.h lb/lbhash.h lb/lb.api.h lb_test_plugin_la_SOURCES = \ diff --git a/plugins/sample-plugin/Makefile.am b/plugins/sample-plugin/Makefile.am index 0b213791c1a..e221f8c1aa9 100644 --- a/plugins/sample-plugin/Makefile.am +++ b/plugins/sample-plugin/Makefile.am @@ -25,7 +25,7 @@ vppplugins_LTLIBRARIES = sample_plugin.la sample_plugin_la_SOURCES = sample/sample.c sample/node.c \ sample/sample_plugin.api.h -BUILT_SOURCES = sample/sample.api.h +BUILT_SOURCES = sample/sample.api.h sample/sample.api.json SUFFIXES = .api.h .api @@ -34,6 +34,15 @@ SUFFIXES = .api.h .api $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ | vppapigen --input - --output $@ --show-name $@ +%.api.json: %.api + @echo " JSON APIGEN " $@ ; \ + mkdir -p `dirname $@` ; \ + $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ + | vppapigen --input - --json $@ + +apidir = $(prefix)/sample/ +api_DATA = sample.api.json + noinst_HEADERS = \ sample/sample_all_api_h.h \ sample/sample_msg_enum.h \ diff --git a/plugins/snat-plugin/Makefile.am b/plugins/snat-plugin/Makefile.am index cdf7e3569c5..f10ba25e097 100644 --- a/plugins/snat-plugin/Makefile.am +++ b/plugins/snat-plugin/Makefile.am @@ -28,7 +28,7 @@ snat_plugin_la_SOURCES = snat/snat.c \ snat/out2in.c \ snat/snat_plugin.api.h -BUILT_SOURCES = snat/snat.api.h snat/snat.py +BUILT_SOURCES = snat/snat.api.h snat/snat.api.json SUFFIXES = .api.h .api @@ -37,14 +37,14 @@ SUFFIXES = .api.h .api $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ | vppapigen --input - --output $@ --show-name $@ -%.py: %.api - $(info Creating Python binding for $@) - $(CC) $(CPPFLAGS) -E -P -C -x c $< \ - | vppapigen --input - --python - \ - | pyvppapigen.py --input - > $@ +%.api.json: %.api + @echo " JSON APIGEN " $@ ; \ + mkdir -p `dirname $@` ; \ + $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ + | vppapigen --input - --json $@ -pyapidir = ${prefix}/vpp_papi_plugins -pyapi_DATA = snat/snat.py +apidir = $(prefix)/snat/ +api_DATA = snat.api.json noinst_HEADERS = \ snat/snat_all_api_h.h \ @@ -60,7 +60,7 @@ install-data-hook: @(cd $(vppapitestpluginsdir) && $(RM) $(vppapitestplugins_LTLIBRARIES)) apidir = $(prefix)/snat -api_DATA = snat/snat.api +api_DATA = snat/snat.api.json # # Java code generation diff --git a/vlib-api/Makefile.am b/vlib-api/Makefile.am index 087d56eec3a..d9f4a27b762 100644 --- a/vlib-api/Makefile.am +++ b/vlib-api/Makefile.am @@ -67,9 +67,12 @@ nobase_include_HEADERS += \ vlibsocket/vl_socket_msg_enum.h \ vlibsocket/sockclnt.api.h -BUILT_SOURCES = vlibsocket/sockclnt.api.h vlibmemory/memclnt.api.h +BUILT_SOURCES = \ + vlibsocket/sockclnt.api.h \ + vlibmemory/memclnt.api.h \ + vlibmemory/memclnt.api.json -SUFFIXES = .api.h .api +SUFFIXES = .api.h .api .api.json # The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk # and requires a symbolic link at the top of the vnet source tree @@ -78,4 +81,4 @@ include $(top_srcdir)/suffix-rules.mk # install the API definition, so we can produce java bindings, etc. apidir = $(prefix)/vlibmemory -api_DATA = vlibmemory/memclnt.api +api_DATA = vlibmemory/memclnt.api.json diff --git a/vnet/Makefile.am b/vnet/Makefile.am index a9481d11dc2..0ba07bac5bd 100644 --- a/vnet/Makefile.am +++ b/vnet/Makefile.am @@ -15,7 +15,7 @@ AUTOMAKE_OPTIONS = foreign subdir-objects AM_CFLAGS = -Wall -Werror @DPDK@ @DPDK_CRYPTO@ @IPSEC@ @IPV6SR@ -BUILT_SOURCES = vnet/interface.api.h +BUILT_SOURCES = vnet/interface.api.h vnet/interface.api.json libvnet_la_SOURCES = libvnetplugin_la_SOURCES = @@ -884,12 +884,12 @@ pcap2pg_LDADD = libvnet.la -l:libvppinfra.a -lpthread -lm -ldl noinst_PROGRAMS += pcap2pg # Set the suffix list -SUFFIXES = .api.h .api +SUFFIXES = .api.h .api .api.json # install the API definition, so we can produce java bindings, etc. -apidir = $(prefix)/vpp-api -api_DATA = vnet/interface.api +apidir = $(prefix)/vnet +api_DATA = vnet/interface.api.json # The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk # and requires a symbolic link at the top of the vnet source tree diff --git a/vpp-api/Makefile.am b/vpp-api/Makefile.am index 310bd2321eb..1812b63765c 100644 --- a/vpp-api/Makefile.am +++ b/vpp-api/Makefile.am @@ -1,17 +1,2 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = python java - -api_json_dir = $(abs_builddir)/vpp-api -api_srcs:=$(shell find $(prefix)/../ -name '*.api') -api_json:=$(patsubst %.api,$(api_json_dir)/%.api.json,$(notdir $(api_srcs))) - -define define_compile_rules -$(api_json_dir)/%.api.json: $(1)%.api - @echo " + Generating '$$<'" - @mkdir -p $$(@D) - $(CC) $$(CPPFLAGS) -E -P -C -x c $$< | vppapigen --input - --json $$@ -endef - -$(foreach directory,$(dir $(api_srcs)),$(eval $(call define_compile_rules,$(directory)))) - -BUILT_SOURCES = $(api_json) diff --git a/vpp-api/java/Makefile.am b/vpp-api/java/Makefile.am index af4c3f31923..f2f5fbe5b2a 100644 --- a/vpp-api/java/Makefile.am +++ b/vpp-api/java/Makefile.am @@ -83,14 +83,14 @@ packagedir_jvpp_core = io/fd/vpp/jvpp/core BUILT_SOURCES += jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h -jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJNIConnection.h $(abs_builddir)/../vpp-api/vpe.api.json +jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJNIConnection.h $(prefix)/../vpp/vpp-api/vpe.api.json cp -rf @srcdir@/jvpp-core/* -t jvpp-core/ mkdir -p jvpp-core/target cd jvpp-core \ && mkdir -p types dto future callfacade callback notification \ && @srcdir@/jvpp/gen/jvpp_gen.py --plugin_name core \ - -i $(abs_builddir)/../vpp-api/vpe.api.json \ - $(abs_builddir)/../vpp-api/interface.api.json \ + -i $(prefix)/../vpp/vpp-api/vpe.api.json \ + $(prefix)/../vnet/vnet/interface.api.json \ && cp -rf types dto future callfacade callback notification *.java -t $(packagedir_jvpp_core) \ && rm -rf types dto future callfacade callback notification *.java diff --git a/vpp-api/python/Makefile.am b/vpp-api/python/Makefile.am index d2c3fb5dd4e..2a578464d0f 100644 --- a/vpp-api/python/Makefile.am +++ b/vpp-api/python/Makefile.am @@ -32,23 +32,8 @@ libpneum_la_LIBADD = -lvlibmemoryclient -lvlibapi -lsvm -lvppinfra -lpthread \ libpneum_la_LDFLAGS = -module libpneum_la_CPPFLAGS = -# -# Core VPP API -# -$(srcdir)/vpp_papi/vpe.py: $(prefix)/../vpp/vpp-api/vpe.api - $(info Creating Python binding for $@) - $(CC) $(CPPFLAGS) -E -P -C -x c $< \ - | vppapigen --input - --python - \ - | pyvppapigen.py --input - > $(srcdir)/vpp_papi/$(notdir $@) - -$(srcdir)/vpp_papi/memclnt.py: $(prefix)/../vlib-api/vlibmemory/memclnt.api - $(info Creating Python binding for $@) - $(CC) $(CPPFLAGS) -E -P -C -x c $< \ - | vppapigen --input - --python - \ - | pyvppapigen.py --input - > $(srcdir)/vpp_papi/$(notdir $@) - # TODO: Support both Python 2 and 3. -install-exec-local: $(srcdir)/vpp_papi/vpe.py $(srcdir)/vpp_papi/memclnt.py +install-exec-local: cd $(srcdir); \ mkdir -p $(prefix)/lib/python2.7/site-packages; \ PYTHONUSERBASE=$(prefix) \ diff --git a/vpp/Makefile.am b/vpp/Makefile.am index 1c40ed3d57e..9ae06055172 100644 --- a/vpp/Makefile.am +++ b/vpp/Makefile.am @@ -46,9 +46,9 @@ nobase_include_HEADERS = \ # install the API definition, so we can produce java bindings, etc. apidir = $(prefix)/vpp-api -api_DATA = vpp-api/vpe.api +api_DATA = vpp-api/vpe.api.json -BUILT_SOURCES += vpp-api/vpe.api.h app/version.h +BUILT_SOURCES += vpp-api/vpe.api.h app/version.h vpp-api/vpe.api.json app/version.o: app/version.h @@ -122,7 +122,7 @@ if WITH_IPV6SR endif # Set the suffix list -SUFFIXES = .api.h .api +SUFFIXES = .api.h .api .api.json # The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk # and requires a symbolic link at the top of the vpp source tree diff --git a/vppapigen/Makefile.am b/vppapigen/Makefile.am index 066e1c30d27..16a4873696c 100644 --- a/vppapigen/Makefile.am +++ b/vppapigen/Makefile.am @@ -14,7 +14,7 @@ AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = vppapigen -bin_SCRIPTS = pyvppapigen.py +bin_SCRIPTS = BUILT_SOURCES = gram.h diff --git a/vppapigen/pyvppapigen.py b/vppapigen/pyvppapigen.py deleted file mode 100755 index ea669517c3e..00000000000 --- a/vppapigen/pyvppapigen.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (c) 2016 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import print_function -import argparse, sys, os, importlib, pprint - -parser = argparse.ArgumentParser(description='VPP Python API generator') -parser.add_argument('-i', '--input', action="store", dest="inputfile", type=argparse.FileType('r')) -parser.add_argument('-c', '--cfile', action="store") -args = parser.parse_args() - -# -# Read API definitions file into vppapidefs -# -exec(args.inputfile.read()) - -# https://docs.python.org/3/library/struct.html -format_struct = {'u8': 'B', - 'u16' : 'H', - 'u32' : 'I', - 'i32' : 'i', - 'u64' : 'Q', - 'f64' : 'd', - 'vl_api_fib_path_t' : 'IIBBBBBBBBBBBBBBBBBBBBB', - 'vl_api_ip4_fib_counter_t' : 'IBQQ', - 'vl_api_ip6_fib_counter_t' : 'QQBQQ', - 'vl_api_lisp_adjacency_t' : 'B' * 35 - }; -# -# NB: If new types are introduced in vpe.api, these must be updated. -# -type_size = {'u8': 1, - 'u16' : 2, - 'u32' : 4, - 'i32' : 4, - 'u64' : 8, - 'f64' : 8, - 'vl_api_fib_path_t' : 29, - 'vl_api_ip4_fib_counter_t' : 21, - 'vl_api_ip6_fib_counter_t' : 33, - 'vl_api_lisp_adjacency_t' : 35 -}; - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - -def get_args(t): - argslist = [] - for i in t: - if i[1][0] == '_': - argslist.append(i[1][1:]) - else: - argslist.append(i[1]) - - return argslist - -def get_pack(f): - zeroarray = False - bytecount = 0 - pack = '' - elements = 1 - if len(f) is 3 or len(f) is 4: - size = type_size[f[0]] - bytecount += size * int(f[2]) - # Check if we have a zero length array - if f[2] == '0': - # If len 3 zero array - elements = 0; - pack += format_struct[f[0]] - bytecount = size - elif size == 1: - n = f[2] * size - pack += str(n) + 's' - else: - pack += format_struct[f[0]] * int(f[2]) - elements = int(f[2]) - else: - bytecount += type_size[f[0]] - pack += format_struct[f[0]] - return (pack, elements, bytecount) - - -''' -def get_reply_func(f): - if f['name']+'_reply' in func_name: - return func_name[f['name']+'_reply'] - if f['name'].find('_dump') > 0: - r = f['name'].replace('_dump','_details') - if r in func_name: - return func_name[r] - return None -''' - -def footer_print(): - print(''' -def msg_id_base_set(b): - global base - base = b - -import os -name = os.path.splitext(os.path.basename(__file__))[0] - ''') - print(u"plugin_register(name, api_func_table, api_name_to_id,", vl_api_version, ", msg_id_base_set)") - -def api_table_print(name, i): - msg_id_in = 'VL_API_' + name.upper() - fstr = name + '_decode' - print('api_func_table.append(' + fstr + ')') - print('api_name_to_id["' + msg_id_in + '"] =', i) - print('') - - -def encode_print(name, id, t): - args = get_args(t) - - if name.find('_dump') > 0: - multipart = True - else: - multipart = False - - if len(args) < 4: - print(u"def", name + "(async = False):") - else: - print(u"def", name + "(" + ', '.join(args[3:]) + ", async = False):") - print(u" global base") - print(u" context = get_context(base + " + id + ")") - - print(''' - results_prepare(context) - waiting_for_reply_set() - ''') - if multipart == True: - print(u" results_more_set(context)") - - t = list(t) - - # only the last field can be a variable-length-array - # it can either be 0, or a string - # first, deal with all the other fields - pack = '>' + ''.join([get_pack(f)[0] for f in t[:-1]]) - - # named variable-length-array - if len(t[-1]) == 4 and t[-1][2] == '0' and t[-1][3] == t[-2][1]: - print(u" vpp_api.write(pack('" + pack + "', base + " - + id + ", 0, context, " + ', '.join(args[3:-2] + ["len(" + args[-1] + ")"]) - + ") + " + args[-1] + ")") - - # unnamed variable-length-array - elif len(t[-1]) >= 3 and t[-1][2] == '0': - print(u" vpp_api.write(pack('" + pack + "', base + " + - id + ", 0, context, " + ', '.join(args[3:-1]) + ") + " - + args[-1] + ")") - - - # not a variable-length-array - else: - pack += get_pack(t[-1])[0] - print(u" vpp_api.write(pack('" + pack + "', base + " + id + - ", 0, context, " + ', '.join(args[3:]) + "))") - - if multipart == True: - print( - u" vpp_api.write(pack('>HII', VL_API_CONTROL_PING, 0, context))") - - print(''' - if not async: - results_event_wait(context, 5) - return results_get(context) - return context - ''') - -def get_normal_pack(t, i, pack, offset): - while t: - f = t.pop(0) - i += 1 - if len(f) >= 3: - return t, i, pack, offset, f - p, elements, size = get_pack(f) - pack += p - offset += size - return t, i, pack, offset, None - -def decode_print(name, t): - # - # Generate code for each element - # - print(u'def ' + name + u'_decode(msg):') - total = 0 - args = get_args(t) - print(u" n = namedtuple('" + name + "', '" + ', '.join(args) + "')") - print(u" res = []") - - pack = '>' - start = 0 - end = 0 - offset = 0 - t = list(t) - i = 0 - while t: - t, i, pack, offset, array = get_normal_pack(t, i, pack, offset) - if array: - p, elements, size = get_pack(array) - - # Byte string - if elements > 0 and type_size[array[0]] == 1: - pack += p - offset += size * elements - continue - - # Dump current pack string - if pack != '>': - print(u" tr = unpack_from('" + pack + "', msg[" + str(start) + ":])") - print(u" res.extend(list(tr))") - start += offset - pack = '>' - - if elements == 0: - # This has to be the last element - if len(array) == 3: - print(u" res.append(msg[" + str(offset) + ":])") - if len(t) > 0: - eprint('WARNING: Variable length array must be last element in message', name, array) - - continue - if size == 1 or len(p) == 1: - # Do it as a bytestring. - if p == 'B': - p = 's' - # XXX: Assume that length parameter is the previous field. Add validation. - print(u" c = res[" + str(i - 2) + "]") - print(u" tr = unpack_from('>' + str(c) + '" + p + "', msg[" + str(start) + ":])") - print(u" res.append(tr)") - continue - print(u" tr2 = []") - print(u" offset = " + str(total)) - print(u" for j in range(res[" + str(i - 2) + "]):") - print(u" tr2.append(unpack_from('>" + p + "', msg[" + str(start) + ":], offset))") - print(u" offset += " + str(size)) - print(u" res.append(tr2)") - continue - - # Missing something!! - print(u" tr = unpack_from('>" + p + "', msg[" + str(start) + ":])") - start += size - - print(u" res.append(tr)") - - if pack != '>': - print(u" tr = unpack_from('" + pack + "', msg[" + str(start) + ":])") - print(u" res.extend(list(tr))") - print(u" return n._make(res)") - print('') - -# -# Generate the main Python file -# -def main(): - print(''' -# -# AUTO-GENERATED FILE. PLEASE DO NOT EDIT. -# -from vpp_api_base import * -from struct import * -from collections import namedtuple -import vpp_api -api_func_table = [] -api_name_to_id = {} - ''') - - for i, a in enumerate(messages): - name = a[0] - encode_print(name, str(i), a[1:]) - decode_print(name, a[1:]) - api_table_print(name, i) - footer_print() - -if __name__ == "__main__": - main()