From 5468f6034610bb108d89e13dc24c833202ee7388 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 28 Apr 2011 10:20:43 +0200 Subject: maint: add the tight_scope syntax-checking rule This ensures that the only externally scoped symbols are ones that are explicitly marked as "extern" or white-listed like "main". * src/Makefile.am (sc_tight_scope): New rule, copied from coreutils. * cfg.mk (sc_tight_scope): Define, to hook to it from the top level. --- src/Makefile.am | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 257472be..ec3e1769 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,3 +45,43 @@ localedir = $(datadir)/locale AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib EXTRA_DIST = dosbuf.c + +# The following rule is not designed to be portable, +# and relies on tools that not everyone has. + +# Most functions in src/*.c should have static scope. +# Any that don't must be marked with `extern', but `main' +# and `usage' are exceptions: they're always extern, but +# do not need to be marked. Also functions starting with __ +# are exempted due to possibly being added by the compiler +# (when compiled as a shared library for example). +# +# The second nm|grep checks for file-scope variables with `extern' scope. +.PHONY: sc_tight_scope +sc_tight_scope: $(bin_PROGRAMS) + @t=exceptions-$$$$; \ + trap 's=$$?; rm -f $$t; exit $$s' 0; \ + for sig in 1 2 3 13 15; do \ + eval "trap 'v=`expr $$sig + 128`; (exit $$v); exit $$v' $$sig"; \ + done; \ + src=`for f in $(SOURCES); do \ + test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \ + hdr=`for f in $(noinst_HEADERS); do \ + test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \ + ( printf 'main\nusage\n_.*\n'; \ + grep -h -A1 '^extern .*[^;]$$' $$src \ + | grep -vE '^(extern |--)' | sed 's/ .*//'; \ + perl -lne '/^extern (?:struct |const |enum )?\S+ \**(\S*) \(/'\ + -e 'and print $$1' $$hdr; \ + ) | sort -u | sed 's/^/^/;s/$$/$$/' > $$t; \ + nm -e *.$(OBJEXT) | sed -n 's/.* T //p' \ + | sed 's/^_//' | grep -Ev -f $$t \ + && { echo the above functions should have static scope >&2; \ + exit 1; } || : ; \ + ( printf '^program_name$$\n'; \ + perl -lne '/^extern .*?\**(\w+);/ and print "^$$1\$$"' \ + $$hdr *.h ) | sort -u > $$t; \ + nm -e *.$(OBJEXT) | sed -n 's/.* [BD] //p' \ + | sed 's/^_//' | grep -Ev -f $$t \ + && { echo the above variables should have static scope >&2; \ + exit 1; } || : -- cgit v1.2.1