diff options
93 files changed, 423 insertions, 692 deletions
diff --git a/Makefile.am b/Makefile.am index ce0f70a1a..8c7bde9d4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,7 +144,6 @@ pkginclude_HEADERS = nodist_pkginclude_HEADERS = dist_yangmodels_DATA = man_MANS = -vtysh_scan = vtysh_daemons = clippy_scan = @@ -226,6 +225,7 @@ EXTRA_DIST += \ python/makefile.py \ python/tiabwarfo.py \ python/xrelfo.py \ + python/xref2vtysh.py \ python/test_xrelfo.py \ python/runtests.py \ \ diff --git a/babeld/subdir.am b/babeld/subdir.am index 856cbd13e..4b9037283 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -4,11 +4,6 @@ if BABELD sbin_PROGRAMS += babeld/babeld -vtysh_scan += \ - babeld/babel_interface.c \ - babeld/babel_zebra.c \ - babeld/babeld.c \ - # end vtysh_daemons += babeld endif diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index 69424c45d..52f2dd8fd 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -26,9 +26,7 @@ #include "lib/log.h" #include "lib/northbound_cli.h" -#ifndef VTYSH_EXTRACT_PL #include "bfdd/bfdd_cli_clippy.c" -#endif /* VTYSH_EXTRACT_PL */ #include "bfd.h" #include "bfdd_nb.h" diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index 4a2c5bf66..7b7a001e2 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -28,9 +28,7 @@ #include "bfd.h" -#ifndef VTYSH_EXTRACT_PL #include "bfdd/bfdd_vty_clippy.c" -#endif /* * Commands help string definitions. diff --git a/bfdd/subdir.am b/bfdd/subdir.am index 8d35b933d..b86a18967 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -5,8 +5,6 @@ if BFDD noinst_LIBRARIES += bfdd/libbfd.a sbin_PROGRAMS += bfdd/bfdd -vtysh_scan += bfdd/bfdd_vty.c -vtysh_scan += bfdd/bfdd_cli.c vtysh_daemons += bfdd man8 += $(MANBUILD)/frr-bfdd.8 endif diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index bcab4099c..2cb85cb1d 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -2033,9 +2033,7 @@ static const struct cmd_variable_handler bmp_targets_var_handlers[] = { #define BMP_STR "BGP Monitoring Protocol\n" -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_bmp_clippy.c" -#endif DEFPY_NOSH(bmp_targets_main, bmp_targets_cmd, diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 580c18b58..8c75f4830 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -1410,9 +1410,7 @@ DEFUN (no_debug_bgp_update_direct_peer, return CMD_SUCCESS; } -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_debug_clippy.c" -#endif DEFPY (debug_bgp_update_prefix_afi_safi, debug_bgp_update_prefix_afi_safi_cmd, diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 24fa2b2a5..e19a58266 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -3336,9 +3336,7 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn) } } -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_evpn_vty_clippy.c" -#endif DEFPY(bgp_evpn_flood_control, bgp_evpn_flood_control_cmd, diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index c227a5e41..129878451 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -39,9 +39,7 @@ #define BGP_LABELPOOL_ENABLE_TESTS 0 -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_labelpool_clippy.c" -#endif /* diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f6b6cb93d..701c3779e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -90,9 +90,7 @@ #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_pbr.h" -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_route_clippy.c" -#endif DEFINE_HOOK(bgp_snmp_update_stats, (struct bgp_node *rn, struct bgp_path_info *pi, bool added), diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 233fd55ef..9aade05d6 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -74,9 +74,7 @@ #include "bgpd/rfapi/bgp_rfapi_cfg.h" #endif -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_routemap_clippy.c" -#endif /* Memo of route-map commands. diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index cb7afd896..2acf74c52 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -52,16 +52,12 @@ #include "lib/network.h" #include "lib/thread.h" -#ifndef VTYSH_EXTRACT_PL #include "rtrlib/rtrlib.h" -#endif #include "hook.h" #include "libfrr.h" #include "lib/version.h" -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_rpki_clippy.c" -#endif DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server"); DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group"); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f380460a9..9c1159968 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1316,9 +1316,7 @@ void bgp_clear_soft_in(struct bgp *bgp, afi_t afi, safi_t safi) bgp_clear(NULL, bgp, afi, safi, clear_all, BGP_CLEAR_SOFT_IN, NULL); } -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_vty_clippy.c" -#endif DEFUN_HIDDEN (bgp_local_mac, bgp_local_mac_cmd, diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 765650313..04fe1f124 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -6,36 +6,9 @@ if BGPD noinst_LIBRARIES += bgpd/libbgp.a sbin_PROGRAMS += bgpd/bgpd noinst_PROGRAMS += bgpd/bgp_btoa -vtysh_scan += \ - bgpd/bgp_bfd.c \ - bgpd/bgp_debug.c \ - bgpd/bgp_dump.c \ - bgpd/bgp_evpn_mh.c \ - bgpd/bgp_evpn_vty.c \ - bgpd/bgp_filter.c \ - bgpd/bgp_labelpool.c \ - bgpd/bgp_mplsvpn.c \ - bgpd/bgp_nexthop.c \ - bgpd/bgp_route.c \ - bgpd/bgp_routemap.c \ - bgpd/bgp_vty.c \ - bgpd/bgp_flowspec_vty.c \ - # end - -# can be loaded as DSO - always include for vtysh -vtysh_scan += bgpd/bgp_rpki.c -vtysh_scan += bgpd/bgp_bmp.c vtysh_daemons += bgpd -if ENABLE_BGP_VNC -vtysh_scan += \ - bgpd/rfapi/bgp_rfapi_cfg.c \ - bgpd/rfapi/rfapi.c \ - bgpd/rfapi/rfapi_vty.c \ - bgpd/rfapi/vnc_debug.c \ - # end -endif if SNMP module_LTLIBRARIES += bgpd/bgpd_snmp.la endif diff --git a/configure.ac b/configure.ac index 4cbdfe0fc..1a481ecd7 100644 --- a/configure.ac +++ b/configure.ac @@ -2747,7 +2747,6 @@ AC_CONFIG_FILES([ pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh pkgsrc/eigrpd.sh]) -AC_CONFIG_FILES([vtysh/extract.pl], [chmod +x vtysh/extract.pl]) AC_CONFIG_FILES([tools/frr], [chmod +x tools/frr]) AC_CONFIG_FILES([tools/watchfrr.sh], [chmod +x tools/watchfrr.sh]) AC_CONFIG_FILES([tools/frrinit.sh], [chmod +x tools/frrinit.sh]) diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst index ff6c4f6e1..d51f06d11 100644 --- a/doc/developer/cli.rst +++ b/doc/developer/cli.rst @@ -453,9 +453,7 @@ all DEFPY statements**: /* GPL header */ #include ... ... - #ifndef VTYSH_EXTRACT_PL #include "daemon/filename_clippy.c" - #endif DEFPY(...) DEFPY(...) diff --git a/doc/developer/vtysh.rst b/doc/developer/vtysh.rst index 160676a7b..323ea57c1 100644 --- a/doc/developer/vtysh.rst +++ b/doc/developer/vtysh.rst @@ -43,9 +43,14 @@ simplifying the output. This is discussed in :ref:`vtysh-configuration`. Command Extraction ------------------ -When VTYSH is built, a Perl script named :file:`extract.pl` searches the FRR -codebase looking for ``DEFUN``'s. It extracts these ``DEFUN``'s, transforms -them into ``DEFSH``'s and appends them to ``vtysh_cmd.c``. Each ``DEFSH`` +To build ``vtysh``, the :file:`python/xref2vtysh.py` script scans through the +:file:`frr.xref` file created earlier in the build process. This file contains +a list of all ``DEFUN`` and ``install_element`` sites in the code, generated +directly from the binaries (and therefore matching exactly what is really +available.) + +This list is collated and transformed into ``DEFSH`` (and ``install_element``) +statements, output to ``vtysh_cmd.c``. Each ``DEFSH`` contains the name of the command plus ``_vtysh``, as well as a flag that indicates which daemons the command was found in. When the command is executed in VTYSH, this flag is inspected to determine which daemons to send the command @@ -55,6 +60,12 @@ avoiding spurious errors from daemons that don't have the command defined. The extraction script contains lots of hardcoded knowledge about what sources to look at and what flags to use for certain commands. +.. note:: + + The ``vtysh_scan`` Makefile variable and ``#ifndef VTYSH_EXTRACT_PL`` + checks in source files are no longer used. Remove them when rebasing older + changes. + .. _vtysh-special-defuns: Special DEFUNs @@ -69,7 +80,7 @@ several VTYSH-specific ``DEFUN`` variants that each serve different purposes. simply forwarded to the daemons indicated in the daemon flag. ``DEFUN_NOSH`` - Used by daemons. Has the same expansion as a ``DEFUN``, but ``extract.pl`` + Used by daemons. Has the same expansion as a ``DEFUN``, but ``xref2vtysh.py`` will skip these definitions when extracting commands. This is typically used when VTYSH must take some special action upon receiving the command, and the programmer therefore needs to write VTYSH's copy of the command manually diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c index 744f5f9c7..2afd9d5ea 100644 --- a/eigrpd/eigrp_cli.c +++ b/eigrpd/eigrp_cli.c @@ -31,9 +31,7 @@ #include "eigrp_zebra.h" #include "eigrp_cli.h" -#ifndef VTYSH_EXTRACT_PL #include "eigrpd/eigrp_cli_clippy.c" -#endif /* VTYSH_EXTRACT_PL */ /* * XPath: /frr-eigrpd:eigrpd/instance diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 3d61294b2..137f9b028 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -55,9 +55,7 @@ #include "eigrpd/eigrp_dump.h" #include "eigrpd/eigrp_const.h" -#ifndef VTYSH_EXTRACT_PL #include "eigrpd/eigrp_vty_clippy.c" -#endif static void eigrp_vty_display_prefix_entry(struct vty *vty, struct eigrp *eigrp, struct eigrp_prefix_descriptor *pe, diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 3b647e060..e417132b5 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -4,12 +4,6 @@ if EIGRPD sbin_PROGRAMS += eigrpd/eigrpd -vtysh_scan += \ - eigrpd/eigrp_cli.c \ - eigrpd/eigrp_dump.c \ - eigrpd/eigrp_vty.c \ - # end -# eigrpd/eigrp_routemap.c vtysh_daemons += eigrpd man8 += $(MANBUILD)/frr-eigrpd.8 endif diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 9db867e2c..3650984f1 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -37,9 +37,7 @@ #include "isisd/isis_circuit.h" #include "isisd/isis_csm.h" -#ifndef VTYSH_EXTRACT_PL #include "isisd/isis_cli_clippy.c" -#endif #ifndef FABRICD diff --git a/isisd/subdir.am b/isisd/subdir.am index 3e5816c16..dabf6a925 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -5,16 +5,6 @@ if ISISD noinst_LIBRARIES += isisd/libisis.a sbin_PROGRAMS += isisd/isisd -vtysh_scan += \ - isisd/isis_cli.c \ - isisd/isis_ldp_sync.c \ - isisd/isis_redist.c \ - isisd/isis_spf.c \ - isisd/isis_te.c \ - isisd/isis_sr.c \ - isisd/isis_vty_fabricd.c \ - isisd/isisd.c \ - # end vtysh_daemons += isisd if SNMP module_LTLIBRARIES += isisd/isisd_snmp.la @@ -25,18 +15,6 @@ endif if FABRICD noinst_LIBRARIES += isisd/libfabric.a sbin_PROGRAMS += isisd/fabricd -if !ISISD -vtysh_scan += \ - isisd/isis_cli.c \ - isisd/isis_ldp_sync.c \ - isisd/isis_redist.c \ - isisd/isis_spf.c \ - isisd/isis_te.c \ - isisd/isis_sr.c \ - isisd/isis_vty_fabricd.c \ - isisd/isisd.c \ - # end -endif vtysh_daemons += fabricd endif diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c index 3d11d3137..33e6b297c 100644 --- a/ldpd/ldp_vty_cmds.c +++ b/ldpd/ldp_vty_cmds.c @@ -25,9 +25,7 @@ #include "ldpd/ldpd.h" #include "ldpd/ldp_vty.h" -#ifndef VTYSH_EXTRACT_PL #include "ldpd/ldp_vty_cmds_clippy.c" -#endif DEFPY_NOSH(ldp_mpls_ldp, ldp_mpls_ldp_cmd, diff --git a/ldpd/subdir.am b/ldpd/subdir.am index 083effb70..0b948adb6 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -5,7 +5,6 @@ if LDPD noinst_LIBRARIES += ldpd/libldp.a sbin_PROGRAMS += ldpd/ldpd -vtysh_scan += ldpd/ldp_vty_cmds.c vtysh_daemons += ldpd man8 += $(MANBUILD)/frr-ldpd.8 endif diff --git a/lib/command.h b/lib/command.h index f4168dedd..31e5cad23 100644 --- a/lib/command.h +++ b/lib/command.h @@ -251,9 +251,6 @@ struct cmd_node { /* Argc max counts. */ #define CMD_ARGC_MAX 256 -/* Turn off these macros when using cpp with extract.pl */ -#ifndef VTYSH_EXTRACT_PL - /* helper defines for end-user DEFUN* macros */ #define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \ static const struct cmd_element cmdname = { \ @@ -370,8 +367,6 @@ struct cmd_node { #define ALIAS_YANG(funcname, cmdname, cmdstr, helpstr) \ ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG) -#endif /* VTYSH_EXTRACT_PL */ - /* Some macroes */ /* @@ -511,7 +506,6 @@ struct xref_install_element { enum node_type node_type; }; -#ifndef VTYSH_EXTRACT_PL #define install_element(node_type_, cmd_element_) do { \ static const struct xref_install_element _xref \ __attribute__((used)) = { \ @@ -523,7 +517,6 @@ struct xref_install_element { XREF_LINK(_xref.xref); \ _install_element(node_type_, cmd_element_); \ } while (0) -#endif extern void _install_element(enum node_type, const struct cmd_element *); diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 9a877a570..e0f0f177e 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -31,9 +31,7 @@ #include "lib/plist_int.h" #include "lib/printfrr.h" -#ifndef VTYSH_EXTRACT_PL #include "lib/filter_cli_clippy.c" -#endif /* VTYSH_EXTRACT_PL */ #define ACCESS_LIST_STR "Access list entry\n" #define ACCESS_LIST_ZEBRA_STR "Access list name\n" @@ -35,9 +35,7 @@ #include "buffer.h" #include "log.h" #include "northbound_cli.h" -#ifndef VTYSH_EXTRACT_PL #include "lib/if_clippy.c" -#endif DEFINE_MTYPE_STATIC(LIB, IF, "Interface"); DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected"); diff --git a/lib/log_vty.c b/lib/log_vty.c index c9268734c..4091c92c7 100644 --- a/lib/log_vty.c +++ b/lib/log_vty.c @@ -29,9 +29,7 @@ #include "lib/printfrr.h" #include "lib/systemd.h" -#ifndef VTYSH_EXTRACT_PL #include "lib/log_vty_clippy.c" -#endif #define ZLOG_MAXLVL(a, b) MAX(a, b) diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 7284d6cea..f342f50e8 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -28,9 +28,7 @@ #include <command.h> #include <jhash.h> -#ifndef VTYSH_EXTRACT_PL #include "lib/nexthop_group_clippy.c" -#endif DEFINE_MTYPE_STATIC(LIB, NEXTHOP_GROUP, "Nexthop Group"); diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 56eac9dc3..e0dcdb490 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -32,9 +32,7 @@ #include "northbound.h" #include "northbound_cli.h" #include "northbound_db.h" -#ifndef VTYSH_EXTRACT_PL #include "lib/northbound_cli_clippy.c" -#endif struct debug nb_dbg_cbs_config = {0, "Northbound callbacks: configuration"}; struct debug nb_dbg_cbs_state = {0, "Northbound callbacks: state"}; diff --git a/lib/plist.c b/lib/plist.c index ff2a59ba2..17e692d13 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1193,9 +1193,7 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name, return CMD_SUCCESS; } -#ifndef VTYSH_EXTRACT_PL #include "lib/plist_clippy.c" -#endif DEFPY (show_ip_prefix_list, show_ip_prefix_list_cmd, diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 6be5d15ec..9adaed91e 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -26,9 +26,7 @@ #include "lib/northbound_cli.h" #include "lib/routemap.h" -#ifndef VTYSH_EXTRACT_PL #include "lib/routemap_cli_clippy.c" -#endif /* VTYSH_EXTRACT_PL */ #define ROUTE_MAP_CMD_STR \ "Create route-map or enter route-map command mode\n" \ diff --git a/lib/subdir.am b/lib/subdir.am index e04e700eb..ea6cb9339 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -139,27 +139,6 @@ nodist_lib_libfrr_la_SOURCES = \ yang/frr-module-translator.yang.c \ # end -vtysh_scan += \ - lib/distribute.c \ - lib/filter.c \ - lib/filter_cli.c \ - lib/if.c \ - lib/if_rmap.c \ - lib/keychain.c \ - lib/lib_vty.c \ - lib/log_vty.c \ - lib/nexthop_group.c \ - lib/plist.c \ - lib/routemap.c \ - lib/routemap_cli.c \ - lib/spf_backoff.c \ - lib/thread.c \ - lib/vrf.c \ - lib/vty.c \ - # end -# can be loaded as DSO - always include for vtysh -vtysh_scan += lib/agentx.c - if SQLITE3 lib_libfrr_la_LIBADD += $(SQLITE3_LIBS) lib_libfrr_la_SOURCES += lib/db.c @@ -347,7 +326,6 @@ lib_libfrrsnmp_la_SOURCES = \ if CARES lib_LTLIBRARIES += lib/libfrrcares.la pkginclude_HEADERS += lib/resolver.h -vtysh_scan += lib/resolver.c endif lib_libfrrcares_la_CFLAGS = $(AM_CFLAGS) $(CARES_CFLAGS) @@ -478,13 +456,18 @@ SUFFIXES += .xref # dependencies added in python/makefile.py frr.xref: - $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ $^ + $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ -c vtysh/vtysh_cmd.c $^ all-am: frr.xref clean-xref: -rm -rf $(xrefs) frr.xref clean-local: clean-xref +CLEANFILES += vtysh/vtysh_cmd.c +vtysh/vtysh_cmd.c: frr.xref + @test -f $@ || rm -f frr.xref || true + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) frr.xref + ## automake's "ylwrap" is a great piece of GNU software... not. .l.c: $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< diff --git a/lib/thread.c b/lib/thread.c index 9eac9b410..4078634f7 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -102,9 +102,7 @@ unsigned long cputime_threshold = CONSUMED_TIME_CHECK; unsigned long walltime_threshold = CONSUMED_TIME_CHECK; /* CLI start ---------------------------------------------------------------- */ -#ifndef VTYSH_EXTRACT_PL #include "lib/thread_clippy.c" -#endif static unsigned int cpu_record_hash_key(const struct cpu_thread_history *a) { @@ -53,9 +53,7 @@ #include <arpa/telnet.h> #include <termios.h> -#ifndef VTYSH_EXTRACT_PL #include "lib/vty_clippy.c" -#endif DEFINE_MTYPE_STATIC(LIB, VTY, "VTY"); DEFINE_MTYPE_STATIC(LIB, VTY_SERV, "VTY server"); diff --git a/lib/zebra.h b/lib/zebra.h index 53ae5b4e9..b2f5e5a84 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -202,9 +202,9 @@ #endif /* HAVE_GLIBC_BACKTRACE */ /* Local includes: */ -#if !(defined(__GNUC__) || defined(VTYSH_EXTRACT_PL)) +#if !defined(__GNUC__) #define __attribute__(x) -#endif /* !__GNUC__ || VTYSH_EXTRACT_PL */ +#endif /* !__GNUC__ */ #include <assert.h> diff --git a/lib/zlog_5424_cli.c b/lib/zlog_5424_cli.c index dd8dbfaff..5eebda9de 100644 --- a/lib/zlog_5424_cli.c +++ b/lib/zlog_5424_cli.c @@ -158,9 +158,7 @@ static int reconf_clear_dst(struct zlog_cfg_5424_user *cfg, struct vty *vty) return reconf_dst(cfg, vty); } -#ifndef VTYSH_EXTRACT_PL #include "lib/zlog_5424_cli_clippy.c" -#endif DEFPY_NOSH(log_5424_target, log_5424_target_cmd, diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index dc0c162c8..227ff6c67 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -4,7 +4,6 @@ if NHRPD sbin_PROGRAMS += nhrpd/nhrpd -vtysh_scan += nhrpd/nhrp_vty.c vtysh_daemons += nhrpd man8 += $(MANBUILD)/frr-nhrpd.8 endif diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index a0cb45579..a5746e115 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -47,9 +47,7 @@ #include "ospf6d.h" #include "lib/json.h" #include "ospf6_nssa.h" -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_area_clippy.c" -#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AREA, "OSPF6 area"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name"); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index ae3ce2f0c..228046521 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -65,9 +65,7 @@ static void ospf6_asbr_redistribute_set(struct ospf6 *ospf6, int type); static void ospf6_asbr_redistribute_unset(struct ospf6 *ospf6, struct ospf6_redist *red, int type); -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_asbr_clippy.c" -#endif unsigned char conf_debug_ospf6_asbr = 0; diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c index d7de66c66..1f7fefa04 100644 --- a/ospf6d/ospf6_gr.c +++ b/ospf6d/ospf6_gr.c @@ -42,9 +42,7 @@ #include "ospf6d/ospf6_intra.h" #include "ospf6d/ospf6_spf.h" #include "ospf6d/ospf6_gr.h" -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_gr_clippy.c" -#endif static void ospf6_gr_nvm_delete(struct ospf6 *ospf6); diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c index f352d3527..771a71024 100644 --- a/ospf6d/ospf6_gr_helper.c +++ b/ospf6d/ospf6_gr_helper.c @@ -49,9 +49,7 @@ #include "ospf6d.h" #include "ospf6_gr.h" #include "lib/json.h" -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_gr_helper_clippy.c" -#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_GR_HELPER, "OSPF6 Graceful restart helper"); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 779076f38..2792820a5 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -46,9 +46,7 @@ #include "ospf6_flood.h" #include "ospf6d.h" -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_lsa_clippy.c" -#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA_HEADER, "OSPF6 LSA header"); diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index b1bff69f0..f35c9df4a 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -49,9 +49,7 @@ #include "ospf6_asbr.h" #include "ospf6d.h" #include "ospf6_nssa.h" -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_nssa_clippy.c" -#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA"); unsigned char config_debug_ospf6_nssa = 0; diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 8e964393f..52e0adaec 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -37,9 +37,7 @@ #include "ospf6_interface.h" #include "ospf6d.h" #include "ospf6_zebra.h" -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_route_clippy.c" -#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE, "OSPF6 route"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE_TABLE, "OSPF6 route table"); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index d48e85ced..eb89a14cd 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -65,9 +65,7 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES, { .val_bool = false }, ); -#ifndef VTYSH_EXTRACT_PL #include "ospf6d/ospf6_top_clippy.c" -#endif /* global ospf6d variable */ static struct ospf6_master ospf6_master; diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index cf863ff52..3dff03956 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -5,27 +5,6 @@ if OSPF6D noinst_LIBRARIES += ospf6d/libospf6.a sbin_PROGRAMS += ospf6d/ospf6d -vtysh_scan += \ - ospf6d/ospf6_nssa.c \ - ospf6d/ospf6_abr.c \ - ospf6d/ospf6_asbr.c \ - ospf6d/ospf6_area.c \ - ospf6d/ospf6_bfd.c \ - ospf6d/ospf6_flood.c \ - ospf6d/ospf6_gr.c \ - ospf6d/ospf6_gr_helper.c \ - ospf6d/ospf6_interface.c \ - ospf6d/ospf6_intra.c \ - ospf6d/ospf6_lsa.c \ - ospf6d/ospf6_message.c \ - ospf6d/ospf6_neighbor.c \ - ospf6d/ospf6_route.c \ - ospf6d/ospf6_spf.c \ - ospf6d/ospf6_top.c \ - ospf6d/ospf6_zebra.c \ - ospf6d/ospf6d.c \ - ospf6d/ospf6_auth_trailer.c \ - # end vtysh_daemons += ospf6d if SNMP module_LTLIBRARIES += ospf6d/ospf6d_snmp.la diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 59f95c5da..a47ed8d67 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -42,9 +42,7 @@ #include "ospfd/ospf_dump.h" #include "ospfd/ospf_packet.h" #include "ospfd/ospf_network.h" -#ifndef VTYSH_EXTRACT_PL #include "ospfd/ospf_dump_clippy.c" -#endif /* Configuration debug option variables. */ unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0}; diff --git a/ospfd/ospf_gr.c b/ospfd/ospf_gr.c index 66ef1d656..6678d8c1f 100644 --- a/ospfd/ospf_gr.c +++ b/ospfd/ospf_gr.c @@ -44,9 +44,7 @@ #include "ospfd/ospf_gr.h" #include "ospfd/ospf_errors.h" #include "ospfd/ospf_dump.h" -#ifndef VTYSH_EXTRACT_PL #include "ospfd/ospf_gr_clippy.c" -#endif static void ospf_gr_nvm_delete(struct ospf *ospf); diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index 77e96f173..7b1fa6626 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -751,9 +751,7 @@ void ospf_ldp_sync_if_write_config(struct vty *vty, /* * LDP-SYNC commands. */ -#ifndef VTYSH_EXTRACT_PL #include "ospfd/ospf_ldp_sync_clippy.c" -#endif DEFPY (ospf_mpls_ldp_sync, ospf_mpls_ldp_sync_cmd, diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 4f0fa6194..c8285f2e5 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -185,9 +185,7 @@ static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty, } } -#ifndef VTYSH_EXTRACT_PL #include "ospfd/ospf_vty_clippy.c" -#endif DEFUN_NOSH (router_ospf, router_ospf_cmd, diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 78688fac9..b67f94288 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -5,18 +5,6 @@ if OSPFD noinst_LIBRARIES += ospfd/libfrrospf.a sbin_PROGRAMS += ospfd/ospfd -vtysh_scan += \ - ospfd/ospf_bfd.c \ - ospfd/ospf_dump.c \ - ospfd/ospf_gr.c \ - ospfd/ospf_ldp_sync.c \ - ospfd/ospf_opaque.c \ - ospfd/ospf_ri.c \ - ospfd/ospf_routemap.c \ - ospfd/ospf_te.c \ - ospfd/ospf_sr.c \ - ospfd/ospf_vty.c \ - # end vtysh_daemons += ospfd if SNMP module_LTLIBRARIES += ospfd/ospfd_snmp.la diff --git a/pathd/path_cli.c b/pathd/path_cli.c index 13e52ac86..a6540cc84 100644 --- a/pathd/path_cli.c +++ b/pathd/path_cli.c @@ -31,9 +31,7 @@ #include "pathd/pathd.h" #include "pathd/path_nb.h" -#ifndef VTYSH_EXTRACT_PL #include "pathd/path_cli_clippy.c" -#endif #include "pathd/path_ted.h" #define XPATH_MAXATTRSIZE 64 diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c index d2b49a7d9..0f259f1dc 100644 --- a/pathd/path_pcep_cli.c +++ b/pathd/path_pcep_cli.c @@ -40,9 +40,7 @@ #include "pathd/path_pcep_lib.h" #include "pathd/path_pcep_pcc.h" -#ifndef VTYSH_EXTRACT_PL #include "pathd/path_pcep_cli_clippy.c" -#endif #define DEFAULT_PCE_PRECEDENCE 255 #define DEFAULT_PCC_MSD 4 diff --git a/pathd/path_ted.c b/pathd/path_ted.c index 316255a97..3e720e42d 100644 --- a/pathd/path_ted.c +++ b/pathd/path_ted.c @@ -29,9 +29,7 @@ #include "pathd/path_errors.h" #include "pathd/path_ted.h" -#ifndef VTYSH_EXTRACT_PL #include "pathd/path_ted_clippy.c" -#endif static struct ls_ted *path_ted_create_ted(void); static void path_ted_register_vty(void); diff --git a/pathd/subdir.am b/pathd/subdir.am index f339c7922..29be8f463 100644 --- a/pathd/subdir.am +++ b/pathd/subdir.am @@ -5,16 +5,11 @@ if PATHD noinst_LIBRARIES += pathd/libpath.a sbin_PROGRAMS += pathd/pathd -vtysh_scan += \ - pathd/path_cli.c \ - pathd/path_ted.c \ - #end vtysh_daemons += pathd # TODO add man page #man8 += $(MANBUILD)/pathd.8 if PATHD_PCEP -vtysh_scan += pathd/path_pcep_cli.c module_LTLIBRARIES += pathd/pathd_pcep.la endif diff --git a/pbrd/pbr_debug.c b/pbrd/pbr_debug.c index 82f045c46..99489777e 100644 --- a/pbrd/pbr_debug.c +++ b/pbrd/pbr_debug.c @@ -23,9 +23,7 @@ #include "command.h" #include "vector.h" -#ifndef VTYSH_EXTRACT_PL #include "pbrd/pbr_debug_clippy.c" -#endif #include "pbrd/pbr_debug.h" struct debug pbr_dbg_map = {0, "PBR map"}; diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index 6f53adb33..e8e5981ec 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -36,9 +36,7 @@ #include "pbrd/pbr_zebra.h" #include "pbrd/pbr_vty.h" #include "pbrd/pbr_debug.h" -#ifndef VTYSH_EXTRACT_PL #include "pbrd/pbr_vty_clippy.c" -#endif DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map PBRMAP seq (1-700)", "Create pbr-map or enter pbr-map command mode\n" diff --git a/pbrd/subdir.am b/pbrd/subdir.am index bbe3f2ab7..8a3bf31bf 100644 --- a/pbrd/subdir.am +++ b/pbrd/subdir.am @@ -5,10 +5,6 @@ if PBRD noinst_LIBRARIES += pbrd/libpbr.a sbin_PROGRAMS += pbrd/pbrd -vtysh_scan += \ - pbrd/pbr_vty.c \ - pbrd/pbr_debug.c \ - # end vtysh_daemons += pbrd man8 += $(MANBUILD)/frr-pbrd.8 endif diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index ae272bbb9..bd6d22947 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -45,9 +45,7 @@ #include "pim_zebra.h" #include "pim_instance.h" -#ifndef VTYSH_EXTRACT_PL #include "pimd/pim6_cmd_clippy.c" -#endif static struct cmd_node debug_node = { .name = "debug", diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c index c34c78296..dc5e67e2c 100644 --- a/pimd/pim6_mld.c +++ b/pimd/pim6_mld.c @@ -2319,9 +2319,7 @@ void gm_ifp_update(struct interface *ifp) #include "lib/command.h" -#ifndef VTYSH_EXTRACT_PL #include "pimd/pim6_mld_clippy.c" -#endif static struct vrf *gm_cmd_vrf_lookup(struct vty *vty, const char *vrf_str, int *err) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index efa1382fc..306891c0e 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -70,9 +70,7 @@ #include "pim_addr.h" #include "pim_cmd_common.h" -#ifndef VTYSH_EXTRACT_PL #include "pimd/pim_cmd_clippy.c" -#endif static struct cmd_node debug_node = { .name = "debug", diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h index d6798c52a..c409b9ed0 100644 --- a/pimd/pim_mroute.h +++ b/pimd/pim_mroute.h @@ -39,10 +39,8 @@ #if defined(HAVE_LINUX_MROUTE_H) #include <linux/mroute.h> #else -#ifndef VTYSH_EXTRACT_PL #include "linux/mroute.h" #endif -#endif typedef struct vifctl pim_vifctl; typedef struct igmpmsg kernmsg; @@ -86,10 +84,8 @@ typedef struct sioc_sg_req pim_sioc_sg_req; #if defined(HAVE_LINUX_MROUTE6_H) #include <linux/mroute6.h> #else -#ifndef VTYSH_EXTRACT_PL #include "linux/mroute6.h" #endif -#endif #ifndef MRT_INIT #define MRT_BASE MRT6_BASE diff --git a/pimd/subdir.am b/pimd/subdir.am index aa06b8647..9b7859696 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -6,11 +6,6 @@ if PIMD sbin_PROGRAMS += pimd/pimd bin_PROGRAMS += pimd/mtracebis noinst_PROGRAMS += pimd/test_igmpv3_join -vtysh_scan += \ - pimd/pim_cmd.c \ - pimd/pim6_cmd.c \ - pimd/pim6_mld.c \ - #end vtysh_daemons += pimd vtysh_daemons += pim6d man8 += $(MANBUILD)/frr-pimd.8 diff --git a/python/vtysh-cmd-check.py b/python/vtysh-cmd-check.py deleted file mode 100644 index ef9eea41a..000000000 --- a/python/vtysh-cmd-check.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 -# -# Quick demo program that checks whether files define commands that aren't -# in vtysh. Execute after building. -# -# This is free and unencumbered software released into the public domain. -# -# Anyone is free to copy, modify, publish, use, compile, sell, or -# distribute this software, either in source code form or as a compiled -# binary, for any purpose, commercial or non-commercial, and by any -# means. -# -# In jurisdictions that recognize copyright laws, the author or authors -# of this software dedicate any and all copyright interest in the -# software to the public domain. We make this dedication for the benefit -# of the public at large and to the detriment of our heirs and -# successors. We intend this dedication to be an overt act of -# relinquishment in perpetuity of all present and future rights to this -# software under copyright law. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -# For more information, please refer to <http://unlicense.org/> - -import os -import json -import subprocess - -os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -with open("frr.xref", "r") as fd: - data = json.load(fd) - -vtysh_scan, _ = subprocess.Popen( - ["make", "var-vtysh_scan"], stdout=subprocess.PIPE -).communicate() -vtysh_scan = set(vtysh_scan.decode("US-ASCII").split()) - -check = set() -vtysh = {} - -for cmd, defs in data["cli"].items(): - for binary, clidef in defs.items(): - if clidef["defun"]["file"].startswith("vtysh/"): - vtysh[clidef["string"]] = clidef - -for cmd, defs in data["cli"].items(): - for binary, clidef in defs.items(): - if clidef["defun"]["file"].startswith("vtysh/"): - continue - - if clidef["defun"]["file"] not in vtysh_scan: - vtysh_def = vtysh.get(clidef["string"]) - if vtysh_def is not None: - print( - "\033[33m%s defines %s, has a custom define in vtysh %s\033[m" - % (clidef["defun"]["file"], cmd, vtysh_def["defun"]["file"]) - ) - else: - print( - "\033[31m%s defines %s, not in vtysh_scan\033[m" - % (clidef["defun"]["file"], cmd) - ) - check.add(clidef["defun"]["file"]) - -print("\nfiles to check:\n\t" + " ".join(sorted(check))) diff --git a/python/xref2vtysh.py b/python/xref2vtysh.py new file mode 100644 index 000000000..ef18fac8a --- /dev/null +++ b/python/xref2vtysh.py @@ -0,0 +1,386 @@ +# FRR xref vtysh command extraction +# +# Copyright (C) 2022 David Lamparter for NetDEF, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; see the file COPYING; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +""" +Generate vtysh_cmd.c from frr .xref file(s). + +This can run either standalone or as part of xrelfo. The latter saves a +non-negligible amount of time (0.5s on average systems, more on e.g. slow ARMs) +since serializing and deserializing JSON is a significant bottleneck in this. +""" + +import sys +import os +import re +import pathlib +import argparse +from collections import defaultdict +import difflib + +import typing +from typing import ( + Dict, + List, +) + +import json + +try: + import ujson as json # type: ignore +except ImportError: + pass + +frr_top_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# vtysh needs to know which daemon(s) to send commands to. For lib/, this is +# not quite obvious... + +daemon_flags = { + "lib/agentx.c": "VTYSH_ISISD|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA", + "lib/filter.c": "VTYSH_ACL", + "lib/filter_cli.c": "VTYSH_ACL", + "lib/if.c": "VTYSH_INTERFACE", + "lib/keychain.c": "VTYSH_RIPD|VTYSH_EIGRPD|VTYSH_OSPF6D", + "lib/lib_vty.c": "VTYSH_ALL", + "lib/log_vty.c": "VTYSH_ALL", + "lib/nexthop_group.c": "VTYSH_NH_GROUP", + "lib/resolver.c": "VTYSH_NHRPD|VTYSH_BGPD", + "lib/routemap.c": "VTYSH_RMAP", + "lib/routemap_cli.c": "VTYSH_RMAP", + "lib/spf_backoff.c": "VTYSH_ISISD", + "lib/thread.c": "VTYSH_ALL", + "lib/vrf.c": "VTYSH_VRF", + "lib/vty.c": "VTYSH_ALL", +} + +vtysh_cmd_head = """/* autogenerated file, DO NOT EDIT! */ +#include <zebra.h> + +#include "command.h" +#include "linklist.h" + +#include "vtysh/vtysh.h" +""" + +if sys.stderr.isatty(): + _fmt_red = "\033[31m" + _fmt_green = "\033[32m" + _fmt_clear = "\033[m" +else: + _fmt_red = _fmt_green = _fmt_clear = "" + + +def c_escape(text: str) -> str: + """ + Escape string for output into C source code. + + Handles only what's needed here. CLI strings and help text don't contain + weird special characters. + """ + return text.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n") + + +class NodeDict(defaultdict): + """ + CLI node ID (integer) -> dict of commands in that node. + """ + + nodenames: Dict[int, str] = {} + + def __init__(self): + super().__init__(dict) + + def items_named(self): + for k, v in self.items(): + yield self.nodename(k), v + + @classmethod + def nodename(cls, nodeid: int) -> str: + return cls.nodenames.get(nodeid, str(nodeid)) + + @classmethod + def load_nodenames(cls): + with open(os.path.join(frr_top_src, "lib", "command.h"), "r") as fd: + command_h = fd.read() + + nodes = re.search(r"enum\s+node_type\s+\{(.*?)\}", command_h, re.S) + if nodes is None: + raise RuntimeError( + "regex failed to match on lib/command.h (to get CLI node names)" + ) + + text = nodes.group(1) + text = re.sub(r"/\*.*?\*/", "", text, flags=re.S) + text = re.sub(r"//.*?$", "", text, flags=re.M) + text = text.replace(",", " ") + text = text.split() + + for i, name in enumerate(text): + cls.nodenames[i] = name + + +class CommandEntry: + """ + CLI command definition. + + - one DEFUN creates at most one of these, even if the same command is + installed in multiple CLI nodes (e.g. BGP address-family nodes) + - for each CLI node, commands with the same CLI string are merged. This + is *almost* irrelevant - ospfd & ospf6d define some identical commands + in the route-map node. Those must be merged for things to work + correctly. + """ + + all_defs: List["CommandEntry"] = [] + warn_counter = 0 + + def __init__(self, origin, name, spec): + self.origin = origin + self.name = name + self._spec = spec + self._registered = False + + self.cmd = spec["string"] + self._cmd_normalized = self.normalize_cmd(self.cmd) + + self.hidden = "hidden" in spec.get("attrs", []) + self.daemons = self._get_daemons() + + self.doclines = self._spec["doc"].splitlines(keepends=True) + if not self.doclines[-1].endswith("\n"): + self.warn_loc("docstring does not end with \\n") + + def warn_loc(self, wtext, nodename=None): + """ + Print warning with parseable (compiler style) location + + Matching the way compilers emit file/lineno means editors/IDE can + identify / jump to the error location. + """ + + if nodename: + prefix = ": [%s] %s:" % (nodename, self.name) + else: + prefix = ": %s:" % (self.name,) + + for line in wtext.rstrip("\n").split("\n"): + sys.stderr.write( + "%s:%d%s %s\n" + % ( + self._spec["defun"]["file"], + self._spec["defun"]["line"], + prefix, + line, + ) + ) + prefix = "- " + + CommandEntry.warn_counter += 1 + + def _get_daemons(self): + path = pathlib.Path(self.origin) + if path.name == "vtysh": + return {} + + defun_file = os.path.relpath(self._spec["defun"]["file"], frr_top_src) + defun_path = pathlib.Path(defun_file) + + if defun_path.parts[0] != "lib": + if "." not in path.name: + # daemons don't have dots in their filename + return {"VTYSH_" + path.name.upper()} + + # loadable modules - use directory name to determine daemon + return {"VTYSH_" + path.parts[-2].upper()} + + if defun_file in daemon_flags: + return {daemon_flags[defun_file]} + + v6_cmd = "ipv6" in self.name + if defun_file == "lib/plist.c": + if v6_cmd: + return { + "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIM6D|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD" + } + else: + return { + "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD" + } + + if defun_file == "lib/if_rmap.c": + if v6_cmd: + return {"VTYSH_RIPNGD"} + else: + return {"VTYSH_RIPD"} + + return {} + + def __repr__(self): + return f"<CommandEntry {self.name}: {self.cmd!r}>" + + def register(self): + """Track DEFUNs so each is only output once.""" + if not self._registered: + self.all_defs.append(self) + self._registered = True + return self + + def merge(self, other, nodename): + if self._cmd_normalized != other._cmd_normalized: + self.warn_loc( + f"command definition mismatch, first definied as:\n{self.cmd!r}", + nodename=nodename, + ) + other.warn_loc(f"later defined as:\n{other.cmd!r}", nodename=nodename) + + if self._spec["doc"] != other._spec["doc"]: + self.warn_loc( + f"help string mismatch, first defined here (-)", nodename=nodename + ) + other.warn_loc( + f"later defined here (+)\nnote: both commands define {self.cmd!r} in same node ({nodename})", + nodename=nodename, + ) + + d = difflib.Differ() + for diffline in d.compare(self.doclines, other.doclines): + if diffline.startswith(" "): + continue + if diffline.startswith("+ "): + diffline = _fmt_green + diffline + elif diffline.startswith("- "): + diffline = _fmt_red + diffline + sys.stderr.write("\t" + diffline.rstrip("\n") + _fmt_clear + "\n") + + if self.hidden != other.hidden: + self.warn_loc( + f"hidden flag mismatch, first {self.hidden!r} here", nodename=nodename + ) + other.warn_loc( + f"later {other.hidden!r} here (+)\nnote: both commands define {self.cmd!r} in same node ({nodename})", + nodename=nodename, + ) + + # ensure name is deterministic regardless of input DEFUN order + self.name = min([self.name, other.name], key=lambda i: (len(i), i)) + self.daemons.update(other.daemons) + + def get_def(self): + doc = "\n".join(['\t"%s"' % c_escape(line) for line in self.doclines]) + defsh = "DEFSH_HIDDEN" if self.hidden else "DEFSH" + + # make daemon list deterministic + daemons = set() + for daemon in self.daemons: + daemons.update(daemon.split("|")) + daemon_str = "|".join(sorted(daemons)) + + return f""" +{defsh} ({daemon_str}, {self.name}_vtysh, +\t"{c_escape(self.cmd)}", +{doc}) +""" + + # accept slightly different command definitions that result in the same command + re_collapse_ws = re.compile(r"\s+") + re_remove_varnames = re.compile(r"\$[a-z][a-z0-9_]*") + + @classmethod + def normalize_cmd(cls, cmd): + cmd = cmd.strip() + cmd = cls.re_collapse_ws.sub(" ", cmd) + cmd = cls.re_remove_varnames.sub("", cmd) + return cmd + + @classmethod + def process(cls, nodes, name, origin, spec): + if "nosh" in spec.get("attrs", []): + return + if origin == "vtysh/vtysh": + return + + if origin == "isisd/fabricd": + # dirty workaround :( + name = "fabricd_" + name + + entry = cls(origin, name, spec) + if not entry.daemons: + return + + for nodedata in spec.get("nodes", []): + node = nodes[nodedata["node"]] + if entry._cmd_normalized not in node: + node[entry._cmd_normalized] = entry.register() + else: + node[entry._cmd_normalized].merge( + entry, nodes.nodename(nodedata["node"]) + ) + + @classmethod + def load(cls, xref): + nodes = NodeDict() + + for cmd_name, origins in xref.get("cli", {}).items(): + for origin, spec in origins.items(): + CommandEntry.process(nodes, cmd_name, origin, spec) + return nodes + + @classmethod + def output_defs(cls, ofd): + for entry in sorted(cls.all_defs, key=lambda i: i.name): + ofd.write(entry.get_def()) + + @classmethod + def output_install(cls, ofd, nodes): + ofd.write("\nvoid vtysh_init_cmd(void)\n{\n") + + for name, items in sorted(nodes.items_named()): + for item in sorted(items.values(), key=lambda i: i.name): + ofd.write(f"\tinstall_element({name}, &{item.name}_vtysh);\n") + + ofd.write("}\n") + + @classmethod + def run(cls, xref, ofd): + ofd.write(vtysh_cmd_head) + + NodeDict.load_nodenames() + nodes = cls.load(xref) + cls.output_defs(ofd) + cls.output_install(ofd, nodes) + + +def main(): + argp = argparse.ArgumentParser(description="FRR xref to vtysh defs") + argp.add_argument( + "xreffile", metavar="XREFFILE", type=str, help=".xref file to read" + ) + argp.add_argument("-Werror", action="store_const", const=True) + args = argp.parse_args() + + with open(args.xreffile, "r") as fd: + data = json.load(fd) + + CommandEntry.run(data, sys.stdout) + + if args.Werror and CommandEntry.warn_counter: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/python/xrelfo.py b/python/xrelfo.py index 09455ea9b..739becd8a 100644 --- a/python/xrelfo.py +++ b/python/xrelfo.py @@ -37,6 +37,7 @@ from clippy.uidhash import uidhash from clippy.elf import * from clippy import frr_top_src, CmdAttr from tiabwarfo import FieldApplicator +from xref2vtysh import CommandEntry try: with open(os.path.join(frr_top_src, 'python', 'xrefstructs.json'), 'r') as fd: @@ -366,6 +367,7 @@ def main(): argp = argparse.ArgumentParser(description = 'FRR xref ELF extractor') argp.add_argument('-o', dest='output', type=str, help='write JSON output') argp.add_argument('--out-by-file', type=str, help='write by-file JSON output') + argp.add_argument('-c', dest='vtysh_cmds', type=str, help='write vtysh_cmd.c') argp.add_argument('-Wlog-format', action='store_const', const=True) argp.add_argument('-Wlog-args', action='store_const', const=True) argp.add_argument('-Werror', action='store_const', const=True) @@ -435,5 +437,13 @@ def _main(args): json.dump(outbyfile, fd, indent=2, sort_keys=True, **json_dump_args) os.rename(args.out_by_file + '.tmp', args.out_by_file) + if args.vtysh_cmds: + with open(args.vtysh_cmds + '.tmp', 'w') as fd: + CommandEntry.run(out, fd) + os.rename(args.vtysh_cmds + '.tmp', args.vtysh_cmds) + if args.Werror and CommandEntry.warn_counter: + sys.exit(1) + + if __name__ == '__main__': main() diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 73442bf16..34ea21672 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -30,9 +30,7 @@ #include "ripd/ripd.h" #include "ripd/rip_nb.h" -#ifndef VTYSH_EXTRACT_PL #include "ripd/rip_cli_clippy.c" -#endif /* * XPath: /frr-ripd:ripd/instance diff --git a/ripd/subdir.am b/ripd/subdir.am index b00c37588..98cc765c9 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -4,11 +4,6 @@ if RIPD sbin_PROGRAMS += ripd/ripd -vtysh_scan += \ - ripd/rip_cli.c \ - ripd/rip_debug.c \ - ripd/ripd.c \ - # end vtysh_daemons += ripd if SNMP diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index ded2f4358..049a392dd 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -30,9 +30,7 @@ #include "ripngd/ripngd.h" #include "ripngd/ripng_nb.h" -#ifndef VTYSH_EXTRACT_PL #include "ripngd/ripng_cli_clippy.c" -#endif /* * XPath: /frr-ripngd:ripngd/instance diff --git a/ripngd/subdir.am b/ripngd/subdir.am index a4db3e5a6..162426c58 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -4,11 +4,6 @@ if RIPNGD sbin_PROGRAMS += ripngd/ripngd -vtysh_scan += \ - ripngd/ripng_cli.c \ - ripngd/ripng_debug.c \ - ripngd/ripngd.c \ - # end vtysh_daemons += ripngd man8 += $(MANBUILD)/frr-ripngd.8 endif diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index ba2e599a5..164a0fd21 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -37,9 +37,7 @@ #include "sharpd/sharp_zebra.h" #include "sharpd/sharp_nht.h" #include "sharpd/sharp_vty.h" -#ifndef VTYSH_EXTRACT_PL #include "sharpd/sharp_vty_clippy.c" -#endif DEFINE_MTYPE_STATIC(SHARPD, SRV6_LOCATOR, "SRv6 Locator"); diff --git a/sharpd/subdir.am b/sharpd/subdir.am index acf4fe5d0..3eb8d1d3b 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -5,7 +5,6 @@ if SHARPD noinst_LIBRARIES += sharpd/libsharp.a sbin_PROGRAMS += sharpd/sharpd -vtysh_scan += sharpd/sharp_vty.c vtysh_daemons += sharpd man8 += $(MANBUILD)/frr-sharpd.8 endif diff --git a/staticd/static_vty.c b/staticd/static_vty.c index c0638f4bc..94a349347 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -36,9 +36,7 @@ #include "static_vty.h" #include "static_routes.h" #include "static_debug.h" -#ifndef VTYSH_EXTRACT_PL #include "staticd/static_vty_clippy.c" -#endif #include "static_nb.h" #define STATICD_STR "Static route daemon\n" diff --git a/staticd/subdir.am b/staticd/subdir.am index 62969a0a2..bb0fc95bc 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -5,7 +5,6 @@ if STATICD noinst_LIBRARIES += staticd/libstatic.a sbin_PROGRAMS += staticd/staticd -vtysh_scan += staticd/static_vty.c vtysh_daemons += staticd man8 += $(MANBUILD)/frr-staticd.8 endif diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am index 02e0497ee..03b404261 100644 --- a/vrrpd/subdir.am +++ b/vrrpd/subdir.am @@ -4,7 +4,6 @@ if VRRPD sbin_PROGRAMS += vrrpd/vrrpd -vtysh_scan += vrrpd/vrrp_vty.c vtysh_daemons += vrrpd man8 += $(MANBUILD)/frr-vrrpd.8 endif diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index aea7d9abc..f822b8985 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -33,9 +33,7 @@ #include "vrrp_debug.h" #include "vrrp_vty.h" #include "vrrp_zebra.h" -#ifndef VTYSH_EXTRACT_PL #include "vrrpd/vrrp_vty_clippy.c" -#endif #define VRRP_STR "Virtual Router Redundancy Protocol\n" diff --git a/vtysh/.gitignore b/vtysh/.gitignore index 118b84407..09e90e51d 100644 --- a/vtysh/.gitignore +++ b/vtysh/.gitignore @@ -1,4 +1,6 @@ vtysh vtysh_cmd.c -extract.pl vtysh_daemons.h + +# does not exist anymore - remove 2023-10-04 or so +extract.pl diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in deleted file mode 100755 index 228a136b7..000000000 --- a/vtysh/extract.pl.in +++ /dev/null @@ -1,282 +0,0 @@ -#! @PERL@ -## -## @configure_input@ -## -## Virtual terminal interface shell command extractor. -## Copyright (C) 2000 Kunihiro Ishiguro -## -## This file is part of GNU Zebra. -## -## GNU Zebra is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by the -## Free Software Foundation; either version 2, or (at your option) any -## later version. -## -## GNU Zebra is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with GNU Zebra; see the file COPYING. If not, write to the Free -## Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -## 02111-1307, USA. -## - -use Getopt::Long; - -print <<EOF; -#include <zebra.h> - -#include "command.h" -#include "linklist.h" - -#include "vtysh/vtysh.h" - -EOF - -my $cli_stomp = 0; - -sub scan_file { - my ( $file, $fabricd) = @_; - - $cppadd = $fabricd ? "-DFABRICD=1" : ""; - - $command_line = "@CPP@ -P -std=gnu11 -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @LUA_INCLUDE@ @CPPFLAGS@ @LIBYANG_CFLAGS@ $cppadd $file |"; - open (FH, $command_line) - || die "Open to the pipeline failed: $!\n\nCommand Issued:\n$command_line"; - local $/; undef $/; - $line = <FH>; - if (!close (FH)) { - die "File: $file failed to compile:\n$!\nwhen extracting cli from it please inspect\n" - } - - # ?: makes a group non-capturing - @defun = ($line =~ /((?:DEFUN|DEFUN_HIDDEN|DEFUN_YANG|ALIAS|ALIAS_HIDDEN|ALIAS_YANG|DEFPY|DEFPY_HIDDEN|DEFPY_YANG)\s*\(.+?\));?\s?\s?\n/sg); - @install = ($line =~ /install_element\s*\(\s*[0-9A-Z_]+,\s*&[^;]*;\s*\n/sg); - - # DEFUN process - foreach (@defun) { - # $_ will contain the entire string including the DEFUN, ALIAS, etc. - # We need to extract the DEFUN/ALIAS from everything in ()s. - # The /s at the end tells the regex to allow . to match newlines. - $_ =~ /^(.*?)\s*\((.*)\)$/s; - - my (@defun_array); - $defun_or_alias = $1; - @defun_array = split (/,/, $2); - - if ($defun_or_alias =~ /_HIDDEN/) { - $hidden = 1; - } else { - $hidden = 0; - } - - $defun_array[0] = ''; - - # Actual input command string. - $str = "$defun_array[2]"; - $str =~ s/^\s+//g; - $str =~ s/\s+$//g; - - # Get VTY command structure. This is needed for searching - # install_element() command. - $cmd = "$defun_array[1]"; - $cmd =~ s/^\s+//g; - $cmd =~ s/\s+$//g; - - if ($fabricd) { - $cmd = "fabricd_" . $cmd; - } - - # $protocol is VTYSH_PROTO format for redirection of user input - if ($file =~ /lib\/keychain\.c$/) { - $protocol = "VTYSH_RIPD|VTYSH_EIGRPD|VTYSH_OSPF6D"; - } - elsif ($file =~ /lib\/routemap\.c$/ || $file =~ /lib\/routemap_cli\.c$/) { - $protocol = "VTYSH_RMAP"; - } - elsif ($file =~ /lib\/vrf\.c$/) { - $protocol = "VTYSH_VRF"; - } - elsif ($file =~ /lib\/if\.c$/) { - $protocol = "VTYSH_INTERFACE"; - } - elsif ($file =~ /lib\/(filter|filter_cli)\.c$/) { - $protocol = "VTYSH_ACL"; - } - elsif ($file =~ /lib\/(lib|log)_vty\.c$/) { - $protocol = "VTYSH_ALL"; - } - elsif ($file =~ /lib\/agentx\.c$/) { - $protocol = "VTYSH_ISISD|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA"; - } - elsif ($file =~ /lib\/nexthop_group\.c$/) { - $protocol = "VTYSH_NH_GROUP"; - } - elsif ($file =~ /lib\/plist\.c$/) { - if ($defun_array[1] =~ m/ipv6/) { - $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIM6D|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"; - } else { - $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"; - } - } - elsif ($file =~ /lib\/if_rmap\.c$/) { - if ($defun_array[1] =~ m/ipv6/) { - $protocol = "VTYSH_RIPNGD"; - } else { - $protocol = "VTYSH_RIPD"; - } - } - elsif ($file =~ /lib\/resolver\.c$/) { - $protocol = "VTYSH_NHRPD|VTYSH_BGPD"; - } - elsif ($file =~ /lib\/spf_backoff\.c$/) { - $protocol = "VTYSH_ISISD"; - } - elsif ($file =~ /lib\/(vty|thread)\.c$/) { - $protocol = "VTYSH_ALL"; - } - elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) { - $protocol = "VTYSH_BGPD"; - } - elsif ($fabricd) { - $protocol = "VTYSH_FABRICD"; - } - elsif ($file =~ /pimd\/pim6_.*\.c$/) { - $protocol = "VTYSH_PIM6D"; - } - else { - ($protocol) = ($file =~ /^(?:.*\/)?([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/); - $protocol = "VTYSH_" . uc $protocol; - } - - # Append _vtysh to structure then build DEFUN again - $defun_array[1] = $cmd . "_vtysh"; - $defun_body = join (", ", @defun_array); - - # $cmd -> $str hash for lookup - if (exists($cmd2str{$cmd})) { - warn "Duplicate CLI Function: $cmd\n"; - warn "\tFrom cli: $cmd2str{$cmd} to New cli: $str\n"; - warn "\tOriginal Protocol: $cmd2proto{$cmd} to New Protocol: $protocol\n"; - $cli_stomp++; - } - $cmd2str{$cmd} = $str; - $cmd2defun{$cmd} = $defun_body; - $cmd2proto{$cmd} = $protocol; - $cmd2hidden{$cmd} = $hidden; - } - - # install_element() process - foreach (@install) { - my (@element_array); - @element_array = split (/,/); - - # Install node - $enode = $element_array[0]; - $enode =~ s/^\s+//g; - $enode =~ s/\s+$//g; - ($enode) = ($enode =~ /([0-9A-Z_]+)$/); - - # VTY command structure. - ($ecmd) = ($element_array[1] =~ /&([^\)]+)/); - $ecmd =~ s/^\s+//g; - $ecmd =~ s/\s+$//g; - - if ($fabricd) { - $ecmd = "fabricd_" . $ecmd; - } - - # Register $ecmd - if (defined ($cmd2str{$ecmd})) { - my ($key); - $key = $enode . "," . $cmd2str{$ecmd}; - $ocmd{$key} = $ecmd; - $odefun{$key} = $cmd2defun{$ecmd}; - - if ($cmd2hidden{$ecmd}) { - $defsh{$key} = "DEFSH_HIDDEN" - } else { - $defsh{$key} = "DEFSH" - } - push (@{$oproto{$key}}, $cmd2proto{$ecmd}); - } - } -} - -my $have_isisd = 0; -my $have_fabricd = 0; - -GetOptions('have-isisd' => \$have_isisd, 'have-fabricd' => \$have_fabricd); - -foreach (@ARGV) { - if (/(^|\/)isisd\//) { - # We scan all the IS-IS files twice, once for isisd, - # once for fabricd. Exceptions are made for the files - # that are not shared between the two. - if (/isis_vty_isisd.c/) { - if ( $have_isisd ) { - scan_file($_, 0); - } - } elsif (/isis_vty_fabricd.c/) { - if ( $have_fabricd ) { - scan_file($_, 1); - } - } else { - if ( $have_isisd ) { - scan_file($_, 0); - } - if ( $have_fabricd ) { - scan_file($_, 1); - } - } - } else { - scan_file($_, 0); - } -} - -# When we have cli commands that map to the same function name, we -# can introduce subtle bugs due to code not being called when -# we think it is. -# -# If extract.pl fails with a error message and you've been -# modifying the cli, then go back and fix your code to -# not have cli command function collisions. -# please fix your code before submittal -if ($cli_stomp) { - warn "There are $cli_stomp command line stomps\n"; -} - -# Check finaly alive $cmd; -foreach (keys %odefun) { - my ($node, $str) = (split (/,/)); - my ($cmd) = $ocmd{$_}; - $live{$cmd} = $_; -} - -# Output DEFSH -foreach (sort keys %live) { - my ($proto); - my ($key); - $key = $live{$_}; - $proto = join ("|", @{$oproto{$key}}); - printf "$defsh{$key} ($proto$odefun{$key})\n\n"; -} - -# Output install_element -print <<EOF; -void vtysh_init_cmd(void) -{ -EOF - -foreach (sort keys %odefun) { - my ($node, $str) = (split (/,/)); - $cmd = $ocmd{$_}; - $cmd =~ s/_cmd$/_cmd_vtysh/; - printf " install_element ($node, &$cmd);\n"; -} - -print <<EOF -} -EOF diff --git a/vtysh/subdir.am b/vtysh/subdir.am index 624361645..cc2a70ade 100644 --- a/vtysh/subdir.am +++ b/vtysh/subdir.am @@ -20,7 +20,6 @@ vtysh_vtysh_SOURCES = \ nodist_vtysh_vtysh_SOURCES = \ vtysh/vtysh_cmd.c \ # end -CLEANFILES += vtysh/vtysh_cmd.c noinst_HEADERS += \ vtysh/vtysh.h \ @@ -39,23 +38,3 @@ $(vtysh_vtysh_OBJECTS): vtysh/vtysh_daemons.h CLEANFILES += vtysh/vtysh_daemons.h vtysh/vtysh_daemons.h: $(PERL) $(top_srcdir)/vtysh/daemons.pl $(vtysh_daemons) > vtysh/vtysh_daemons.h - -AM_V_EXTRACT = $(am__v_EXTRACT_$(V)) -am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY)) -am__v_EXTRACT_0 = @echo " EXTRACT " $@; -am__v_EXTRACT_1 = - -if ISISD -HAVE_ISISD = --have-isisd -else -HAVE_ISISD = -endif - -if FABRICD -HAVE_FABRICD = --have-fabricd -else -HAVE_FABRICD = -endif - -vtysh/vtysh_cmd.c: vtysh/extract.pl $(vtysh_scan) - $(AM_V_EXTRACT) $^ $(HAVE_ISISD) $(HAVE_FABRICD) > vtysh/vtysh_cmd.c diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am index e899b895e..04a4aaf16 100644 --- a/watchfrr/subdir.am +++ b/watchfrr/subdir.am @@ -4,7 +4,6 @@ if WATCHFRR sbin_PROGRAMS += watchfrr/watchfrr -vtysh_scan += watchfrr/watchfrr_vty.c man8 += $(MANBUILD)/frr-watchfrr.8 endif diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c index e5cc43754..742b474ea 100644 --- a/watchfrr/watchfrr_vty.c +++ b/watchfrr/watchfrr_vty.c @@ -153,9 +153,7 @@ DEFUN_NOSH (show_logging, return CMD_SUCCESS; } -#ifndef VTYSH_EXTRACT_PL #include "watchfrr/watchfrr_vty_clippy.c" -#endif DEFPY (watchfrr_ignore_daemon, watchfrr_ignore_daemon_cmd, diff --git a/zebra/debug.c b/zebra/debug.c index 25102145d..16aac7909 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -23,9 +23,7 @@ #include "command.h" #include "debug.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/debug_clippy.c" -#endif /* For debug statement. */ unsigned long zebra_debug_event; diff --git a/zebra/dpdk/zebra_dplane_dpdk_vty.c b/zebra/dpdk/zebra_dplane_dpdk_vty.c index 748bce9e3..d1814af3b 100644 --- a/zebra/dpdk/zebra_dplane_dpdk_vty.c +++ b/zebra/dpdk/zebra_dplane_dpdk_vty.c @@ -23,9 +23,7 @@ #include "lib/json.h" #include "zebra/dpdk/zebra_dplane_dpdk.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/dpdk/zebra_dplane_dpdk_vty_clippy.c" -#endif #define ZD_STR "Zebra dataplane information\n" #define ZD_DPDK_STR "DPDK offload information\n" diff --git a/zebra/interface.c b/zebra/interface.c index c674b499a..52e6bc81d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -2603,9 +2603,7 @@ static void interface_update_stats(void) #endif /* HAVE_NET_RT_IFLIST */ } -#ifndef VTYSH_EXTRACT_PL #include "zebra/interface_clippy.c" -#endif /* Show all interfaces to vty. */ DEFPY(show_interface, show_interface_cmd, "show interface vrf NAME$vrf_name [brief$brief] [json$uj]", diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 127888d65..a8ec60844 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -51,9 +51,7 @@ static uint32_t interfaces_configured_for_ra_from_bgp; #if defined(HAVE_RTADV) -#ifndef VTYSH_EXTRACT_PL #include "zebra/rtadv_clippy.c" -#endif DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix"); DEFINE_MTYPE_STATIC(ZEBRA, ADV_IF, "Advertised Interface"); diff --git a/zebra/subdir.am b/zebra/subdir.am index 298b71598..984293149 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -4,29 +4,6 @@ if ZEBRA sbin_PROGRAMS += zebra/zebra -vtysh_scan += \ - zebra/debug.c \ - zebra/interface.c \ - zebra/router-id.c \ - zebra/rtadv.c \ - zebra/zebra_gr.c \ - zebra/zebra_mlag_vty.c \ - zebra/zebra_evpn_mh.c \ - zebra/zebra_mpls_vty.c \ - zebra/zebra_srv6_vty.c \ - zebra/zebra_ptm.c \ - zebra/zebra_pw.c \ - zebra/zebra_routemap.c \ - zebra/zebra_vty.c \ - zebra/zserv.c \ - zebra/zebra_vrf.c \ - zebra/dpdk/zebra_dplane_dpdk_vty.c \ - # end - -# can be loaded as DSO - always include for vtysh -vtysh_scan += zebra/irdp_interface.c -vtysh_scan += zebra/zebra_fpm.c - vtysh_daemons += zebra if IRDP @@ -255,8 +232,6 @@ module_LTLIBRARIES += zebra/dplane_fpm_nl.la zebra_dplane_fpm_nl_la_SOURCES = zebra/dplane_fpm_nl.c zebra_dplane_fpm_nl_la_LDFLAGS = $(MODULE_LDFLAGS) zebra_dplane_fpm_nl_la_LIBADD = - -vtysh_scan += zebra/dplane_fpm_nl.c endif if NETLINK_DEBUG diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 064c91b72..98120accf 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -3252,9 +3252,7 @@ int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp) return 0; } -#ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_evpn_mh_clippy.c" -#endif /* CLI for setting an ES in bypass mode */ DEFPY_HIDDEN(zebra_evpn_es_bypass, zebra_evpn_es_bypass_cmd, "[no] evpn mh bypass", diff --git a/zebra/zebra_mlag_vty.c b/zebra/zebra_mlag_vty.c index ebaaf03da..a1c544d5d 100644 --- a/zebra/zebra_mlag_vty.c +++ b/zebra/zebra_mlag_vty.c @@ -29,9 +29,7 @@ #include "debug.h" #include "zapi_msg.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_mlag_vty_clippy.c" -#endif DEFUN_HIDDEN (show_mlag, show_mlag_cmd, diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 2cc84a1f7..13d1995d5 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -40,9 +40,7 @@ #include "zebra/zebra_rnh.h" #include "zebra/zebra_routemap.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_routemap_clippy.c" -#endif static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER; static struct thread *zebra_t_rmap_update = NULL; diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 9adfc6550..e6810bdc5 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -40,9 +40,7 @@ #include "zebra/zebra_routemap.h" #include "zebra/zebra_dplane.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_srv6_vty_clippy.c" -#endif static int zebra_sr_config(struct vty *vty); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index a2844ca95..c99aa2e8f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -44,9 +44,7 @@ #include "zebra/zebra_vxlan.h" #include "zebra/zebra_netns_notify.h" #include "zebra/zebra_routemap.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_vrf_clippy.c" -#endif #include "zebra/table_manager.h" static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 525e0366e..f68a65671 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -46,9 +46,7 @@ #include "lib/route_opaque.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_evpn_mh.h" -#ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_vty_clippy.c" -#endif #include "zebra/zserv.h" #include "zebra/router-id.h" #include "zebra/ipforward.h" |