Bruno Haible wrote: > Would it be possible to generalize the sc_prohibit_*_without_use rules > to more header files easily? > > # Don't include this header unless you use one of its functions. > sc_prohibit_error_without_use: > @h='error.h' \ > re='\<error(_at_line|_print_progname|_one_per_line|_message_count)? > *\('\ > $(_sc_header_without_use) > > How about generating the list of identifiers that are declared in a header > file (macros, variables, functions, type, struct names, union names, > enum names, enum tags) and compute a regular expression that matches them? > > For the first part, one could use 'ctags'?
Good idea. > Or, if only 'extern' declared > entities matter, one can use this script that I use in libunistring: > http://git.savannah.gnu.org/gitweb/?p=libunistring.git;a=blob;f=lib/declared.sh For some headers, extern symbols is enough. For others, there are no extern symbols and rather only macros. In general, everything matters: types, macros, extern definitions. It'd be great to automate something. > Also, it would be useful to extend this to POSIX header files, such > as <stdlib.h> or <unistd.h>, by making use of the info found in > glibc/conform/data/*.h-data. Here's an example where I used Regexp::Assemble to generate the regexp: # Don't include xalloc.h unless you use one of its functions. # Consider these symbols: # perl -lne '/^# *define (\w+)\(/ and print $1' lib/xalloc.h|grep -v '^__'; # perl -lne '/^(?:extern )?(?:void|char) \*?(\w+) *\(/ and print $1' lib/xalloc.h # Divide into two sets on case, and filter each through this: # | sort | perl -MRegexp::Assemble -le \ # 'print Regexp::Assemble->new(file => "/dev/stdin")->as_string'|sed 's/\?://g' # Note this was produced by the above: # _xa1 = \ #x(((2n?)?re|c(har)?|n(re|m)|z)alloc|alloc_(oversized|die)|m(alloc|emdup)|strdup) # But we can do better, in at least two ways: # 1) take advantage of two "dup"-suffixed strings: # x(((2n?)?re|c(har)?|n(re|m)|[mz])alloc|alloc_(oversized|die)|(mem|str)dup) # 2) notice that "c(har)?|[mz]" is equivalent to the shorter and more readable # "char|[cmz]" # x(((2n?)?re|char|n(re|m)|[cmz])alloc|alloc_(oversized|die)|(mem|str)dup) _xa1 = x(((2n?)?re|char|n(re|m)|[cmz])alloc|alloc_(oversized|die)|(mem|str)dup) _xa2 = X([CZ]|N?M)ALLOC sc_prohibit_xalloc_without_use: @h='xalloc.h' \ re='\<($(_xa1)|$(_xa2)) *\('\ $(_sc_header_without_use)