From 574b20e518079db0f91720c0641e4222d9fda84f Mon Sep 17 00:00:00 2001 From: Mathieu Lirzin Date: Sat, 8 Jul 2017 20:18:45 +0200 Subject: build: Inline perl prototypes in sources Prototypes allows us to avoid using the '&foo' invocation form when invoking a subroutine before its definition. Previously those prototypes were generated to prevent them from falling out-of-sync with actual definitions. Now we provide a 'check-perl-protos' lint script to ensure that this is not the case. This has the same benefits as generating prototypes while simplifying the bootstrap/build process. * bin/gen-perl-protos: Remove. * bin/Makefile.inc: Adapt. * bootstrap: Likewise. * bin/aclocal.in: Inline prototypes. * bin/automake.in: Likewise. * maintainer/check-perl-protos: New lint script. * maintainer/syntax-checks.mk (sc_perl_protos): New target. (syntax_check_rules): Add it. --- bin/Makefile.inc | 6 +---- bin/aclocal.in | 21 +++++++++++++++- bin/automake.in | 57 ++++++++++++++++++++++++++++++++++++++++++-- bin/gen-perl-protos | 36 ---------------------------- bootstrap | 7 ++---- maintainer/check-perl-protos | 50 ++++++++++++++++++++++++++++++++++++++ maintainer/syntax-checks.mk | 8 +++++++ 7 files changed, 136 insertions(+), 49 deletions(-) delete mode 100755 bin/gen-perl-protos create mode 100755 maintainer/check-perl-protos diff --git a/bin/Makefile.inc b/bin/Makefile.inc index 62dd483d9..c63f670b8 100644 --- a/bin/Makefile.inc +++ b/bin/Makefile.inc @@ -61,19 +61,15 @@ uninstall-hook: # $(datadir) or other do_subst'ituted variables change. %D%/automake: %D%/automake.in %D%/aclocal: %D%/aclocal.in -%D%/automake %D%/aclocal: Makefile %D%/gen-perl-protos +%D%/automake %D%/aclocal: Makefile $(AM_V_GEN)rm -f $@ $@-t $@-t2 \ && $(MKDIR_P) $(@D) \ ## Common substitutions. && in=$@.in && $(do_subst) <$(srcdir)/$$in >$@-t \ -## Auto-compute prototypes of perl subroutines. - && $(PERL) -w $(srcdir)/%D%/gen-perl-protos $@-t > $@-t2 \ - && mv -f $@-t2 $@-t \ ## We can't use '$(generated_file_finalize)' here, because currently ## Automake contains occurrences of unexpanded @substitutions@ in ## comments, and that is perfectly legit. && chmod a+x,a-w $@-t && mv -f $@-t $@ -EXTRA_DIST += %D%/gen-perl-protos %D%/aclocal-$(APIVERSION): %D%/aclocal $(AM_V_GEN) rm -f $@; \ diff --git a/bin/aclocal.in b/bin/aclocal.in index 738996f39..64fd66233 100644 --- a/bin/aclocal.in +++ b/bin/aclocal.in @@ -173,7 +173,26 @@ use constant SCAN_M4_DIRS_ERROR => 2; # Prototypes for all subroutines. -#! Prototypes here will automatically be generated by the build system. +sub add_file ($); +sub add_macro ($); +sub check_acinclude (); +sub install_file ($$); +sub list_compare (\@\@); +sub parse_ACLOCAL_PATH (); +sub parse_arguments (); +sub reset_maps (); +sub scan_configure (); +sub scan_configure_dep ($); +sub scan_file ($$$); +sub scan_m4_dirs ($$@); +sub scan_m4_files (); +sub strip_redundant_includes (%); +sub trace_used_macros (); +sub unlink_tmp (;$); +sub usage ($); +sub version (); +sub write_aclocal ($@); +sub xmkdir_p ($); ################################################################ diff --git a/bin/automake.in b/bin/automake.in index ad86cf4a8..3433d3de7 100644 --- a/bin/automake.in +++ b/bin/automake.in @@ -80,8 +80,61 @@ use Carp; ## Subroutine prototypes. ## ## ----------------------- ## -#! Prototypes here will automatically be generated by the build system. - +sub append_exeext (&$); +sub check_gnits_standards (); +sub check_gnu_standards (); +sub check_trailing_slash ($\$); +sub check_typos (); +sub define_files_variable ($\@$$); +sub define_standard_variables (); +sub define_verbose_libtool (); +sub define_verbose_texinfo (); +sub do_check_merge_target (); +sub get_number_of_threads (); +sub handle_compile (); +sub handle_data (); +sub handle_dist (); +sub handle_emacs_lisp (); +sub handle_factored_dependencies (); +sub handle_footer (); +sub handle_gettext (); +sub handle_headers (); +sub handle_install (); +sub handle_java (); +sub handle_languages (); +sub handle_libraries (); +sub handle_libtool (); +sub handle_ltlibraries (); +sub handle_makefiles_serial (); +sub handle_man_pages (); +sub handle_minor_options (); +sub handle_options (); +sub handle_programs (); +sub handle_python (); +sub handle_scripts (); +sub handle_silent (); +sub handle_subdirs (); +sub handle_tags (); +sub handle_targets (); +sub handle_tests (); +sub handle_tests_dejagnu (); +sub handle_texinfo (); +sub handle_user_recursion (); +sub initialize_per_input (); +sub lang_lex_finish (); +sub lang_sub_obj (); +sub lang_vala_finish (); +sub lang_yacc_finish (); +sub locate_aux_dir (); +sub parse_arguments (); +sub scan_aclocal_m4 (); +sub scan_autoconf_files (); +sub silent_flag (); +sub transform ($\%); +sub transform_token ($\%$); +sub usage (); +sub version (); +sub yacc_lex_finish_helper (); ## ----------- ## ## Constants. ## diff --git a/bin/gen-perl-protos b/bin/gen-perl-protos deleted file mode 100755 index 215d275b8..000000000 --- a/bin/gen-perl-protos +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright (C) 2013-2017 Free Software Foundation, 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 3, 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. If not, see . - -use warnings; -use strict; - -my @lines = <>; -my @protos = map { /^(sub \w+\s*\(.*\))/ ? ("$1;") : () } @lines; - -while (defined ($_ = shift @lines)) - { - if (/^#!.* prototypes/i) - { - print "# BEGIN AUTOMATICALLY GENERATED PROTOTYPES\n"; - print join ("\n", sort @protos) . "\n"; - print "# END AUTOMATICALLY GENERATED PROTOTYPES\n"; - } - else - { - print; - } - } diff --git a/bootstrap b/bootstrap index d0766d4c8..1382a9fe8 100755 --- a/bootstrap +++ b/bootstrap @@ -103,11 +103,8 @@ dosubst automake-$APIVERSION/Automake/Config.in \ dosubst m4/amversion.in m4/amversion.m4 # Create temporary replacement for aclocal and automake. -for p in bin/aclocal bin/automake; do - dosubst $p.in $p.tmp - $PERL -w bin/gen-perl-protos $p.tmp > $p.tmp2 - mv -f $p.tmp2 $p.tmp -done +dosubst bin/aclocal.in bin/aclocal.tmp +dosubst bin/automake.in bin/automake.tmp # Create required makefile snippets. $PERL ./gen-testsuite-part > t/testsuite-part.tmp diff --git a/maintainer/check-perl-protos b/maintainer/check-perl-protos new file mode 100755 index 000000000..b1d6a72b5 --- /dev/null +++ b/maintainer/check-perl-protos @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +# +# Copyright (C) 2017 Free Software Foundation, 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 3, 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. If not, see . + +use warnings; +use strict; + +my @lines = <>; +my %forwards = map { /^sub (\w+)\s*\((.*)\);$/ ? ("$1" => "$2") : () } @lines; +my %subs = map { /^sub (\w+)\s*\((.*)\)$/ ? ("$1" => "$2") : () } @lines; +my $error_count = 0; + +# $subs{"foo"} = "$$"; +# $subs{"bar"} = "@"; +# $forwards{"bar"} = "\$"; + +# Check that every subroutine has a matching forward declaration with +# the same prototype. +foreach my $sub (keys (%subs)) + { + # XXX: The location of the subroutine is not reported. + if (grep { $sub eq $_ } keys (%forwards)) + { + if ($forwards{$sub} ne $subs{$sub}) + { + $error_count += 1; + warn ("prototype mismatch for \"$sub\" subroutine\n"); + } + } + else + { + $error_count += 1; + warn ("missing prototype for \"$sub\" subroutine\n"); + } + } + +exit (($error_count == 0) ? 0 : 1); diff --git a/maintainer/syntax-checks.mk b/maintainer/syntax-checks.mk index c8b074008..07a12ab6f 100644 --- a/maintainer/syntax-checks.mk +++ b/maintainer/syntax-checks.mk @@ -51,6 +51,7 @@ sc_mkinstalldirs \ sc_pre_normal_post_install_uninstall \ sc_perl_no_undef \ sc_perl_no_split_regex_space \ +sc_perl_protos \ sc_cd_in_backquotes \ sc_cd_relative_dir \ sc_perl_at_uscore_in_scalar_context \ @@ -102,6 +103,13 @@ sc_sanity_gnu_grep: .PHONY: sc_sanity_gnu_grep $(syntax_check_rules): sc_sanity_gnu_grep +# Check that every subroutine in perl scripts has a corresponding +# prototype +sc_perl_protos: + $(AM_V_GEN)$(srcdir)/maintainer/check-perl-protos \ + <$(srcdir)/bin/aclocal.in && \ + $(srcdir)/maintainer/check-perl-protos <$(srcdir)/bin/automake.in + # These check avoids accidental configure substitutions in the source. # There are exactly 8 lines that should be modified from automake.in to # automake, and 9 lines that should be modified from aclocal.in to -- cgit v1.2.1