summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2011-04-28 10:20:43 +0200
committerJim Meyering <meyering@redhat.com>2011-04-28 10:34:47 +0200
commit5468f6034610bb108d89e13dc24c833202ee7388 (patch)
tree837e91eff2ebecbcfc052ad08a1ea8cc75a54b37 /src
parentabcb2b51a6ecd30134074277a611f2dea71421c9 (diff)
downloadgrep-5468f6034610bb108d89e13dc24c833202ee7388.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am40
1 files changed, 40 insertions, 0 deletions
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; } || :