From 811627be3732ccbdaaea86b0dafdda1748375671 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 9 May 2011 12:30:55 +0200 Subject: [PATCH] maint.mk: add a syntax-check rule to ensure tightly-scoped symbols * top/maint.mk (sc_tight_scope): New rule. (sc_tight_scope-0): New rule, ifdef'd out. (_gl_TS_dir): Default. (_gl_TS_unmarked_extern_functions, _gl_TS_function_regex): Define. (_gl_TS_unmarked_extern_vars, _gl_TS_var_regex): Define. --- ChangeLog | 9 ++++++++ top/maint.mk | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/ChangeLog b/ChangeLog index f7e0a330bd..7feeba08dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-09 Jim Meyering + + maint.mk: add a syntax-check rule to ensure tightly-scoped symbols + * top/maint.mk (sc_tight_scope): New rule. + (sc_tight_scope-0): New rule, ifdef'd out. + (_gl_TS_dir): Default. + (_gl_TS_unmarked_extern_functions, _gl_TS_function_regex): Define. + (_gl_TS_unmarked_extern_vars, _gl_TS_var_regex): Define. + 2011-05-09 Simon Josefsson * m4/gc.m4: Remove gl_PREREQ_GC (not used). Reported by Bruno diff --git a/top/maint.mk b/top/maint.mk index 03a9036752..793915cc7f 100644 --- a/top/maint.mk +++ b/top/maint.mk @@ -1325,3 +1325,65 @@ update-copyright: grep -l -w Copyright \ $$(export VC_LIST_EXCEPT_DEFAULT=COPYING && $(VC_LIST_EXCEPT)) \ | $(update-copyright-env) xargs $(build_aux)/$@ + +# NOTE: This test is silently skipped if $(_gl_TS_dir)/Makefile.am +# does not mention noinst_HEADERS. +# NOTE: to override these _gl_TS_* default values, you must +# define the variable(s) using "export" in cfg.mk. +_gl_TS_dir ?= src +ALL_RECURSIVE_TARGETS += sc_tight_scope +sc_tight_scope: tight-scope.mk + @grep noinst_HEADERS $(_gl_TS_dir)/Makefile.am > /dev/null 2>&1 \ + && $(MAKE) -s -C $(_gl_TS_dir) \ + -f Makefile -f '$(abs_srcdir)/tight-scope.mk' $@-0 \ + || : + @rm -f $< + +tight-scope.mk: $(ME) + @rm -f $@ $@-t + @perl -ne '/^# TS-start/.../^# TS-end/ and print' $(ME) > $@-t + @chmod a=r $@-t && mv $@-t $@ + +ifeq (a,b) +# TS-start +# Most functions 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. +_gl_TS_unmarked_extern_functions ?= main usage +_gl_TS_function_regex ?= \ + ^(?:extern|XTERN) +(?:void|(?:struct |const |enum )?\S+) +\**(\S+) +\( + +# The second nm|grep checks for file-scope variables with `extern' scope. +# Without gnulib's progname module, you might put program_name here. +_gl_TS_unmarked_extern_vars ?= +_gl_TS_var_regex ?= ^(?:extern|XTERN) .*?\**(\w+)(\[.*?\])?; +.PHONY: sc_tight_scope-0 +sc_tight_scope-0: $(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 '^%s$$\n' $(_gl_TS_unmarked_extern_functions); \ + grep -h -A1 '^extern .*[^;]$$' $$src \ + | grep -vE '^(extern |--)' | sed 's/ .*//'; \ + perl -lne '/$(_gl_TS_function_regex)/' \ + -e 'and print $$1' $$hdr; \ + ) | sort -u | sed 's/^/^/;s/$$/$$/' > $$t; \ + nm -e *.$(OBJEXT) | sed -n 's/.* T //p' | grep -Ev -f $$t \ + && { echo the above functions should have static scope >&2; \ + exit 1; } || : ; \ + ( printf '^%s$$\n' $(_gl_TS_unmarked_extern_vars); \ + perl -lne '/$(_gl_TS_var_regex)/ and print "^$$1\$$"' \ + $$hdr *.h ) | sort -u > $$t; \ + nm -e *.$(OBJEXT) | sed -n 's/.* [BCDGRS] //p' \ + | sort -u | grep -Ev -f $$t \ + && { echo the above variables should have static scope >&2; \ + exit 1; } || : +# TS-end +endif -- 2.30.2