ME := maint.mk
ifneq ($(build_aux),) $(error "$(ME): \ set $$(_build-aux) relative to $$(srcdir) instead of $$(build_aux)") endif
gzip_rsyncable := \ $(shell gzip --help 2>/dev/null|grep rsyncable >/dev/null \ && printf %s --rsyncable) GZIP_ENV = '--no-name --best $(gzip_rsyncable)'
GIT = git VC = $(GIT)
VC_LIST = $(srcdir)/$(_build-aux)/vc-list-files -C $(srcdir)
VC_LIST_ALWAYS_EXCLUDE_REGEX ?= ^$$
_dot_escaped_srcdir = $(subst .,.,$(srcdir))
ifeq ($(srcdir),.) _prepend_srcdir_prefix = else _prepend_srcdir_prefix = | sed 's|^|$(srcdir)/|' endif
_sc_excl = \ $(if $(exclude_file_name_regexp--$@),$(exclude_file_name_regexp--$@),^$$) VC_LIST_EXCEPT = \ $(VC_LIST) | sed 's|^$(_dot_escaped_srcdir)/||' \ | if test -f $(srcdir)/.x-$@; then grep -vEf $(srcdir)/.x-$@; \ else grep -Ev -e "$${VC_LIST_EXCEPT_DEFAULT-ChangeLog}"; fi \ | grep -Ev -e '($(VC_LIST_ALWAYS_EXCLUDE_REGEX)|$(_sc_excl))' \ $(_prepend_srcdir_prefix)
ifeq ($(origin prev_version_file), undefined) prev_version_file = $(srcdir)/.prev-version endif
PREV_VERSION := $(shell cat $(prev_version_file) 2>/dev/null) VERSION_REGEXP = $(subst .,.,$(VERSION)) PREV_VERSION_REGEXP = $(subst .,.,$(PREV_VERSION))
ifeq ($(VC),$(GIT)) this-vc-tag = v$(VERSION) this-vc-tag-regexp = v$(VERSION_REGEXP) else tag-package = $(shell echo "$(PACKAGE)" | tr '[:lower:]' '[:upper:]') tag-this-version = $(subst .,_,$(VERSION)) this-vc-tag = $(tag-package)-$(tag-this-version) this-vc-tag-regexp = $(this-vc-tag) endif my_distdir = $(PACKAGE)-$(VERSION)
release_archive_dir ?= ../release
gnu_ftp_host-alpha = alpha.gnu.org gnu_ftp_host-beta = alpha.gnu.org gnu_ftp_host-stable = ftp.gnu.org gnu_rel_host ?= $(gnu_ftp_host-$(RELEASE_TYPE))
ifeq ($(gnu_rel_host),ftp.gnu.org) url_dir_list ?= http://ftpmirror.gnu.org/$(PACKAGE) else url_dir_list ?= ftp://$(gnu_rel_host)/gnu/$(PACKAGE) endif
today = $(shell date +%Y-%m-%d)
news-check-lines-spec ?= 1,10 news-check-regexp ?= '^*.* $(VERSION_REGEXP) ($(today))'
export LC_ALL = C
_cfg_mk := $(shell test -f $(srcdir)/cfg.mk && echo '$(srcdir)/cfg.mk')
syntax-check-rules := $(sort $(shell sed -n 's/^(sc_[a-zA-Z0-9_-]):./\1/p' \ $(srcdir)/$(ME) $(_cfg_mk))) .PHONY: $(syntax-check-rules)
ifeq ($(shell $(VC_LIST) >/dev/null 2>&1; echo $$?),0) local-checks-available += $(syntax-check-rules) else local-checks-available += no-vc-detected no-vc-detected: @echo "No version control files detected; skipping syntax check" endif .PHONY: $(local-checks-available)
$(syntax-check-rules): %: %.m sc_m_rules_ = $(patsubst %, %.m, $(syntax-check-rules)) .PHONY: $(sc_m_rules_) $(sc_m_rules_): @echo $(patsubst sc_%.m, %, $@) @date +%s.%N > .sc-start-$(basename $@)
sc_z_rules_ = $(patsubst %, %.z, $(syntax-check-rules)) .PHONY: $(sc_z_rules_) $(sc_z_rules_): %.z: % @end=$$(date +%s.%N); \ start=$$(cat .sc-start-$); \ rm -f .sc-start-$; \ awk -v s=$$start -v e=$$end \ 'END {printf "%.2f $(patsubst sc_%,%,$*)\n", e - s}' < /dev/null
local-check := \ $(patsubst sc_%, sc_%.z, \ $(filter-out $(local-checks-to-skip), $(local-checks-available)))
syntax-check: $(local-check)
export require = export prohibit = export exclude = export in_vc_files = export in_files = export containing = export non_containing = export halt = export with_grep_options =
export ignore_case = _ignore_case = $$(test -n "$$ignore_case" && printf %s -i || :)
define _sc_say_and_exit dummy=; : so we do not need a semicolon before each use; \ { printf '%s\n' "$(ME): $$msg" 1>&2; exit 1; }; endef
sc_avoid_if_before_free: @$(srcdir)/$(_build-aux)/useless-if-before-free \ $(useless_free_options) \ $$($(VC_LIST_EXCEPT) | grep -v useless-if-before-free) && \ { echo '$(ME): found useless "if" before "free" above' 1>&2; \ exit 1; } || :
sc_cast_of_argument_to_free: @prohibit='\<free ( (' halt="don't cast free argument" \ $(_sc_search_regexp)
sc_cast_of_x_alloc_return_value: @prohibit='*) x(m|c|re)alloc>' \ halt="don't cast xalloc return value" \ $(_sc_search_regexp)
sc_cast_of_alloca_return_value: @prohibit='*) *alloca>' \ halt="don't cast alloca return value" \ $(_sc_search_regexp)
sc_space_tab: @prohibit='[ ] ' \ halt='found SPACE-TAB sequence; remove the SPACE' \ $(_sc_search_regexp)
sc_prohibit_atoi_atof: @prohibit='\<([fs]?scanf|ato([filq]|ll)) (' \ halt='do not use scan''f, ato''f, ato''i, ato''l, ato''ll or ato''q' \ $(_sc_search_regexp)
sp_ = strcmp (.+) sc_prohibit_strcmp: @prohibit='! strcmp (|\<$(sp_) [!=]=|[!=]= $(sp_)' \ exclude=':# define STRN?EQ(' \ halt='$(ME): replace strcmp calls above with STREQ/STRNEQ' \ $(_sc_search_regexp)
sc_prohibit_magic_number_exit: @prohibit='(^|[^.])\<(usage|exit) ?([0-9]|\<error ?([1-9][0-9],' \ halt='use EXIT_ values rather than magic number' \ $(_sc_search_regexp)
sc_error_exit_success: @prohibit='error *(EXIT_SUCCESS,' \ in_vc_files='.[chly]$$' \ halt='found error (EXIT_SUCCESS' \ $(_sc_search_regexp)
sc_error_message_warn_fatal: @grep -nEA2 '[^rp]error *(' $$($(VC_LIST_EXCEPT)) \ | grep -E '"Warning|"Fatal|"fatal' && \ { echo '$(ME): use FATAL, WARNING or warning' 1>&2; \ exit 1; } || :
sc_error_message_uppercase: @grep -nEA2 '[^rp]error *(' $$($(VC_LIST_EXCEPT)) \ | grep -E '"[A-Z]' \ | grep -vE '"FATAL|"WARNING|"Java|"C#|PRIuMAX' && \ { echo '$(ME): found capitalized error message' 1>&2; \ exit 1; } || :
sc_error_message_period: @grep -nEA2 '[^rp]error *(' $$($(VC_LIST_EXCEPT)) \ | grep -E '[^."]."' && \ { echo '$(ME): found error message ending in period' 1>&2; \ exit 1; } || :
sc_file_system: @prohibit=file''system \ ignore_case=1 \ halt='found use of "file''system"; spell it "file system"' \ $(_sc_search_regexp)
sc_prohibit_have_config_h: @prohibit='^# if.HAVE''_CONFIG_H' \ halt='found use of HAVE''_CONFIG_H; remove' \ $(_sc_search_regexp)
config_h_header ?= <config\.h> sc_require_config_h: @require='^# *include $(config_h_header)' \ in_vc_files='.c$$' \ halt='the above files do not include <config.h>' \ $(_sc_search_regexp)
sc_require_config_h_first: @if $(VC_LIST_EXCEPT) | grep -l '.c$$' > /dev/null; then \ fail=0; \ for i in $$($(VC_LIST_EXCEPT) | grep '.c$$'); do \ grep '^# include>' $$i | sed 1q \ | grep -E '^# include $(config_h_header)' > /dev/null \ || { echo $$i; fail=1; }; \ done; \ test $$fail = 1 && \ { echo '$(ME): the above files include some other header' \ 'before <config.h>' 1>&2; exit 1; } || :; \ else :; \ fi
sc_prohibit_HAVE_MBRTOWC: @prohibit='\bHAVE_MBRTOWC\b' \ halt="do not use $$prohibit; it is always defined" \ $(_sc_search_regexp)
define _sc_header_without_use
dummy=; : so we do not need a semicolon before each use; \
h_esc=echo '[<"]'"$$h"'[">]'|sed 's/\./\\\\./g'
; \
if $(VC_LIST_EXCEPT) | grep -l '.c$$' > /dev/null; then \
files=$$(grep -l '^# *include '"$$h_esc" \
$$($(VC_LIST_EXCEPT) | grep '.c$$')) && \
grep -LE "$$re" $$files | grep . && \
{ echo "$(ME): the above files include $$h but don't use it" \
1>&2; exit 1; } || :; \
else :; \
fi
endef
sc_prohibit_assert_without_use: @h='assert.h' re='\<assert *(' $(_sc_header_without_use)
sc_prohibit_close_stream_without_use: @h='close-stream.h' re='\<close_stream *(' $(_sc_header_without_use)
sc_prohibit_getopt_without_use: @h='getopt.h' re='\<getopt(_long)? *(' $(_sc_header_without_use)
sc_prohibit_quotearg_without_use: @h='quotearg.h' re='\<quotearg(_[^ ]+)? *(' $(_sc_header_without_use)
sc_prohibit_quote_without_use: @h='quote.h' re='\<quote((_n)? *(|_quoting_options>)' \ $(_sc_header_without_use)
sc_prohibit_long_options_without_use: @h='long-options.h' re='\<parse_long_options *(' \ $(_sc_header_without_use)
sc_prohibit_inttostr_without_use: @h='inttostr.h' re='\<(off|[iu]max|uint)tostr *(' \ $(_sc_header_without_use)
sc_prohibit_ignore_value_without_use: @h='ignore-value.h' re='\<ignore_(value|ptr) *(' \ $(_sc_header_without_use)
sc_prohibit_error_without_use: @h='error.h' \ re='\<error(_at_line|_print_progname|_one_per_line|_message_count)? *('\ $(_sc_header_without_use)
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)
hash_re = \ clear|delete|free|get(first|next)|insert|lookup|print_statistics|reset_tuning hash_fn = \<($(_hash_re)) *( _hash_struct = (struct )?\<[Hh]ash(table|tuning)> sc_prohibit_hash_without_use: @h='hash.h' \ re='$(_hash_fn)|$(_hash_struct)'\ $(_sc_header_without_use)
sc_prohibit_cloexec_without_use: @h='cloexec.h' re='\<(set_cloexec_flag|dup_cloexec) *(' \ $(_sc_header_without_use)
sc_prohibit_posixver_without_use: @h='posixver.h' re='\<posix2_version *(' $(_sc_header_without_use)
sc_prohibit_same_without_use: @h='same.h' re='\<same_name *(' $(_sc_header_without_use)
sc_prohibit_hash_pjw_without_use: @h='hash-pjw.h' \ re='\<hash_pjw>' \ $(_sc_header_without_use)
sc_prohibit_safe_read_without_use: @h='safe-read.h' re='(\<SAFE_READ_ERROR>|\<safe_read *()' \ $(_sc_header_without_use)
sc_prohibit_argmatch_without_use: @h='argmatch.h' \ re='(\<(ARRAY_CARDINALITY|X?ARGMATCH(|TO_ARGUMENT|_VERIFY))>|\<(invalid_arg|argmatch(_exit_fn|(in)?valid)?) *()' \ $(_sc_header_without_use)
sc_prohibit_canonicalize_without_use: @h='canonicalize.h' \ re='CAN_(EXISTING|ALL_BUT_LAST|MISSING)|canonicalize_(mode_t|filename_mode|file_name)' \ $(_sc_header_without_use)
sc_prohibit_root_dev_ino_without_use: @h='root-dev-ino.h' \ re='(\<ROOT_DEV_INO_(CHECK|WARN)>|\<get_root_dev_ino *()' \ $(_sc_header_without_use)
sc_prohibit_openat_without_use: @h='openat.h' \ re='\<(openat_(permissive|needs_fchdir|(save|restore)_fail)|l?(stat|ch(own|mod))at|(euid)?accessat)>' \ $(_sc_header_without_use)
ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\ |isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper sc_prohibit_c_ctype_without_use: @h='c-ctype.h' re='\<c_($(ctype_re)) *(' \ $(_sc_header_without_use)
_empty = _sp = $(_empty) $(_empty)
_sig_functions = \ bsd_signal kill killpg pthread_kill pthread_sigmask raise sigaction \ sigaddset sigaltstack sigdelset sigemptyset sigfillset sighold sigignore \ siginterrupt sigismember signal sigpause sigpending sigprocmask sigqueue \ sigrelse sigset sigsuspend sigtimedwait sigwait sigwaitinfo _sig_function_re = $(subst $(_sp),|,$(strip $(_sig_functions)))
_sig_types_and_consts = \ MINSIGSTKSZ SA_NOCLDSTOP SA_NOCLDWAIT SA_NODEFER SA_ONSTACK \ SA_RESETHAND SA_RESTART SA_SIGINFO SIGEV_NONE SIGEV_SIGNAL \ SIGEV_THREAD SIGSTKSZ SIG_BLOCK SIG_SETMASK SIG_UNBLOCK SS_DISABLE \ SS_ONSTACK mcontext_t pid_t sig_atomic_t sigevent siginfo_t sigset_t \ sigstack sigval stack_t ucontext_t
_sig_names = \ SIGABRT SIGALRM SIGALRM1 SIGBUS SIGCANCEL SIGCHLD SIGCLD SIGCONT \ SIGDANGER SIGDIL SIGEMT SIGFPE SIGFREEZE SIGGRANT SIGHUP SIGILL \ SIGINFO SIGINT SIGIO SIGIOT SIGKAP SIGKILL SIGKILLTHR SIGLOST SIGLWP \ SIGMIGRATE SIGMSG SIGPHONE SIGPIPE SIGPOLL SIGPRE SIGPROF SIGPWR \ SIGQUIT SIGRETRACT SIGSAK SIGSEGV SIGSOUND SIGSTKFLT SIGSTOP SIGSYS \ SIGTERM SIGTHAW SIGTRAP SIGTSTP SIGTTIN SIGTTOU SIGURG SIGUSR1 \ SIGUSR2 SIGVIRT SIGVTALRM SIGWAITING SIGWINCH SIGWIND SIGWINDOW \ SIGXCPU SIGXFSZ _sig_syms_re = $(subst $(_sp),|,$(strip $(_sig_names) $(_sig_types_and_consts)))
sc_prohibit_signal_without_use: @h='signal.h' \ re='\<($(_sig_function_re)) *(|\<($(_sig_syms_re))>' \ $(_sc_header_without_use)
sc_prohibit_stdio--_without_use: @h='stdio--.h' re='\<((f(re)?|p)open|tmpfile) *(' \ $(_sc_header_without_use)
sc_prohibit_stdio-safer_without_use: @h='stdio-safer.h' re='\<((f(re)?|p)open|tmpfile)_safer *(' \ $(_sc_header_without_use)
sc_prohibit_strings_without_use: @h='strings.h' \ re='\<(strn?casecmp|ffs(ll)?)>' \ $(_sc_header_without_use)
_intprops_names = \ TYPE_IS_INTEGER TYPE_TWOS_COMPLEMENT TYPE_ONES_COMPLEMENT \ TYPE_SIGNED_MAGNITUDE TYPE_SIGNED TYPE_MINIMUM TYPE_MAXIMUM \ INT_BITS_STRLEN_BOUND INT_STRLEN_BOUND INT_BUFSIZE_BOUND \ INT_ADD_RANGE_OVERFLOW INT_SUBTRACT_RANGE_OVERFLOW \ INT_NEGATE_RANGE_OVERFLOW INT_MULTIPLY_RANGE_OVERFLOW \ INT_DIVIDE_RANGE_OVERFLOW INT_REMAINDER_RANGE_OVERFLOW \ INT_LEFT_SHIFT_RANGE_OVERFLOW INT_ADD_OVERFLOW INT_SUBTRACT_OVERFLOW \ INT_NEGATE_OVERFLOW INT_MULTIPLY_OVERFLOW INT_DIVIDE_OVERFLOW \ INT_REMAINDER_OVERFLOW INT_LEFT_SHIFT_OVERFLOW _intprops_syms_re = $(subst $(_sp),|,$(strip $(_intprops_names)))
sc_prohibit_intprops_without_use: @h='intprops.h' \ re='\<($(_intprops_syms_re)) *(' \ $(_sc_header_without_use)
_stddef_syms_re = NULL|offsetof|ptrdiff_t|size_t|wchar_t
sc_prohibit_stddef_without_use: @h='stddef.h' \ re='\<($(_stddef_syms_re))>' \ $(_sc_header_without_use)
_de1 = dirfd|(close|(fd)?open|read|rewind|seek|tell)dir(64)?(_r)? _de2 = (versionsort|struct dirent|getdirentries|alphasort|scandir(at)?)(64)? _de3 = MAXNAMLEN|DIR|ino_t|d_ino|d_fileno|d_namlen _dirent_syms_re = $(_de1)|$(_de2)|$(_de3)
sc_prohibit_dirent_without_use: @h='dirent.h' \ re='\<($(_dirent_syms_re))>' \ $(_sc_header_without_use)
sc_prohibit_verify_without_use: @h='verify.h' \ re='\<(verify(true|expr)?|static_assert) *(' \ $(_sc_header_without_use)
sc_prohibit_xfreopen_without_use: @h='xfreopen.h' re='\<xfreopen *(' $(_sc_header_without_use)
sc_obsolete_symbols: @prohibit='\<(HAVE''_FCNTL_H|O''_NDELAY)>' \ halt='do not use HAVE''_FCNTL_H or O'_NDELAY \ $(_sc_search_regexp)
sc_changelog: @prohibit='^[^12 ]' \ in_vc_files='^ChangeLog$$' \ halt='found unexpected prefix in a ChangeLog' \ $(_sc_search_regexp)
sc_program_name: @require='set_program_name (m?argv[0]);' \ in_vc_files='.c$$' \ containing='\<main (' \ halt='the above files do not call set_program_name' \ $(_sc_search_regexp)
sc_bindtextdomain: @require='bindtextdomain (' \ in_vc_files='.c$$' \ containing='\<main (' \ halt='the above files do not call bindtextdomain' \ $(_sc_search_regexp)
Exit_witness_file ?= tests/test-lib.sh Exit_base := $(notdir $(Exit_witness_file)) sc_require_test_exit_idiom: @if test -f $(srcdir)/$(Exit_witness_file); then \ die=0; \ for i in $$(grep -l -F 'srcdir/$(Exit_base)' \ $$($(VC_LIST) tests)); do \ tail -n1 $$i | grep '^Exit .' > /dev/null \ && : || { die=1; echo $$i; } \ done; \ test $$die = 1 && \ { echo 1>&2 '$(ME): the final line in each of the above is not:'; \ echo 1>&2 'Exit something'; \ exit 1; } || :; \ fi
sc_trailing_blank: @prohibit='[ ]$$' \ halt='found trailing blank(s)' \ $(_sc_search_regexp)
longopt_re = --[a-z][0-9A-Za-z-]([?=[0-9A-Za-z-]]?)? sc_two_space_separator_in_usage: @prohibit='^ (-[A-Za-z],)? $(longopt_re) [^ ].\$$' \ halt='help2man requires at least two spaces between an option and its description'\ $(_sc_search_regexp)
_gl_translatable_diag_func_re ?= error
sc_unmarked_diagnostics: @prohibit='\<$(gl_translatable_diag_func_re) ([^"]"[^"]*[a-z]{3}' \ exclude='(|ngettext ?)(' \ halt='$(ME): found unmarked diagnostic(s)' \ $(_sc_search_regexp)
sc_useless_cpp_parens: @prohibit='^# if .defined *(' \ halt='found useless parentheses in cpp directive' \ $(_sc_search_regexp)
gl_assured_headers_ = \ cd $(gnulib_dir)/lib && echo *.in.h|sed 's/.in.h//g'
az_ = abcdefghijklmnopqrstuvwxyz AZ_ = ABCDEFGHIJKLMNOPQRSTUVWXYZ gl_header_upper_case_or_ = \ $$($(gl_assured_headers_) \ | tr $(az_)/.- $(AZ_)___ \ | tr -s ' ' '|' \ ) sc_prohibit_always_true_header_tests: @or=$(gl_header_upper_case_or_); \ re="HAVE_($$or)H"; \ prohibit='\<'"$$re"'>' \ halt=$$(printf '%s\n' \ 'do not test the above HAVE<header>_H symbol(s);' \ ' with the corresponding gnulib module, they are always true') \ $(_sc_search_regexp)
gl_other_headers_ ?= \ intprops.h \ openat.h \ stat-macros.h
gl_extract_significant_defines_ = \ /^# define ([^_ (][^ (])(\s*(|\s+\w+)/\ && $$2 !~ /(?:rpl_|used_without)/\ && $$1 !~ /^(?:NSIG|ENODATA)$$/\ && $$1 !~ /^(?:SA_RESETHAND|SA_RESTART)$$/\ and print $$1
define def_sym_regex gen_h=$(gl_generated_headers_); \ (cd $(gnulib_dir)/lib; \ for f in .in.h $(gl_other_headers_); do \ test -f $$f \ && perl -lne '$(gl_extract_significant_defines_)' $$f; \ done; \ ) | sort -u \ | sed 's/^/^ # (define|undef) /;s/$$/\>/' endef
sc_prohibit_always-defined_macros: @if test -d $(gnulib_dir); then \ case $$(echo all: | grep -l -f - Makefile) in Makefile);; *) \ echo '$(ME): skipping $@: you lack GNU grep' 1>&2; exit 0;; \ esac; \ $(def_sym_regex) | grep -E -f - $$($(VC_LIST_EXCEPT)) \ && { echo '$(ME): define the above via some gnulib .h file' \ 1>&2; exit 1; } || :; \ fi
sc_prohibit_backup_files: @$(VC_LIST) | grep '~$$' && \ { echo '$(ME): found version controlled backup file' 1>&2; \ exit 1; } || :
sc_GPL_version: @prohibit='either ''version [^3]' \ halt='GPL vN, N!=3' \ $(_sc_search_regexp)
_GFDL_regexp = (Free ''Documentation.*Version 1.[^3]|Version 1.[^3] or any) sc_GFDL_version: @prohibit='$(_GFDL_regexp)' \ halt='GFDL vN, N!=3' \ $(_sc_search_regexp)
texinfo_suffix_re_ ?= .(txi|texi(nfo)?)$$ sc_texinfo_acronym: @prohibit='@acronym{' \ in_vc_files='$(texinfo_suffix_re_)' \ halt='found use of Texinfo @acronym{}' \ $(_sc_search_regexp)
cvs_keywords = \ Author|Date|Header|Id|Name|Locker|Log|RCSfile|Revision|Source|State
sc_prohibit_cvs_keyword: @prohibit='\$$($(cvs_keywords))\$$' \ halt='do not use CVS keyword expansion' \ $(_sc_search_regexp)
require_exactly_one_NL_at_EOF_ = \ foreach my $$f (@ARGV) \ { \ open F, "<", $$f or (warn "failed to open $$f: $$!\n"), next; \ my $$p = sysseek (F, -2, 2); \ my $$c = "seek failure probably means file has < 2 bytes; ignore"; \ my $$last_two_bytes; \ defined $$p and $$p = sysread F, $$last_two_bytes, 2; \ close F; \ $$c = "ignore read failure"; \ $$p && ($$last_two_bytes eq "\n\n" \ || substr ($$last_two_bytes,1) ne "\n") \ and (print $$f), $$fail=1; \ } \ END { exit defined $$fail } sc_prohibit_empty_lines_at_EOF: @perl -le '$(require_exactly_one_NL_at_EOF_)' $$($(VC_LIST_EXCEPT)) \ || { echo '$(ME): empty line(s) or no newline at EOF' \ 1>&2; exit 1; } || :
sc_prohibit_stat_st_blocks: @prohibit='[.>]st_blocks' \ halt='do not use st_blocks; use ST_NBLOCKS' \ $(_sc_search_regexp)
sc_prohibit_S_IS_definition: @prohibit='^ # define S_IS' \ halt='do not define S_IS macros; include <sys/stat.h>' \ $(_sc_search_regexp)
perl_filename_lineno_text_ = \ -e ' {' \ -e ' $$n = ($$` =~ tr/\n/\n/ + 1);' \ -e ' ($$v = $$&) =~ s/\n/\n/g;' \ -e ' print "$$ARGV:$$n:$$v\n";' \ -e ' }'
prohibit_doubled_word_RE_ ?= \ /\b(then?|[iao]n|i[fst]|but|f?or|at|and|[dt]o)\s+\1\b/gims prohibit_doubled_word_ = \ -e 'while ($(prohibit_doubled_word_RE_))' \ $(perl_filename_lineno_text_)
ignore_doubled_word_match_RE_ ?= ^$$
sc_prohibit_doubled_word: @perl -n -0777 $(prohibit_doubled_word_) $$($(VC_LIST_EXCEPT)) \ | grep -vE '$(ignore_doubled_word_match_RE_)' \ | grep . && { echo '$(ME): doubled words' 1>&2; exit 1; } || :
bad_xref_re_ ?= (?:[\w,:;] +|(?:see|also)\s+)\@xref{ bad_pxref_re_ ?= (?:[.!?]|(?:see|also))\s+\@pxref{ prohibit_undesirable_word_seq_RE_ ?= \ /(?:\bcan\s+not\b|$(bad_xref_re_)|$(bad_pxref_re_))/gims prohibit_undesirable_word_seq_ = \ -e 'while ($(prohibit_undesirable_word_seq_RE_))' \ $(perl_filename_lineno_text_)
ignore_undesirable_word_sequence_RE_ ?= ^$$
sc_prohibit_undesirable_word_seq: @perl -n -0777 $(prohibit_undesirable_word_seq_) \ $$($(VC_LIST_EXCEPT)) \ | grep -vE '$(ignore_undesirable_word_sequence_RE_)' | grep . \ && { echo '$(ME): undesirable word sequence' >&2; exit 1; } || :
_ptm1 = use "test C1 && test C2", not "test C1 -''a C2" _ptm2 = use "test C1 || test C2", not "test C1 -''o C2"
sc_prohibit_test_minus_ao: @prohibit='(\<test| [+) .+ -[ao] ' \ halt='$(_ptm1); $(_ptm2)' \ $(_sc_search_regexp)
sc_prohibit_test_double_equal: @prohibit='(\<test| [+) .+ == ' \ containing='#! /bin/[a-z]sh' \ halt='use "test x = x", not "test x =''= x"' \ $(_sc_search_regexp)
sc_proper_name_utf8_requires_ICONV: @progs=$$(grep -l 'proper_name_utf8 ''("' $$($(VC_LIST_EXCEPT)));\ if test "x$$progs" != x; then \ fail=0; \ for p in $$progs; do \ dir=$$(dirname "$$p"); \ perl -0777 \ -ne 'exit !(/^LDADD =(.+?[^\]\n)/ms && $$1 =~ /ICONV/)' \ $$dir/Makefile.am && continue; \ base=$$(basename "$$p" .c); \ grep "$${base}_LDADD.*ICONV)" $$dir/Makefile.am > /dev/null \ || { fail=1; echo 1>&2 "$(ME): $$p uses proper_name_utf8"; }; \ done; \ test $$fail = 1 && \ { echo 1>&2 '$(ME): the above do not link with any ICONV library'; \ exit 1; } || :; \ fi
sc_redundant_const: @prohibit='\bconst\b[[:space:][:alnum:]]{2,}\bconst\b' \ halt='redundant "const" in declarations' \ $(_sc_search_regexp)
sc_const_long_option: @prohibit='^ static.struct option ' \ exclude='const struct option|struct option const' \ halt='$(ME): add "const" to the above declarations' \ $(_sc_search_regexp)
NEWS_hash = \ $$(sed -n '/^*. $(PREV_VERSION_REGEXP) ([0-9-])/,$$p' \ $(srcdir)/NEWS \ | perl -0777 -pe \ 's/^Copyright.+?Free\sSoftware\sFoundation,\sInc.\n//ms' \ | md5sum - \ | sed 's/ .*//')
sc_immutable_NEWS: @if test -f $(srcdir)/NEWS; then \ test "$(NEWS_hash)" = '$(old_NEWS_hash)' && : || \ { echo '$(ME): you have modified old NEWS' 1>&2; exit 1; }; \ fi
update-NEWS-hash: NEWS perl -pi -e 's/^(old_NEWS_hash[ \t]+:?=[ \t]+).*/$${1}'"$(NEWS_hash)/" \ $(srcdir)/cfg.mk
makefile_at_at_check_exceptions ?= sc_makefile_at_at_check: @perl -ne '/\@\w+\@/' \ -e ' && !/(\w+)\s+=.*\@\1\@$$/' \ -e ''$(_makefile_at_at_check_exceptions) \ -e 'and (print "$$ARGV:$$.: $$"), $$m=1; END {exit !$$m}' \ $$($(VC_LIST_EXCEPT) | grep -E '(^|/)(Makefile.am|[^/]+.mk)$$') \ && { echo '$(ME): use $$(...), not @...@' 1>&2; exit 1; } || :
news-check: NEWS if sed -n $(news-check-lines-spec)p $(srcdir)/NEWS \ | grep -E $(news-check-regexp) >/dev/null; then \ :; \ else \ echo 'NEWS: $$(news-check-regexp) failed to match' 1>&2; \ exit 1; \ fi
sc_makefile_TAB_only_indentation: @prohibit='^ [ ]{8}' \ in_vc_files='akefile|.mk$$' \ halt='found TAB-8-space indentation' \ $(_sc_search_regexp)
sc_m4_quote_check: @prohibit='(AC_DEFINE(_UNQUOTED)?|AC_DEFUN)([^[]' \ in_vc_files='(^configure.ac|.m4)$$' \ halt='quote the first arg to AC_DEF*' \ $(_sc_search_regexp)
fix_po_file_diag = \ 'you have changed the set of files with translatable diagnostics;\n\ apply the above patch\n'
po_file ?= $(srcdir)/po/POTFILES.in
generated_files ?= $(srcdir)/lib/.[ch]
sc_po_check:
@if test -f $(po_file); then \
grep -E -v '^(#|$$)' $(po_file) \
| grep -v '^src/false.c$$' | sort > $@-1; \
files=; \
for file in $$($(VC_LIST_EXCEPT)) $(generated_files); do \
test -r $$file || continue; \
case $$file in \
.m4|.mk) continue ;; \
.?|.??) ;; \
) continue;; \
esac; \
case $$file in \
.[ch]) \
base=expr " $$file" : ' \(.*\)\..'
; \
{ test -f $$base.l || test -f $$base.y; } && continue;; \
esac; \
files="$$files $$file"; \
done; \
grep -E -l '\b(N?_|gettext )([^)"]*("|$$)' $$files \
| sed 's|^$(_dot_escaped_srcdir)/||' | sort -u > $@-2; \
diff -u -L $(po_file) -L $(po_file) $@-1 $@-2 \
|| { printf '$(ME): '$(fix_po_file_diag) 1>&2; exit 1; }; \
rm -f $@-1 $@-2; \
fi
msg = '$(ME): Do not use ":" above; use $$(PATH_SEPARATOR) instead' sc_makefile_path_separator_check: @prohibit='PATH[=].*:' \ in_vc_files='akefile|.mk$$' \ halt=$(msg) \ $(_sc_search_regexp)
writable-files: if test -d $(release_archive_dir); then \ for file in $(DIST_ARCHIVES); do \ for p in ./ $(release_archive_dir)/; do \ test -e $$p$$file || continue; \ test -w $$p$$file \ || { echo ERROR: $$p$$file is not writable; fail=1; }; \ done; \ done; \ test "$$fail" && exit 1 || : ; \ else :; \ fi
v_etc_file = $(gnulib_dir)/lib/version-etc.c sample-test = tests/sample-test texi = doc/$(PACKAGE).texi
sc_copyright_check: @require='enum { COPYRIGHT_YEAR = '$$(date +%Y)' };' \ in_files=$(v_etc_file) \ halt='out of date copyright in $(v_etc_file); update it' \ $(_sc_search_regexp) @require='# Copyright (C) '$$(date +%Y)' Free' \ in_vc_files=$(sample-test) \ halt='out of date copyright in $(sample-test); update it' \ $(_sc_search_regexp) @require='Copyright @copyright{} .*'$$(date +%Y)' Free' \ in_vc_files=$(texi) \ halt='out of date copyright in $(texi); update it' \ $(_sc_search_regexp)
_hv_file ?= $(srcdir)/tests/help-version _hv_regex_weak ?= ^ . ./init.sh"
hv_regex_strong ?= ^ *. "\$${srcdir=.}/init.sh" sc_cross_check_PATH_usage_in_tests: @if test -f $(_hv_file); then \ grep -l 'VERSION mismatch' $(_hv_file) >/dev/null \ || { echo "$@: skipped: no such file: $(_hv_file)" 1>&2; \ exit 0; }; \ grep -lE '$(_hv_regex_strong)' $(_hv_file) >/dev/null \ || { echo "$@: $(_hv_file) lacks conforming use of init.sh" 1>&2; \ exit 1; }; \ good=$$(grep -E '$(_hv_regex_strong)' $(_hv_file)); \ grep -LFx "$$good" \ $$(grep -lE '$(_hv_regex_weak)' $$($(VC_LIST_EXCEPT))) \ | grep . && \ { echo "$(ME): the above files use path_prepend inconsistently" \ 1>&2; exit 1; } || :; \ fi
_test_script_regex ?= \<init.sh>
sc_prohibit_reversed_compare_failure: @prohibit='\<compare [^ ]+ ([^ ]*exp|/dev/null)' \ containing='$(_test_script_regex)' \ halt='reversed compare arguments' \ $(_sc_search_regexp)
sc_Wundef_boolean: @prohibit='^#define.*(yes|no|true|false)$$' \ in_files='$(CONFIG_INCLUDE)' \ halt='Use 0 or 1 for macro values' \ $(_sc_search_regexp)
sc_prohibit_path_max_allocation: @prohibit='(\balloca ([^)]|[[^]]*)PATH_MAX' \ halt='Avoid stack allocations of size PATH_MAX' \ $(_sc_search_regexp)
sc_vulnerable_makefile_CVE-2009-4029: @prohibit='perm -777 -exec chmod a+rwx|chmod 777 \$$(distdir)' \ in_files=$$(find $(srcdir) -name Makefile.in) \ halt=$$(printf '%s\n' \ 'the above files are vulnerable; beware of running' \ ' "make dist*" rules, and upgrade to fixed automake' \ ' see http://bugzilla.redhat.com/542609 for details') \ $(_sc_search_regexp)
vc-diff-check: (unset CDPATH; cd $(srcdir) && $(VC) diff) > vc-diffs || : if test -s vc-diffs; then \ cat vc-diffs; \ echo "Some files are locally modified:" 1>&2; \ exit 1; \ else \ rm vc-diffs; \ fi
rel-files = $(DIST_ARCHIVES)
gnulib_dir ?= $(srcdir)/gnulib gnulib-version = $$(cd $(gnulib_dir) && git describe) bootstrap-tools ?= autoconf,automake,gnulib
gpg_key_ID ?= \ $$(git cat-file tag v$(VERSION) \ | gpgv --status-fd 1 --keyring /dev/null - - 2>/dev/null \ | sed -n '/^[GNUPG:] ERRSIG /{s///;s/ .*//p;q}')
translation_project_ ?= coordinator@translationproject.org
ifeq ($(RELEASE_TYPE),stable) announcement_Cc_ ?= $(translation_project_), $(PACKAGE_BUGREPORT) announcement_mail_headers_ ?= \ To: info-gnu@gnu.org \ Cc: $(announcement_Cc_) \ Mail-Followup-To: $(PACKAGE_BUGREPORT) else announcement_Cc_ ?= $(translation_project_) announcement_mail_headers_ ?= \ To: $(PACKAGE_BUGREPORT) \ Cc: $(announcement_Cc_) endif
announcement: NEWS ChangeLog $(rel-files) @$(srcdir)/$(build-aux)/announce-gen \ --mail-headers='$(announcement_mail_headers)' \ --release-type=$(RELEASE_TYPE) \ --package=$(PACKAGE) \ --prev=$(PREV_VERSION) \ --curr=$(VERSION) \ --gpg-key-id=$(gpg_key_ID) \ --news=$(srcdir)/NEWS \ --bootstrap-tools=$(bootstrap-tools) \ $$(case ,$(bootstrap-tools), in (,gnulib,) \ echo --gnulib-version=$(gnulib-version);; esac) \ --no-print-checksums \ $(addprefix --url-dir=, $(url_dir_list))
ftp-gnu = ftp://ftp.gnu.org/gnu www-gnu = http://www.gnu.org
upload_dest_dir_ ?= $(PACKAGE) emit_upload_commands: @echo ===================================== @echo ===================================== @echo "$(srcdir)/$(build-aux)/gnupload $(GNUPLOADFLAGS) \" @echo " --to $(gnu_rel_host):$(upload_dest_dir) \" @echo " $(rel-files)" @echo '# send the ~/announce-$(my_distdir) e-mail' @echo ===================================== @echo =====================================
define emit-commit-log printf '%s\n' 'maint: post-release administrivia' '' \ ' NEWS: Add header line for next release.' \ ' .prev-version: Record previous version.' \ '* cfg.mk (old_NEWS_hash): Auto-update.' endef
.PHONY: no-submodule-changes no-submodule-changes: if test -d $(srcdir)/.git; then \ diff=$$(cd $(srcdir) && git submodule -q foreach \ git diff-index --name-only HEAD) \ || exit 1; \ case $$diff in '') ;; \ *) echo '$(ME): submodule files are locally modified:'; \ echo "$$diff"; exit 1;; esac; \ else \ : ; \ fi
submodule-checks ?= no-submodule-changes public-submodule-commit
.PHONY: public-submodule-commit public-submodule-commit: $(AM_V_GEN)if test -d $(srcdir)/.git; then \ cd $(srcdir) && \ git submodule --quiet foreach test '$$(git rev-parse $$sha1)' \ = '$$(git merge-base origin $$sha1)' \ || { echo '$(ME): found non-public submodule commit' >&2; \ exit 1; }; \ else \ : ; \ fi
gl_public_submodule_commit ?= public-submodule-commit check: $(gl_public_submodule_commit)
.PHONY: alpha beta stable ALL_RECURSIVE_TARGETS += alpha beta stable alpha beta stable: $(local-check) writable-files $(submodule-checks) test $@ = stable \ && { echo $(VERSION) | grep -E '^[0-9]+(.[0-9]+)+$$' \ || { echo "invalid version string: $(VERSION)" 1>&2; exit 1;};}\ || : $(MAKE) vc-diff-check $(MAKE) news-check $(MAKE) distcheck $(MAKE) dist $(MAKE) $(release-prep-hook) RELEASE_TYPE=$@ $(MAKE) -s emit_upload_commands RELEASE_TYPE=$@
release-prep-hook ?= release-prep
gl_noteworthy_news_ = * Noteworthy changes in release ?.? (????-??-??) [?] .PHONY: release-prep release-prep: case $$RELEASE_TYPE in alpha|beta|stable) ;; \ *) echo "invalid RELEASE_TYPE: $$RELEASE_TYPE" 1>&2; exit 1;; esac $(MAKE) --no-print-directory -s announcement > ~/announce-$(my_distdir) if test -d $(release_archive_dir); then \ ln $(rel-files) $(release_archive_dir); \ chmod a-w $(rel-files); \ fi echo $(VERSION) > $(prev_version_file) $(MAKE) update-NEWS-hash perl -pi -e '$$. == 3 and print "$(gl_noteworthy_news_)\n\n\n"' NEWS $(emit-commit-log) > .ci-msg $(VC) commit -F .ci-msg -a rm .ci-msg
gendocs_options_ ?=
.PHONY: web-manual web-manual: @test -z "$(manual_title)" \ && { echo define manual_title in cfg.mk 1>&2; exit 1; } || : @cd '$(srcdir)/doc'; \ $(SHELL) ../$(build-aux)/gendocs.sh $(gendocs_options) \ -o '$(abs_builddir)/doc/manual' \ --email $(PACKAGE_BUGREPORT) $(PACKAGE) \ "$(PACKAGE_NAME) - $(manual_title)" @echo " *** Upload the doc/manual directory to web-cvs."
init-coverage: $(MAKE) $(AM_MAKEFLAGS) clean lcov --directory . --zerocounters
COVERAGE_CCOPTS ?= "-g --coverage" COVERAGE_OUT ?= doc/coverage
build-coverage: $(MAKE) $(AM_MAKEFLAGS) CFLAGS=$(COVERAGE_CCOPTS) CXXFLAGS=$(COVERAGE_CCOPTS) $(MAKE) $(AM_MAKEFLAGS) CFLAGS=$(COVERAGE_CCOPTS) CXXFLAGS=$(COVERAGE_CCOPTS) check mkdir -p $(COVERAGE_OUT) lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \ --capture
gen-coverage: genhtml --output-directory $(COVERAGE_OUT) \ $(COVERAGE_OUT)/$(PACKAGE).info \ --highlight --frames --legend \ --title "$(PACKAGE_NAME)"
coverage: init-coverage build-coverage gen-coverage
PACKAGE ?= $(shell basename $(PWD)) PO_DOMAIN ?= $(PACKAGE) POURL = http://translationproject.org/latest/$(PO_DOMAIN)/ PODIR ?= po refresh-po: rm -f $(PODIR)/.po && \ echo "$(ME): getting translations into po (please ignore the robots.txt ERROR 404)..." && \ wget --no-verbose --directory-prefix $(PODIR) --no-directories --recursive --level 1 --accept .po --accept .po.1 $(POURL) && \ echo 'en@boldquot' > $(PODIR)/LINGUAS && \ echo 'en@quot' >> $(PODIR)/LINGUAS && \ ls $(PODIR)/.po | sed 's/.po//' | sed 's,$(PODIR)/,,' | sort >> $(PODIR)/LINGUAS
# Running indent once is not idempotent, but running it twice is. INDENT_SOURCES ?= $(C_SOURCES) .PHONY: indent indent: indent $(INDENT_SOURCES) indent $(INDENT_SOURCES)
update-copyright-env ?=
.PHONY: update-copyright update-copyright: grep -l -w Copyright \ $$(export VC_LIST_EXCEPT_DEFAULT=COPYING && $(VC_LIST_EXCEPT)) \ | $(update-copyright-env) xargs $(srcdir)/$(_build-aux)/$@
_gl_TS_dir ?= src
ALL_RECURSIVE_TARGETS += sc_tight_scope sc_tight_scope: tight-scope.mk @fail=0; \ if ! grep '^ export _gl_TS_headers =' $(srcdir)/cfg.mk \ > /dev/null \ && ! grep -w noinst_HEADERS $(srcdir)/$(_gl_TS_dir)/Makefile.am \ > /dev/null 2>&1; then \ echo '$(ME): skipping $@'; \ else \ $(MAKE) -s -C $(_gl_TS_dir) \ -f Makefile \ -f $(abs_top_srcdir)/cfg.mk \ -f $(abs_top_builddir)/$< \ _gl_tight_scope \ || fail=1; \ fi; \ rm -f $<; \ exit $$fail
tight-scope.mk: $(ME) @rm -f $@ $@-t @perl -ne '/^# TS-start/.../^# TS-end/ and print' $(srcdir)/$(ME) > $@-t @chmod a=r $@-t && mv $@-t $@
ifeq (a,b)
_gl_TS_unmarked_extern_functions ?= main usage _gl_TS_function_match ?= /^(?:$(_gl_TS_extern)) +.?(\S+) (/
_gl_TS_extern ?= extern
_gl_TS_unmarked_extern_vars ?=
_gl_TS_var_match ?= /^(?:$(_gl_TS_extern)) .?(\w+)([.?])?;/
_gl_TS_obj_files ?= *.$(OBJEXT)
_gl_TS_headers ?= $(noinst_HEADERS)
.PHONY: _gl_tight_scope
_gl_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 $(_gl_TS_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_match) and print "^$$1\$$"' $$hdr; \
) | sort -u > $$t; \
nm -e $(_gl_TS_obj_files) | 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_match) and print "^$$1\$$"' $$hdr .h \
) | sort -u > $$t; \
nm -e $(_gl_TS_obj_files) | sed -n 's/.* [BCDGRS] //p' \
| sort -u | grep -Ev -f $$t \
&& { echo the above variables should have static scope >&2; \
exit 1; } || :
endif