ptx: avoid heap overrun for backslash at end of optarg string
[platform/upstream/coreutils.git] / maint.mk
1 # -*-Makefile-*-
2 # This Makefile fragment is shared between the coreutils,
3 # CPPI, Bison, and Autoconf.
4
5 ## Copyright (C) 2001-2008 Free Software Foundation, Inc.
6 ##
7 ## This program is free software: you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation, either version 3 of the License, or
10 ## (at your option) any later version.
11 ##
12 ## This program is distributed in the hope that it will be useful,
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ## GNU General Public License for more details.
16 ##
17 ## You should have received a copy of the GNU General Public License
18 ## along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 # This is reported not to work with make-3.79.1
21 # ME := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
22 ME := maint.mk
23
24 # Do not save the original name or timestamp in the .tar.gz file.
25 # Use --rsyncable if available.
26 gzip_rsyncable := \
27   $(shell gzip --help 2>/dev/null|grep rsyncable >/dev/null && echo --rsyncable)
28 GZIP_ENV = '--no-name --best $(gzip_rsyncable)'
29
30 GIT = git
31 VC = $(GIT)
32 VC-tag = git tag -s -m '$(VERSION)'
33
34 VC_LIST = build-aux/vc-list-files
35
36 VC_LIST_EXCEPT = \
37   $(VC_LIST) | if test -f .x-$@; then grep -vEf .x-$@; else grep -v ChangeLog; fi
38
39 ifeq ($(origin prev_version_file), undefined)
40   prev_version_file = $(srcdir)/.prev-version
41 endif
42
43 PREV_VERSION := $(shell cat $(prev_version_file))
44 VERSION_REGEXP = $(subst .,\.,$(VERSION))
45
46 ifeq ($(VC),$(GIT))
47 this-vc-tag = v$(VERSION)
48 this-vc-tag-regexp = v$(VERSION_REGEXP)
49 else
50 tag-package = $(shell echo "$(PACKAGE)" | tr '[:lower:]' '[:upper:]')
51 tag-this-version = $(subst .,_,$(VERSION))
52 this-vc-tag = $(tag-package)-$(tag-this-version)
53 this-vc-tag-regexp = $(this-vc-tag)
54 endif
55 my_distdir = $(PACKAGE)-$(VERSION)
56
57 # Old releases are stored here.
58 release_archive_dir ?= ../release
59
60 # Prevent programs like 'sort' from considering distinct strings to be equal.
61 # Doing it here saves us from having to set LC_ALL elsewhere in this file.
62 export LC_ALL = C
63
64
65
66 ## --------------- ##
67 ## Sanity checks.  ##
68 ## --------------- ##
69
70 # Collect the names of rules starting with `sc_'.
71 syntax-check-rules := $(shell sed -n 's/^\(sc_[a-zA-Z0-9_-]*\):.*/\1/p' \
72                         $(srcdir)/$(ME))
73 .PHONY: $(syntax-check-rules)
74
75 local-checks-available = \
76   po-check copyright-check m4-check author_mark_check \
77   patch-check strftime-check $(syntax-check-rules) \
78   makefile_path_separator_check \
79   makefile-check check-AUTHORS
80 .PHONY: $(local-checks-available)
81
82 local-check := $(filter-out $(local-checks-to-skip), $(local-checks-available))
83
84 syntax-check: $(local-check)
85 #       @grep -nE '#  *include <(limits|std(def|arg|bool))\.h>'         \
86 #           $$(find -type f -name '*.[chly]') &&                        \
87 #         { echo '$(ME): found conditional include' 1>&2;               \
88 #           exit 1; } || :
89
90 #       grep -nE '^#  *include <(string|stdlib)\.h>'                    \
91 #           $(srcdir)/{lib,src}/*.[chy] &&                              \
92 #         { echo '$(ME): FIXME' 1>&2;                                   \
93 #           exit 1; } || :
94 # FIXME: don't allow `#include .strings\.h' anywhere
95
96 sc_avoid_if_before_free:
97         @$(srcdir)/build-aux/useless-if-before-free                     \
98                 $(useless_free_options)                                 \
99             $$($(VC_LIST_EXCEPT)) &&                                    \
100           { echo '$(ME): found useless "if" before "free" above' 1>&2;  \
101             exit 1; } || :
102
103 sc_cast_of_argument_to_free:
104         @grep -nE '\<free \(\(' $$($(VC_LIST_EXCEPT)) &&                \
105           { echo '$(ME): don'\''t cast free argument' 1>&2;             \
106             exit 1; } || :
107
108 sc_cast_of_x_alloc_return_value:
109         @grep -nE '\*\) *x(m|c|re)alloc\>' $$($(VC_LIST_EXCEPT)) &&     \
110           { echo '$(ME): don'\''t cast x*alloc return value' 1>&2;      \
111             exit 1; } || :
112
113 sc_cast_of_alloca_return_value:
114         @grep -nE '\*\) *alloca\>' $$($(VC_LIST_EXCEPT)) &&             \
115           { echo '$(ME): don'\''t cast alloca return value' 1>&2;       \
116             exit 1; } || :
117
118 sc_space_tab:
119         @grep -n '[ ]   ' $$($(VC_LIST_EXCEPT)) &&                      \
120           { echo '$(ME): found SPACE-TAB sequence; remove the SPACE'    \
121                 1>&2; exit 1; } || :
122
123 # Don't use *scanf or the old ato* functions in `real' code.
124 # They provide no error checking mechanism.
125 # Instead, use strto* functions.
126 sc_prohibit_atoi_atof:
127         @grep -nE '\<([fs]?scanf|ato([filq]|ll))\>' $$($(VC_LIST_EXCEPT)) && \
128           { echo '$(ME): do not use *scan''f, ato''f, ato''i, ato''l, ato''ll, ato''q, or ss''canf'     \
129                 1>&2; exit 1; } || :
130
131 # Use STREQ rather than comparing strcmp == 0, or != 0.
132 sc_prohibit_strcmp:
133         @grep -nE '! *str''cmp \(|\<str''cmp \([^)]+\) *=='             \
134             $$($(VC_LIST_EXCEPT)) &&                                    \
135           { echo '$(ME): use STREQ in place of the above uses of str''cmp' \
136                 1>&2; exit 1; } || :
137
138 # Using EXIT_SUCCESS as the first argument to error is misleading,
139 # since when that parameter is 0, error does not exit.  Use `0' instead.
140 sc_error_exit_success:
141         @grep -nF 'error (EXIT_SUCCESS,'                                \
142             $$(find -type f -name '*.[chly]') &&                        \
143           { echo '$(ME): found error (EXIT_SUCCESS' 1>&2;               \
144             exit 1; } || :
145
146 sc_file_system:
147         @grep -ni 'file''system' $$($(VC_LIST_EXCEPT)) &&               \
148           { echo '$(ME): found use of "file''system";'                  \
149             'rewrite to use "file system"' 1>&2;                        \
150             exit 1; } || :
151
152 sc_no_have_config_h:
153         @grep -n '^# *if.*HAVE''_CONFIG_H' $$($(VC_LIST_EXCEPT)) &&     \
154           { echo '$(ME): found use of HAVE''_CONFIG_H; remove'          \
155                 1>&2; exit 1; } || :
156
157 # Nearly all .c files must include <config.h>.
158 sc_require_config_h:
159         @if $(VC_LIST_EXCEPT) | grep '\.c$$' > /dev/null; then          \
160           grep -L '^# *include <config\.h>'                             \
161                 $$($(VC_LIST_EXCEPT) | grep '\.c$$')                    \
162               | grep . &&                                               \
163           { echo '$(ME): the above files do not include <config.h>'     \
164                 1>&2; exit 1; } || :;                                   \
165         else :;                                                         \
166         fi
167
168 # To use this "command" macro, you must first define two shell variables:
169 # h: the header, enclosed in <> or ""
170 # re: a regular expression that matches IFF something provided by $h is used.
171 define _header_without_use
172   h_esc=`echo "$$h"|sed 's/\./\\./'`;                                   \
173   if $(VC_LIST_EXCEPT) | grep '\.c$$' > /dev/null; then                 \
174     files=$$(grep -l '^# *include '"$$h_esc"                            \
175              $$($(VC_LIST_EXCEPT) | grep '\.c$$')) &&                   \
176     grep -LE "$$re" $$files | grep . &&                                 \
177       { echo "$(ME): the above files include $$h but don't use it"      \
178         1>&2; exit 1; } || :;                                           \
179   else :;                                                               \
180   fi
181 endef
182
183 # Prohibit the inclusion of assert.h without an actual use of assert.
184 sc_prohibit_assert_without_use:
185         @h='<assert.h>' re='\<assert *\(' $(_header_without_use)
186
187 # Prohibit the inclusion of getopt.h without an actual use.
188 sc_prohibit_getopt_without_use:
189         @h='<getopt.h>' re='\<getopt(_long)? *\(' $(_header_without_use)
190
191 # Don't include quotearg.h unless you use one of its functions.
192 sc_prohibit_quotearg_without_use:
193         @h='"quotearg.h"' re='\<quotearg(_[^ ]+)? *\(' $(_header_without_use)
194
195 # Don't include quote.h unless you use one of its functions.
196 sc_prohibit_quote_without_use:
197         @h='"quote.h"' re='\<quote(_n)? *\(' $(_header_without_use)
198
199 # Don't include this header unless you use one of its functions.
200 sc_prohibit_long_options_without_use:
201         @h='"long-options.h"' re='\<parse_long_options *\(' \
202           $(_header_without_use)
203
204 # Don't include this header unless you use one of its functions.
205 sc_prohibit_inttostr_without_use:
206         @h='"inttostr.h"' re='\<(off|[iu]max|uint)tostr *\(' \
207           $(_header_without_use)
208
209 # Don't include this header unless you use one of its functions.
210 sc_prohibit_error_without_use:
211         @h='"error.h"' \
212         re='\<error(_at_line|_print_progname|_one_per_line|_message_count)? *\('\
213           $(_header_without_use)
214
215 sc_prohibit_safe_read_without_use:
216         @h='"safe-read.h"' re='(\<SAFE_READ_ERROR\>|\<safe_read *\()' \
217           $(_header_without_use)
218
219 sc_prohibit_argmatch_without_use:
220         @h='"argmatch.h"' \
221         re='(\<(ARRAY_CARDINALITY|X?ARGMATCH(|_TO_ARGUMENT|_VERIFY))\>|\<argmatch(_exit_fn|_(in)?valid) *\()' \
222           $(_header_without_use)
223
224 sc_prohibit_root_dev_ino_without_use:
225         @h='"root-dev-ino.h"' \
226         re='(\<ROOT_DEV_INO_(CHECK|WARN)\>|\<get_root_dev_ino *\()' \
227           $(_header_without_use)
228
229 sc_obsolete_symbols:
230         @grep -nE '\<(HAVE''_FCNTL_H|O''_NDELAY)\>'                     \
231              $$($(VC_LIST_EXCEPT)) &&                                   \
232           { echo '$(ME): do not use HAVE''_FCNTL_H or O''_NDELAY'       \
233                 1>&2; exit 1; } || :
234
235 # FIXME: warn about definitions of EXIT_FAILURE, EXIT_SUCCESS, STREQ
236
237 # Each nonempty line must start with a year number, or a TAB.
238 sc_changelog:
239         @grep -n '^[^12 ]' $$(find . -maxdepth 2 -name ChangeLog) &&    \
240           { echo '$(ME): found unexpected prefix in a ChangeLog' 1>&2;  \
241             exit 1; } || :
242
243 # Ensure that dd's definition of LONGEST_SYMBOL stays in sync
244 # with the strings from the two affected variables.
245 dd_c = $(srcdir)/src/dd.c
246 sc_dd_max_sym_length:
247 ifneq ($(wildcard $(dd_c)),)
248         @len=$$( (sed -n '/conversions\[\] =$$/,/^};/p' $(dd_c);\
249                  sed -n '/flags\[\] =$$/,/^};/p' $(dd_c) )      \
250                 |sed -n '/"/s/^[^"]*"\([^"]*\)".*/\1/p'         \
251               | wc --max-line-length);                          \
252         max=$$(sed -n '/^#define LONGEST_SYMBOL /s///p' $(dd_c) \
253               |tr -d '"' | wc --max-line-length);               \
254         if test "$$len" = "$$max"; then :; else                 \
255           echo 'dd.c: LONGEST_SYMBOL is not longest' 1>&2;      \
256           exit 1;                                               \
257         fi
258 endif
259
260 # Many m4 macros names once began with `jm_'.
261 # On 2004-04-13, they were all changed to start with gl_ instead.
262 # Make sure that none are inadvertently reintroduced.
263 sc_prohibit_jm_in_m4:
264         @grep -nE 'jm_[A-Z]'                                            \
265                 $$($(VC_LIST) m4 |grep '\.m4$$'; echo /dev/null) &&     \
266             { echo '$(ME): do not use jm_ in m4 macro names'            \
267               1>&2; exit 1; } || :
268
269 sc_root_tests:
270         @if test -d tests \
271               && grep check-root tests/Makefile.am>/dev/null 2>&1; then \
272         t1=sc-root.expected; t2=sc-root.actual;                         \
273         grep -nl '^require_root_$$'                                     \
274           $$($(VC_LIST) tests) |sed s,tests,., |sort > $$t1;            \
275         sed -n 's,      cd \([^ ]*\) .*MAKE..check TESTS=\(.*\),./\1/\2,p' \
276           $(srcdir)/tests/Makefile.am |sort > $$t2;                     \
277         diff -u $$t1 $$t2 || diff=1;                                    \
278         rm -f $$t1 $$t2;                                                \
279         test "$$diff"                                                   \
280           && { echo 'tests/Makefile.am: missing check-root action'>&2;  \
281                exit 1; } || :;                                          \
282         fi
283
284 headers_with_interesting_macro_defs = \
285   exit.h        \
286   fcntl_.h      \
287   fnmatch_.h    \
288   intprops.h    \
289   inttypes_.h   \
290   lchown.h      \
291   openat.h      \
292   stat-macros.h \
293   stdint_.h
294
295 # Create a list of regular expressions matching the names
296 # of macros that are guaranteed by parts of gnulib to be defined.
297 .re-defmac:
298         @(cd $(srcdir)/lib;                                             \
299           for f in $(headers_with_interesting_macro_defs); do           \
300             test -f $$f &&                                              \
301               sed -n '/^# *define \([^_ (][^ (]*\)[ (].*/s//\1/p' $$f;  \
302            done;                                                        \
303          ) | sort -u                                                    \
304            | grep -Ev 'ATTRIBUTE_NORETURN|SIZE_MAX'                     \
305            | sed 's/^/^# *define /'                                     \
306           > $@-t
307         @mv $@-t $@
308
309 # Don't define macros that we already get from gnulib header files.
310 sc_always_defined_macros: .re-defmac
311         @if test -f $(srcdir)/src/system.h; then                        \
312           trap 'rc=$$?; rm -f .re-defmac; exit $$rc' 0 1 2 3 15;        \
313           grep -f .re-defmac $$($(VC_LIST))                             \
314             && { echo '$(ME): define the above via some gnulib .h file' \
315                   1>&2;  exit 1; } || :;                                \
316         fi
317
318 # Create a list of regular expressions matching the names
319 # of files included from system.h.  Exclude a couple.
320 .re-list:
321         @sed -n '/^# *include /s///p' $(srcdir)/src/system.h \
322           | grep -Ev 'sys/(param|file)\.h' \
323           | sed 's/ .*//;;s/^["<]/^# *include [<"]/;s/\.h[">]$$/\\.h[">]/' \
324           > $@-t
325         @mv $@-t $@
326
327 # Files in src/ should not include directly any of
328 # the headers already included via system.h.
329 sc_system_h_headers: .re-list
330         @if test -f $(srcdir)/src/system.h; then                        \
331           trap 'rc=$$?; rm -f .re-list; exit $$rc' 0 1 2 3 15;          \
332           grep -nE -f .re-list                                          \
333               $$($(VC_LIST) src |                                       \
334                  grep -Ev '((copy|system)\.h|parse-gram\.c)$$')         \
335             && { echo '$(ME): the above are already included via system.h'\
336                   1>&2;  exit 1; } || :;                                \
337         fi
338
339 sc_sun_os_names:
340         @grep -nEi \
341             'solaris[^[:alnum:]]*2\.(7|8|9|[1-9][0-9])|sunos[^[:alnum:]][6-9]' \
342             $$($(VC_LIST_EXCEPT)) &&                                    \
343           { echo '$(ME): found misuse of Sun OS version numbers' 1>&2;  \
344             exit 1; } || :
345
346 sc_the_the:
347         @grep -ni '\<the ''the\>' $$($(VC_LIST_EXCEPT)) &&              \
348           { echo '$(ME): found use of "the ''the";' 1>&2;               \
349             exit 1; } || :
350
351 sc_tight_scope:
352         $(MAKE) -C src $@
353
354 sc_trailing_blank:
355         @grep -n '[      ]$$' $$($(VC_LIST_EXCEPT)) &&                  \
356           { echo '$(ME): found trailing blank(s)'                       \
357                 1>&2; exit 1; } || :
358
359 # Match lines like the following, but where there is only one space
360 # between the options and the description:
361 #   -D, --all-repeated[=delimit-method]  print all duplicate lines\n
362 longopt_re = --[a-z][0-9A-Za-z-]*(\[?=[0-9A-Za-z-]*\]?)?
363 sc_two_space_separator_in_usage:
364         @grep -nE '^   *(-[A-Za-z],)? $(longopt_re) [^ ].*\\$$'         \
365             $$($(VC_LIST_EXCEPT)) &&                                    \
366           { echo "$(ME): help2man requires at least two spaces between"; \
367             echo "$(ME): an option and its description"; \
368                 1>&2; exit 1; } || :
369
370 # Look for diagnostics that aren't marked for translation.
371 # This won't find any for which error's format string is on a separate line.
372 sc_unmarked_diagnostics:
373         @grep -nE                                                       \
374             '\<error \([^"]*"[^"]*[a-z]{3}' $$($(VC_LIST_EXCEPT))       \
375           | grep -v '_''(' &&                                           \
376           { echo '$(ME): found unmarked diagnostic(s)' 1>&2;            \
377             exit 1; } || :
378
379 # Avoid useless parentheses like those in this example:
380 # #if defined (SYMBOL) || defined (SYM2)
381 sc_useless_cpp_parens:
382         @grep -n '^# *if .*defined *(' $$($(VC_LIST_EXCEPT)) &&         \
383           { echo '$(ME): found useless parentheses in cpp directive'    \
384                 1>&2; exit 1; } || :
385
386 # Require the latest GPL.
387 sc_GPL_version:
388         @grep -n 'either ''version [^3]' $$($(VC_LIST_EXCEPT)) &&       \
389           { echo '$(ME): GPL vN, N!=3' 1>&2; exit 1; } || :
390
391 # Ensure that the c99-to-c89 patch applies cleanly.
392 patch-check:
393         rm -rf src-c89 $@.1 $@.2
394         cp -a src src-c89
395         (cd src-c89; patch -p1 -V never --fuzz=0) < src/c99-to-c89.diff \
396           > $@.1 2>&1
397         if test "$$REGEN_PATCH" = yes; then \
398           diff -upr src src-c89 | sed 's,src-c89/,src/,' \
399             | grep -v '^Only in' > new-diff || : ; fi
400         grep -v '^patching file ' $@.1 > $@.2 || :
401         msg=ok; test -s $@.2 && msg='fuzzy patch' || : ;        \
402         rm -f src-c89/*.o || msg='rm failed';                   \
403         $(MAKE) -C src-c89 CFLAGS='-Wdeclaration-after-statement -Werror' \
404           || msg='compile failure with extra options';          \
405         test "$$msg" = ok && rm -rf src-c89 $@.1 $@.2 || echo "$$msg" 1>&2; \
406         test "$$msg" = ok
407
408 # Ensure that date's --help output stays in sync with the info
409 # documentation for GNU strftime.  The only exception is %N,
410 # which date accepts but GNU strftime does not.
411 extract_char = sed 's/^[^%][^%]*%\(.\).*/\1/'
412 strftime-check:
413         if test -f $(srcdir)/src/date.c; then                           \
414           grep '^  %.  ' $(srcdir)/src/date.c | sort                    \
415             | $(extract_char) > $@-src;                                 \
416           { echo N;                                                     \
417             info libc date calendar format | grep '^    `%.'\'          \
418               | $(extract_char); } | sort > $@-info;                    \
419           diff -u $@-src $@-info || exit 1;                             \
420           rm -f $@-src $@-info;                                         \
421         fi
422
423 check-AUTHORS:
424         $(MAKE) -C src $@
425
426 # Ensure that we use only the standard $(VAR) notation,
427 # not @...@ in Makefile.am, now that we can rely on automake
428 # to emit a definition for each substituted variable.
429 makefile-check:
430         grep -nE '@[A-Z_0-9]+@' `find . -name Makefile.am` \
431           && { echo '$(ME): use $$(...), not @...@' 1>&2; exit 1; } || :
432
433 news-date-check: NEWS
434         today=`date +%Y-%m-%d`;                                         \
435         if head NEWS | grep '^\*.* $(VERSION_REGEXP) ('$$today')'       \
436             >/dev/null; then                                            \
437           :;                                                            \
438         else                                                            \
439           echo "version or today's date is not in NEWS" 1>&2;           \
440           exit 1;                                                       \
441         fi
442
443 changelog-check:
444         if head ChangeLog | grep 'Version $(VERSION_REGEXP)\.$$'        \
445             >/dev/null; then                                            \
446           :;                                                            \
447         else                                                            \
448           echo "$(VERSION) not in ChangeLog" 1>&2;                      \
449           exit 1;                                                       \
450         fi
451
452 m4-check:
453         @grep -n 'AC_DEFUN([^[]' m4/*.m4 \
454           && { echo '$(ME): quote the first arg to AC_DEFUN' 1>&2; \
455                exit 1; } || :
456
457 # Verify that all source files using _() are listed in po/POTFILES.in.
458 # FIXME: don't hard-code file names below; use a more general mechanism.
459 po-check:
460         if test -f po/POTFILES.in; then                                 \
461           grep -E -v '^(#|$$)' po/POTFILES.in                           \
462             | grep -v '^src/false\.c$$' | sort > $@-1;                  \
463           files=;                                                       \
464           for file in $$($(VC_LIST_EXCEPT)) lib/*.[ch]; do              \
465             case $$file in                                              \
466             djgpp/* | man/*) continue;;                                 \
467             */c99-to-c89.diff) continue;;                               \
468             esac;                                                       \
469             case $$file in                                              \
470             *.[ch])                                                     \
471               base=`expr " $$file" : ' \(.*\)\..'`;                     \
472               { test -f $$base.l || test -f $$base.y; } && continue;;   \
473             esac;                                                       \
474             files="$$files $$file";                                     \
475           done;                                                         \
476           grep -E -l '\b(N?_|gettext *)\([^)"]*("|$$)' $$files          \
477             | sort -u > $@-2;                                           \
478           diff -u $@-1 $@-2 || exit 1;                                  \
479           rm -f $@-1 $@-2;                                              \
480         fi
481
482 # In a definition of #define AUTHORS "... and ..." where the RHS contains
483 # the English word `and', the string must be marked with `N_ (...)' so that
484 # gettext recognizes it as a string requiring translation.
485 author_mark_check:
486         @grep -n '^# *define AUTHORS "[^"]* and ' src/*.c |grep -v ' N_ (' && \
487           { echo '$(ME): enclose the above strings in N_ (...)' 1>&2; \
488             exit 1; } || :
489
490 # Sometimes it is useful to change the PATH environment variable
491 # in Makefiles.  When doing so, it's better not to use the Unix-centric
492 # path separator of `:', but rather the automake-provided `@PATH_SEPARATOR@'.
493 # It'd be better to use `find -print0 ...|xargs -0 ...', but less portable,
494 # and there probably aren't many projects with so many Makefile.am files
495 # that we'd have to worry about limits on command line length.
496 msg = '$(ME): Do not use `:'\'' above; use @PATH_SEPARATOR@ instead'
497 makefile_path_separator_check:
498         @grep -n 'PATH=.*:' `find $(srcdir) -name Makefile.am` \
499           && { echo $(msg) 1>&2; exit 1; } || :
500
501 # Check that `make alpha' will not fail at the end of the process.
502 writable-files:
503         if test -d $(release_archive_dir); then :; else                 \
504           for file in $(distdir).tar.gz                                 \
505                       $(release_archive_dir)/$(distdir).tar.gz; do      \
506             test -e $$file || continue;                                 \
507             test -w $$file                                              \
508               || { echo ERROR: $$file is not writable; fail=1; };       \
509           done;                                                         \
510           test "$$fail" && exit 1 || :
511         fi
512
513 v_etc_file = lib/version-etc.c
514 sample-test = tests/sample-test
515 texi = doc/$(PACKAGE).texi
516 # Make sure that the copyright date in $(v_etc_file) is up to date.
517 # Do the same for the $(sample-test) and the main doc/.texi file.
518 copyright-check:
519         @if test -f $(v_etc_file); then \
520           grep 'enum { COPYRIGHT_YEAR = '$$(date +%Y)' };' $(v_etc_file) \
521             >/dev/null \
522           || { echo 'out of date copyright in $(v_etc_file); update it' 1>&2; \
523                exit 1; }; \
524         fi
525         @if test -f $(sample-test); then \
526           grep '# Copyright (C) '$$(date +%Y)' Free' $(sample-test) \
527             >/dev/null \
528           || { echo 'out of date copyright in $(sample-test); update it' 1>&2; \
529                exit 1; }; \
530         fi
531         @if test -f $(texi); then \
532           grep 'Copyright @copyright{} .*'$$(date +%Y)' Free' $(texi) \
533             >/dev/null \
534           || { echo 'out of date copyright in $(texi); update it' 1>&2; \
535                exit 1; }; \
536         fi
537
538 vc-diff-check:
539         $(VC) diff > vc-diffs || :
540         if test -s vc-diffs; then                               \
541           cat vc-diffs;                                         \
542           echo "Some files are locally modified:" 1>&2;         \
543           exit 1;                                               \
544         else                                                    \
545           rm vc-diffs;                                          \
546         fi
547
548 cvs-check: vc-diff-check
549
550 maintainer-distcheck:
551         $(MAKE) distcheck
552         $(MAKE) my-distcheck
553
554
555 # Don't make a distribution if checks fail.
556 # Also, make sure the NEWS file is up-to-date.
557 vc-dist: $(local-check) cvs-check maintainer-distcheck
558         $(MAKE) dist
559
560 # Use this to make sure we don't run these programs when building
561 # from a virgin tgz file, below.
562 null_AM_MAKEFLAGS = \
563   ACLOCAL=false \
564   AUTOCONF=false \
565   AUTOMAKE=false \
566   AUTOHEADER=false \
567   MAKEINFO=false
568
569 built_programs = $$(cd src && MAKEFLAGS= $(MAKE) -s built_programs.list)
570
571 warn_cflags = -Dlint -O -Werror -Wall -Wformat -Wshadow -Wpointer-arith
572 bin=bin-$$$$
573
574 write_loser = printf '\#!%s\necho $$0: bad path 1>&2; exit 1\n' '$(SHELL)'
575
576 # Use -Wformat -Werror to detect format-string/arg-list mismatches.
577 # Also, check for shadowing problems with -Wshadow, and for pointer
578 # arithmetic problems with -Wpointer-arith.
579 # These CFLAGS are pretty strict.  If you build this target, you probably
580 # have to have a recent version of gcc and glibc headers.
581 # The for-loop below ensures that there is a bin/ directory full of all
582 # of the programs under test (except the few that are required for basic
583 # Makefile rules), all symlinked to the just-built "false" program.
584 # This is to ensure that if ever a test neglects to make PATH include
585 # the build srcdir, these always-failing programs will run.
586 # Otherwise, it is too easy to test the wrong programs.
587 # Note that "false" itself is a symlink to true, so it too will malfunction.
588 TMPDIR ?= /tmp
589 t=$(TMPDIR)/$(PACKAGE)/test
590 my-distcheck: $(local-check) check
591         -rm -rf $(t)
592         mkdir -p $(t)
593         GZIP=$(GZIP_ENV) $(AMTAR) -C $(t) -zxf $(distdir).tar.gz
594         cd $(t)/$(distdir)                              \
595           && ./configure --disable-nls --prefix=$(t)/i  \
596           && $(MAKE) CFLAGS='$(warn_cflags)'            \
597               AM_MAKEFLAGS='$(null_AM_MAKEFLAGS)'       \
598           && $(MAKE) dvi                                \
599           && $(MAKE) install                            \
600           && test -f $(mandir)/man1/ls.1                \
601           && mkdir $(bin)                               \
602           && ($(write_loser)) > $(bin)/loser            \
603           && chmod a+x $(bin)/loser                     \
604           && for i in $(built_programs); do             \
605                case $$i in                              \
606                  rm|expr|basename|echo|sort|ls|tr);;    \
607                  cat|dirname|mv|wc);;                   \
608                  *) ln $(bin)/loser $(bin)/$$i;;        \
609                esac;                                    \
610              done                                       \
611           && ln -sf ../src/true $(bin)/false            \
612           && PATH=`pwd`/$(bin):$$PATH $(MAKE) -C tests check \
613           && $(MAKE) -C gnulib-tests check              \
614           && rm -rf $(bin)                              \
615           && $(MAKE) distclean
616         (cd $(t) && mv $(distdir) $(distdir).old        \
617           && $(AMTAR) -zxf - ) < $(distdir).tar.gz
618         diff -ur $(t)/$(distdir).old $(t)/$(distdir)
619         if test -f $(srcdir)/src/c99-to-c89.diff; then                  \
620           cd $(t)/$(distdir)                                            \
621             && (cd src && patch -V never --fuzz=0 <c99-to-c89.diff)     \
622             && ./configure --disable-largefile                          \
623                  CFLAGS='-Werror -ansi -Wno-long-long'                  \
624             && $(MAKE);                                                 \
625         fi
626         -rm -rf $(t)
627         @echo "========================"; \
628         echo "$(distdir).tar.gz is ready for distribution"; \
629         echo "========================"
630
631 WGET = wget
632 WGETFLAGS = -C off
633
634 rel-check:
635         tarz=/tmp/rel-check-tarz-$$$$; \
636         md5_tmp=/tmp/rel-check-md5-$$$$; \
637         set -e; \
638         trap 'status=$$?; rm -f $$tarz $$md5_tmp; exit $$status' 0 1 2 3 15; \
639         $(WGET) $(WGETFLAGS) -q --output-document=$$tarz $(url); \
640         echo "$(md5)  -" > $$md5_tmp; \
641         md5sum -c $$md5_tmp < $$tarz
642
643 rel-files = $(DIST_ARCHIVES)
644
645 gnulib-version = $$(cd $(gnulib_dir) && git describe)
646
647 announcement: NEWS ChangeLog $(rel-files)
648         @./build-aux/announce-gen                                       \
649             --release-type=$(RELEASE_TYPE)                              \
650             --package=$(PACKAGE)                                        \
651             --prev=$(PREV_VERSION)                                      \
652             --curr=$(VERSION)                                           \
653             --gpg-key-id=$(gpg_key_ID)                                  \
654             --news=NEWS                                                 \
655             --bootstrap-tools=autoconf,automake,bison,gnulib            \
656             --gnulib-version=$(gnulib-version)                          \
657             $(addprefix --url-dir=, $(url_dir_list))
658
659 ## ---------------- ##
660 ## Updating files.  ##
661 ## ---------------- ##
662
663 ftp-gnu = ftp://ftp.gnu.org/gnu
664 www-gnu = http://www.gnu.org
665
666 # Use mv, if you don't have/want move-if-change.
667 move_if_change ?= move-if-change
668
669 emit_upload_commands:
670         @echo =====================================
671         @echo =====================================
672         @echo "$(srcdir)/build-aux/gnupload $(GNUPLOADFLAGS) \\"
673         @echo "    --to $(gnu_rel_host):$(PACKAGE) \\"
674         @echo "  $(rel-files)"
675         @echo '# send the /tmp/announcement e-mail'
676         @echo =====================================
677         @echo =====================================
678
679 .PHONY: alpha beta major
680 alpha beta major: $(local-check) writable-files
681         test $@ = major                                         \
682           && { echo $(VERSION) | grep -E '^[0-9]+(\.[0-9]+)+$$' \
683                || { echo "invalid version string: $(VERSION)" 1>&2; exit 1;};}\
684           || :
685         $(MAKE) vc-dist
686         $(MAKE) news-date-check
687         $(MAKE) -s announcement RELEASE_TYPE=$@ > /tmp/announce-$(my_distdir)
688         if test -d $(release_archive_dir); then                 \
689           ln $(rel-files) $(release_archive_dir);               \
690           chmod a-w $(rel-files);                               \
691         fi
692         $(MAKE) -s emit_upload_commands RELEASE_TYPE=$@
693         echo $(VERSION) > $(prev_version_file)
694         $(VC) commit -m \
695           '$(prev_version_file): Record previous version: $(VERSION).' \
696           $(prev_version_file)