[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] maint.mk: add a syntax-check rule to ensure tightly-scoped symbo
From: |
Jim Meyering |
Subject: |
[PATCH] maint.mk: add a syntax-check rule to ensure tightly-scoped symbols |
Date: |
Mon, 09 May 2011 12:44:14 +0200 |
I've been using a precursor of this rule in coreutils for many years,
added it to idutils a year or two ago and added it to grep just recently.
I did not like having to duplicate and customize bits
in the separate copies, depending on where I used it,
so finally have made it general enough so that the same
code works in coreutils, diffutils, gzip and grep.
The only customization required was for gzip:
# Tell the tight_scope rule that sources are in ".".
export _gl_TS_dir = .
# Tell the tight_scope rule that these variables are deliberately "extern".
export _gl_TS_unmarked_extern_vars = \
block_start d_buf inbuf outbuf prev read_buf strstart window
The first is to tell the rule that the sources are in ".",
rather than src/, and the second is to identify as deliberately-extern
that list of variables. An alternative would have been to add
explicitly "extern" declarations in a file like gzip.h, but that
would have been more invasive.
There's still room for generalization -- like if you
have more than one directory in which to run this rule.
And I probably should not have hard-coded XTERN in the
default regexp. I expect to remove it eventually, and to add
the kludge only for gzip, where it's currently required.
As a syntax-check rule, this one is unusual in two ways:
- it creates a file in the current (top level) directory
- it extracts a portion of maint.mk (sc_tight_scope-0) to
be used in a sub-make.
- this new rule must be customized, yet it is being run in the sub-make
where normal assignments from cfg.mk would not take affect.
Thus, any customizing assignment must use "export", as mentioned
in the comments.
>From 811627be3732ccbdaaea86b0dafdda1748375671 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
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(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f7e0a33..7feeba0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-05-09 Jim Meyering <address@hidden>
+
+ 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 <address@hidden>
* m4/gc.m4: Remove gl_PREREQ_GC (not used). Reported by Bruno
diff --git a/top/maint.mk b/top/maint.mk
index 03a9036..793915c 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' address@hidden
\
+ || :
+ @rm -f $<
+
+tight-scope.mk: $(ME)
+ @rm -f $@ address@hidden
+ @perl -ne '/^# TS-start/.../^# TS-end/ and print' $(ME) > address@hidden
+ @chmod a=r address@hidden && mv address@hidden $@
+
+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
--
1.7.5.1.332.g711ff
- [PATCH] maint.mk: add a syntax-check rule to ensure tightly-scoped symbols,
Jim Meyering <=