Makefile.maint 22.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
# This is reported not to work with make-3.79.1
# ME := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
ME := Makefile.maint

# Do not save the original name or timestamp in the .tar.gz file.
# Use --rsyncable if available.
gzip_rsyncable := \
  $(shell gzip --help 2>/dev/null|grep rsyncable >/dev/null && echo --rsyncable)
GZIP_ENV = '--no-name --best $(gzip_rsyncable)'

11
VC_LIST = $(top_srcdir)/build-aux/vc-list-files
12

13
VC_LIST_EXCEPT = \
14
  $(VC_LIST) -C $(top_srcdir) | if test -f .x-$@; then grep -vEf .x-$@; else grep -v ChangeLog; fi
15 16 17 18 19 20

# Prevent programs like 'sort' from considering distinct strings to be equal.
# Doing it here saves us from having to set LC_ALL elsewhere in this file.
export LC_ALL = C

# Collect the names of rules starting with `sc_'.
21 22
syntax-check-rules := $(shell sed -n 's/^\(sc_[a-zA-Z0-9_-]*\):.*/\1/p' \
                        $(srcdir)/$(ME))
23 24 25 26
.PHONY: $(syntax-check-rules)

local-checks-available = \
  po-check copyright-check m4-check author_mark_check \
27
  patch-check strftime-check $(syntax-check-rules) \
28 29 30 31 32 33 34
  makefile_path_separator_check \
  makefile-check check-AUTHORS
.PHONY: $(local-checks-available)

local-check := $(filter-out $(local-checks-to-skip), $(local-checks-available))

syntax-check: $(local-check)
35 36 37 38
#	@grep -nE '#  *include <(limits|std(def|arg|bool))\.h>'		\
#	    $$(find -type f -name '*.[chly]') &&			\
#	  { echo '$(ME): found conditional include' 1>&2;		\
#	    exit 1; } || :
39

40 41 42 43 44
#	grep -nE '^#  *include <(string|stdlib)\.h>'			\
#	    $(srcdir)/{lib,src}/*.[chy] &&				\
#	  { echo '$(ME): FIXME' 1>&2;					\
#	    exit 1; } || :
# FIXME: don't allow `#include .strings\.h' anywhere
45 46

sc_avoid_if_before_free:
47 48
	@$(srcdir)/build-aux/useless-if-before-free			\
		$(useless_free_options)					\
49
	    $$($(VC_LIST_EXCEPT)) &&					\
50 51 52
	  { echo '$(ME): found useless "if" before "free" above' 1>&2;	\
	    exit 1; } || :

53 54 55
# Avoid uses of write(2).  Either switch to streams (fwrite), or use
# the safewrite wrapper.
sc_avoid_write:
56 57
	@if $(VC_LIST_EXCEPT) | grep '\.c$$' > /dev/null; then		\
	  grep '\<write *(' $$($(VC_LIST_EXCEPT) | grep '\.c$$') &&	\
58 59 60 61 62 63
	    { echo "$(ME): the above files use write;"			\
	      " consider using the safewrite wrapper instead"		\
		  1>&2; exit 1; } || :;					\
	else :;								\
	fi

64
sc_cast_of_argument_to_free:
65
	@grep -nE '\<free \(\(' $$($(VC_LIST_EXCEPT)) &&		\
66 67 68 69
	  { echo '$(ME): don'\''t cast free argument' 1>&2;		\
	    exit 1; } || :

sc_cast_of_x_alloc_return_value:
70
	@grep -nE '\*\) *x(m|c|re)alloc\>' $$($(VC_LIST_EXCEPT)) &&	\
71 72 73 74
	  { echo '$(ME): don'\''t cast x*alloc return value' 1>&2;	\
	    exit 1; } || :

sc_cast_of_alloca_return_value:
75
	@grep -nE '\*\) *alloca\>' $$($(VC_LIST_EXCEPT)) &&		\
76 77 78 79
	  { echo '$(ME): don'\''t cast alloca return value' 1>&2;	\
	    exit 1; } || :

sc_space_tab:
80
	@grep -n '[ ]	' $$($(VC_LIST_EXCEPT)) &&			\
81 82 83
	  { echo '$(ME): found SPACE-TAB sequence; remove the SPACE'	\
		1>&2; exit 1; } || :

84 85 86 87 88 89 90 91
cvs_keywords = \
  Author|Date|Header|Id|Name|Locker|Log|RCSfile|Revision|Source|State

sc_prohibit_cvs_keyword:
	@grep -nE '\$$($(cvs_keywords))\$$' $$($(VC_LIST_EXCEPT)) &&	\
	  { echo '$(ME): do not use CVS keyword expansion '		\
		1>&2; exit 1; } || :

92 93 94 95
# Don't use *scanf or the old ato* functions in `real' code.
# They provide no error checking mechanism.
# Instead, use strto* functions.
sc_prohibit_atoi_atof:
96
	@grep -nE '\<([fs]?scanf|ato([filq]|ll))\>' $$($(VC_LIST_EXCEPT)) && \
97 98 99 100
	  { echo '$(ME): do not use *scan''f, ato''f, ato''i, ato''l, ato''ll, ato''q, or ss''canf'	\
		1>&2; exit 1; } || :

# Use STREQ rather than comparing strcmp == 0, or != 0.
101
# Similarly, use STREQLEN or STRPREFIX rather than strncmp.
102
sc_prohibit_strcmp:
103
	@grep -nE '! *str''n?cmp *\(|\<str''n?cmp *\([^)]+\) *=='	\
104
	    $$($(VC_LIST_EXCEPT)) &&					\
105 106 107 108 109 110 111 112 113 114 115 116
	  { echo '$(ME): use STREQ in place of the above uses of str''cmp' \
		1>&2; exit 1; } || :

# Using EXIT_SUCCESS as the first argument to error is misleading,
# since when that parameter is 0, error does not exit.  Use `0' instead.
sc_error_exit_success:
	@grep -nF 'error (EXIT_SUCCESS,'				\
	    $$(find -type f -name '*.[chly]') &&			\
	  { echo '$(ME): found error (EXIT_SUCCESS' 1>&2;		\
	    exit 1; } || :

sc_file_system:
117
	@grep -ni 'file''system' $$($(VC_LIST_EXCEPT)) &&		\
118 119 120 121 122
	  { echo '$(ME): found use of "file''system";'			\
	    'rewrite to use "file system"' 1>&2;			\
	    exit 1; } || :

sc_no_have_config_h:
123
	@grep -n '^# *if.*HAVE''_CONFIG_H' $$($(VC_LIST_EXCEPT)) &&	\
124 125 126 127 128
	  { echo '$(ME): found use of HAVE''_CONFIG_H; remove'		\
		1>&2; exit 1; } || :

# Nearly all .c files must include <config.h>.
sc_require_config_h:
129
	@if $(VC_LIST_EXCEPT) | grep '\.c$$' > /dev/null; then		\
130
	  grep -L '^# *include <config\.h>'				\
131
		$$($(VC_LIST_EXCEPT) | grep '\.c$$')			\
132 133 134 135 136 137
	      | grep . &&						\
	  { echo '$(ME): the above files do not include <config.h>'	\
		1>&2; exit 1; } || :;					\
	else :;								\
	fi

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
# To use this "command" macro, you must first define two shell variables:
# h: the header, enclosed in <> or ""
# re: a regular expression that matches IFF something provided by $h is used.
define _header_without_use
  h_esc=`echo "$$h"|sed 's/\./\\./'`;					\
  if $(VC_LIST_EXCEPT) | grep '\.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

153 154
# Prohibit the inclusion of assert.h without an actual use of assert.
sc_prohibit_assert_without_use:
155 156 157 158 159
	@h='<assert.h>' re='\<assert *\(' $(_header_without_use)

# Prohibit the inclusion of getopt.h without an actual use.
sc_prohibit_getopt_without_use:
	@h='<getopt.h>' re='\<getopt(_long)? *\(' $(_header_without_use)
160 161 162

# Don't include quotearg.h unless you use one of its functions.
sc_prohibit_quotearg_without_use:
163
	@h='"quotearg.h"' re='\<quotearg(_[^ ]+)? *\(' $(_header_without_use)
164 165 166

# Don't include quote.h unless you use one of its functions.
sc_prohibit_quote_without_use:
167
	@h='"quote.h"' re='\<quote(_n)? *\(' $(_header_without_use)
168

169 170 171 172 173 174 175 176 177 178
# Prohibit the inclusion of c-ctype.h without an actual use.
sc_prohibit_c_ctype_without_use:
	@h='[<"]c-ctype.h[">]' re='\<c_($(ctype_re)) *\(' $(_header_without_use)

# Prohibit the inclusion of <ctype.h>.
sc_prohibit_ctype_h:
	@grep -E '^# *include  *<ctype\.h>' $$($(VC_LIST_EXCEPT)) &&	\
	  { echo "$(ME): don't use ctype.h; instead, use c-ctype.h"	\
		1>&2; exit 1; } || :

179 180
sc_obsolete_symbols:
	@grep -nE '\<(HAVE''_FCNTL_H|O''_NDELAY)\>'			\
181
	     $$($(VC_LIST_EXCEPT)) &&					\
182 183 184 185 186 187
	  { echo '$(ME): do not use HAVE''_FCNTL_H or O''_NDELAY'	\
		1>&2; exit 1; } || :

# FIXME: warn about definitions of EXIT_FAILURE, EXIT_SUCCESS, STREQ

# Each nonempty line must start with a year number, or a TAB.
188 189 190
# Or day-of-week+space.
changelog_entry_header_regexp = \
  ([12][0-9][0-9][0-9]|	.|(Mon|Tue|Wed|Thu|Fri|Sat|Sun) )
191
sc_changelog:
192 193
	@grep -Evn '(^$$|^$(changelog_entry_header_regexp))'		\
	  $$(find . -maxdepth 2 -name ChangeLog) &&			\
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
	  { echo '$(ME): found unexpected prefix in a ChangeLog' 1>&2;	\
	    exit 1; } || :

# Ensure that dd's definition of LONGEST_SYMBOL stays in sync
# with the strings from the two affected variables.
dd_c = $(srcdir)/src/dd.c
sc_dd_max_sym_length:
ifneq ($(wildcard $(dd_c)),)
	@len=$$( (sed -n '/conversions\[\] =$$/,/^};/p' $(dd_c);\
		 sed -n '/flags\[\] =$$/,/^};/p' $(dd_c) )	\
		|sed -n '/"/s/^[^"]*"\([^"]*\)".*/\1/p'		\
	      | wc --max-line-length);				\
	max=$$(sed -n '/^#define LONGEST_SYMBOL /s///p' $(dd_c)	\
	      |tr -d '"' | wc --max-line-length);		\
	if test "$$len" = "$$max"; then :; else			\
	  echo 'dd.c: LONGEST_SYMBOL is not longest' 1>&2;	\
	  exit 1;						\
	fi
endif

# Many m4 macros names once began with `jm_'.
# On 2004-04-13, they were all changed to start with gl_ instead.
# Make sure that none are inadvertently reintroduced.
sc_prohibit_jm_in_m4:
	@grep -nE 'jm_[A-Z]'					\
219
		$$($(VC_LIST) m4 |grep '\.m4$$'; echo /dev/null) && \
220 221 222 223 224 225 226
	    { echo '$(ME): do not use jm_ in m4 macro names'	\
	      1>&2; exit 1; } || :

sc_root_tests:
	@if test -d tests \
	      && grep check-root tests/Makefile.am>/dev/null 2>&1; then \
	t1=sc-root.expected; t2=sc-root.actual;				\
227 228
	grep -nl '^require_root_$$'					\
	  $$($(VC_LIST) tests) |sed s,tests,., |sort > $$t1;		\
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
	sed -n 's,	cd \([^ ]*\) .*MAKE..check TESTS=\(.*\),./\1/\2,p' \
	  $(srcdir)/tests/Makefile.am |sort > $$t2;			\
	diff -u $$t1 $$t2 || diff=1;					\
	rm -f $$t1 $$t2;						\
	test "$$diff"							\
	  && { echo 'tests/Makefile.am: missing check-root action'>&2;	\
	       exit 1; } || :;						\
	fi

headers_with_interesting_macro_defs = \
  exit.h	\
  fcntl_.h	\
  fnmatch_.h	\
  intprops.h	\
  inttypes_.h	\
  lchown.h	\
  openat.h	\
  stat-macros.h	\
  stdint_.h

# Create a list of regular expressions matching the names
# of macros that are guaranteed by parts of gnulib to be defined.
.re-defmac:
	@(cd $(srcdir)/lib;						\
	  for f in $(headers_with_interesting_macro_defs); do		\
	    test -f $$f &&						\
	      sed -n '/^# *define \([^_ (][^ (]*\)[ (].*/s//\1/p' $$f;	\
	   done;							\
	 ) | sort -u							\
	   | grep -Ev 'ATTRIBUTE_NORETURN|SIZE_MAX'			\
	   | sed 's/^/^# *define /'					\
	  > $@-t
	@mv $@-t $@

# Don't define macros that we already get from gnulib header files.
sc_always_defined_macros: .re-defmac
	@if test -f $(srcdir)/src/system.h; then			\
	  trap 'rc=$$?; rm -f .re-defmac; exit $$rc' 0 1 2 3 15;	\
267
	  grep -f .re-defmac $$($(VC_LIST))				\
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
	    && { echo '$(ME): define the above via some gnulib .h file'	\
		  1>&2;  exit 1; } || :;				\
	fi

# Create a list of regular expressions matching the names
# of files included from system.h.  Exclude a couple.
.re-list:
	@sed -n '/^# *include /s///p' $(srcdir)/src/system.h \
	  | grep -Ev 'sys/(param|file)\.h' \
	  | sed 's/ .*//;;s/^["<]/^# *include [<"]/;s/\.h[">]$$/\\.h[">]/' \
	  > $@-t
	@mv $@-t $@

# Files in src/ should not include directly any of
# the headers already included via system.h.
sc_system_h_headers: .re-list
	@if test -f $(srcdir)/src/system.h; then			\
	  trap 'rc=$$?; rm -f .re-list; exit $$rc' 0 1 2 3 15;		\
	  grep -nE -f .re-list						\
287
	      $$($(VC_LIST) src |					\
288 289 290 291 292 293 294 295
		 grep -Ev '((copy|system)\.h|parse-gram\.c)$$')		\
	    && { echo '$(ME): the above are already included via system.h'\
		  1>&2;  exit 1; } || :;				\
	fi

sc_sun_os_names:
	@grep -nEi \
	    'solaris[^[:alnum:]]*2\.(7|8|9|[1-9][0-9])|sunos[^[:alnum:]][6-9]' \
296
	    $$($(VC_LIST_EXCEPT)) &&					\
297 298 299 300
	  { echo '$(ME): found misuse of Sun OS version numbers' 1>&2;	\
	    exit 1; } || :

sc_the_the:
301
	@grep -ni '\<the ''the\>' $$($(VC_LIST_EXCEPT)) &&		\
302 303 304 305 306 307 308
	  { echo '$(ME): found use of "the ''the";' 1>&2;		\
	    exit 1; } || :

sc_tight_scope:
	$(MAKE) -C src $@

sc_trailing_blank:
309
	@grep -n '[	 ]$$' $$($(VC_LIST_EXCEPT)) &&			\
310 311 312
	  { echo '$(ME): found trailing blank(s)'			\
		1>&2; exit 1; } || :

313 314 315 316 317 318 319 320
# Ensure that no C source file uses TABs for indentation.
# Also match *.h.in files, to get libvirt.h.in.
# Exclude files in gnulib, since they're imported.
sc_TAB_in_indentation:
	@grep -lE '^ *	' /dev/null					\
	     $$($(VC_LIST_EXCEPT)					\
	        | grep -E '\.[ch](\.in)?$$'				\
	        | grep -v '^gnulib/') &&				\
321 322
	  { echo '$(ME): found TAB(s) used for indentation in C sources;'\
	      'use spaces' 1>&2; exit 1; } || :
323

324 325 326
ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\
|isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper

327
sc_avoid_ctype_macros:
328
	@grep -E '\b($(ctype_re)) *\(' /dev/null			\
329 330
	     $$($(VC_LIST_EXCEPT)) &&					\
	  { echo "$(ME): don't use ctype macros (use c-ctype.h)"	\
331 332
		1>&2; exit 1; } || :

333 334 335 336 337 338
# Match lines like the following, but where there is only one space
# between the options and the description:
#   -D, --all-repeated[=delimit-method]  print all duplicate lines\n
longopt_re = --[a-z][0-9A-Za-z-]*(\[?=[0-9A-Za-z-]*\]?)?
sc_two_space_separator_in_usage:
	@grep -nE '^   *(-[A-Za-z],)? $(longopt_re) [^ ].*\\$$'		\
339
	    $$($(VC_LIST_EXCEPT)) &&					\
340 341 342 343
	  { echo "$(ME): help2man requires at least two spaces between"; \
	    echo "$(ME): an option and its description"; \
		1>&2; exit 1; } || :

344 345 346 347 348 349 350 351 352 353 354 355 356 357
msg_gen_function =
msg_gen_function += DISABLE_fprintf
msg_gen_function += virXendError
msg_gen_function += virXMLError
msg_gen_function += virHashError
msg_gen_function += virConfError
msg_gen_function += virTestError
msg_gen_function += virLibConnError
msg_gen_function += virStorageReportError
msg_gen_function += virxmlRpcError
msg_gen_function += virLog
msg_gen_function += qemudLog
msg_gen_function += remoteDispatchError
msg_gen_function += virStorageLog
358
msg_gen_function += xenXMError
359
msg_gen_function += ReportError
360
msg_gen_function += qemudReportError
361
msg_gen_function += openvzLog
D
Daniel Veillard 已提交
362
msg_gen_function += openvzError
363
msg_gen_function += virDomainReportError
364 365
msg_gen_function += virReportErrorHelper
msg_gen_function += lxcError
366
msg_gen_function += umlError
367

368 369 370
# Uncomment the following and run "make syntax-check" to see diagnostics
# that are not yet marked for translation, but that need to be rewritten
# so that they are translatable.
371
# msg_gen_function += error
372 373 374 375 376
# msg_gen_function += virXenError
# msg_gen_function += testError

func_or := $(shell printf '$(msg_gen_function)'|tr -s '[[:space:]]' '|')
func_re := ($(func_or))
377

378 379
# Look for diagnostics that aren't marked for translation.
# This won't find any for which error's format string is on a separate line.
380 381 382
# The sed filters eliminate false-positives like these:
#    _("...: "
#    "%s", _("no storage vol w..."
383 384
sc_unmarked_diagnostics:
	@grep -nE							\
385
            '\<$(func_re) \([^"]*"[^"]*[a-z]{3}' $$($(VC_LIST_EXCEPT))	\
386 387 388
	  | grep -v '_''(' &&						\
	  { echo '$(ME): found unmarked diagnostic(s)' 1>&2;		\
	    exit 1; } || :
389 390
	@{ grep     -nE '\<$(func_re) *\(.*;$$' $$($(VC_LIST_EXCEPT));   \
	   grep -A1 -nE '\<$(func_re) *\(.*,$$' $$($(VC_LIST_EXCEPT)); } \
391 392
	   | sed 's/_("[^"][^"]*"//;s/[	 ]"%s"//'			\
	   | grep '[	 ]"' &&						\
393 394
	  { echo '$(ME): found unmarked diagnostic(s)' 1>&2;		\
	    exit 1; } || :
395

396
sc_prohibit_virBufferAdd_with_string_literal:
397
	@grep -nE '\<virBufferAdd *\([^,]+, *"[^"]' $$($(VC_LIST_EXCEPT)) && \
398 399 400
	  { echo '$(ME): use virBufferAddLit, not virBufferAdd,' \
	      'with a string literal' 1>&2; exit 1; } || :

401 402 403 404 405 406
# Not only do they fail to deal well with ipv6, but the gethostby*
# functions are also not thread-safe.
sc_prohibit_gethostby:
	@grep -nE '\<gethostby(addr|name2?) *\(' $$($(VC_LIST_EXCEPT)) && \
	  { echo '$(ME): use getaddrinfo, not gethostby*' 1>&2; exit 1; } || :

407 408 409
# Avoid useless parentheses like those in this example:
# #if defined (SYMBOL) || defined (SYM2)
sc_useless_cpp_parens:
410
	@grep -n '^# *if .*defined *(' $$($(VC_LIST_EXCEPT)) &&		\
411 412 413 414 415
	  { echo '$(ME): found useless parentheses in cpp directive'	\
		1>&2; exit 1; } || :

# Require the latest GPL.
sc_GPL_version:
416
	@grep -n 'either ''version [^3]' $$($(VC_LIST_EXCEPT)) &&	\
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
	  { echo '$(ME): GPL vN, N!=3' 1>&2; exit 1; } || :

# Ensure that the c99-to-c89 patch applies cleanly.
patch-check:
	rm -rf src-c89 $@.1 $@.2
	cp -a src src-c89
	(cd src-c89; patch -p1 -V never --fuzz=0) < src/c99-to-c89.diff \
	  > $@.1 2>&1
	if test "$$REGEN_PATCH" = yes; then \
	  diff -upr src src-c89 | sed 's,src-c89/,src/,' \
	    | grep -v '^Only in' > new-diff || : ; fi
	grep -v '^patching file ' $@.1 > $@.2 || :
	msg=ok; test -s $@.2 && msg='fuzzy patch' || : ;	\
	rm -f src-c89/*.o || msg='rm failed';			\
	$(MAKE) -C src-c89 CFLAGS='-Wdeclaration-after-statement -Werror' \
	  || msg='compile failure with extra options';		\
	test "$$msg" = ok && rm -rf src-c89 $@.1 $@.2 || echo "$$msg" 1>&2; \
	test "$$msg" = ok

# Ensure that date's --help output stays in sync with the info
# documentation for GNU strftime.  The only exception is %N,
# which date accepts but GNU strftime does not.
extract_char = sed 's/^[^%][^%]*%\(.\).*/\1/'
strftime-check:
J
Jim Meyering 已提交
441
	@if test -f $(srcdir)/src/date.c; then				\
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
	  grep '^  %.  ' $(srcdir)/src/date.c | sort			\
	    | $(extract_char) > $@-src;					\
	  { echo N;							\
	    info libc date calendar format | grep '^    `%.'\'		\
	      | $(extract_char); } | sort > $@-info;			\
	  diff -u $@-src $@-info || exit 1;				\
	  rm -f $@-src $@-info;						\
	fi

check-AUTHORS:
	$(MAKE) -C src $@

# Ensure that we use only the standard $(VAR) notation,
# not @...@ in Makefile.am, now that we can rely on automake
# to emit a definition for each substituted variable.
makefile-check:
	grep -nE '@[A-Z_0-9]+@' `find . -name Makefile.am` \
	  && { echo 'Makefile.maint: use $$(...), not @...@' 1>&2; exit 1; } || :

news-date-check: NEWS
	today=`date +%Y-%m-%d`;						\
	if head NEWS | grep '^\*.* $(VERSION_REGEXP) ('$$today')'	\
	    >/dev/null; then						\
	  :;								\
	else								\
	  echo "version or today's date is not in NEWS" 1>&2;		\
	  exit 1;							\
	fi

changelog-check:
	if head ChangeLog | grep 'Version $(VERSION_REGEXP)\.$$'	\
	    >/dev/null; then						\
	  :;								\
	else								\
	  echo "$(VERSION) not in ChangeLog" 1>&2;			\
	  exit 1;							\
	fi

m4-check:
481
	@grep -n 'AC_DEFUN([^[]' $(top_srcdir)/m4/*.m4 \
482 483 484
	  && { echo 'Makefile.maint: quote the first arg to AC_DEFUN' 1>&2; \
	       exit 1; } || :

485 486 487 488
fix_po_file_diag = \
'you have changed the set of files with translatable diagnostics;\n\
apply the above patch\n'

489
# Verify that all source files using _() are listed in po/POTFILES.in.
490
po_file = po/POTFILES.in
491
po-check:
J
Jim Meyering 已提交
492
	@if test -f po/POTFILES.in; then					\
493 494 495
	  grep -E -v '^(#|$$)' po/POTFILES.in				\
	    | grep -v '^src/false\.c$$' | sort > $@-1;			\
	  files=;							\
496 497 498 499 500
	  for file in $$($(VC_LIST_EXCEPT)); do				\
	    case $$file in						\
	    djgpp/* | man/*) continue;;					\
	    */c99-to-c89.diff) continue;;				\
	    esac;							\
501 502 503 504
	    case $$file in						\
	    *.[ch])							\
	      base=`expr " $$file" : ' \(.*\)\..'`;			\
	      { test -f $$base.l || test -f $$base.y; } && continue;;	\
505
	    *) continue;;						\
506 507 508 509 510
	    esac;							\
	    files="$$files $$file";					\
	  done;								\
	  grep -E -l '\b(N?_|gettext *)\([^)"]*("|$$)' $$files		\
	    | sort -u > $@-2;						\
511 512
	  diff -u -L $(po_file) -L $(po_file) $@-1 $@-2			\
	    || { printf '$(ME): '$(fix_po_file_diag) 1>&2; exit 1; };	\
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
	  rm -f $@-1 $@-2;						\
	fi

# In a definition of #define AUTHORS "... and ..." where the RHS contains
# the English word `and', the string must be marked with `N_ (...)' so that
# gettext recognizes it as a string requiring translation.
author_mark_check:
	@grep -n '^# *define AUTHORS "[^"]* and ' src/*.c |grep -v ' N_ (' && \
	  { echo 'Makefile.maint: enclose the above strings in N_ (...)' 1>&2; \
	    exit 1; } || :

# Sometimes it is useful to change the PATH environment variable
# in Makefiles.  When doing so, it's better not to use the Unix-centric
# path separator of `:', but rather the automake-provided `@PATH_SEPARATOR@'.
# It'd be better to use `find -print0 ...|xargs -0 ...', but less portable,
# and there probably aren't many projects with so many Makefile.am files
# that we'd have to worry about limits on command line length.
msg = 'Makefile.maint: Do not use `:'\'' above; use @PATH_SEPARATOR@ instead'
makefile_path_separator_check:
	@grep -n 'PATH=.*:' `find $(srcdir) -name Makefile.am` \
	  && { echo $(msg) 1>&2; exit 1; } || :

# Check that `make alpha' will not fail at the end of the process.
writable-files:
	if test -d $(release_archive_dir); then :; else			\
538 539 540 541 542 543 544
	  for file in $(distdir).tar.gz					\
	              $(release_archive_dir)/$(distdir).tar.gz; do	\
	    test -e $$file || continue;					\
	    test -w $$file						\
	      || { echo ERROR: $$file is not writable; fail=1; };	\
	  done;								\
	  test "$$fail" && exit 1 || :
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
	fi

v_etc_file = lib/version-etc.c
sample-test = tests/sample-test
texi = doc/$(PACKAGE).texi
# Make sure that the copyright date in $(v_etc_file) is up to date.
# Do the same for the $(sample-test) and the main doc/.texi file.
copyright-check:
	@if test -f $(v_etc_file); then \
	  grep 'enum { COPYRIGHT_YEAR = '$$(date +%Y)' };' $(v_etc_file) \
	    >/dev/null \
	  || { echo 'out of date copyright in $(v_etc_file); update it' 1>&2; \
	       exit 1; }; \
	fi
	@if test -f $(sample-test); then \
	  grep '# Copyright (C) '$$(date +%Y)' Free' $(sample-test) \
	    >/dev/null \
	  || { echo 'out of date copyright in $(sample-test); update it' 1>&2; \
	       exit 1; }; \
	fi
	@if test -f $(texi); then \
	  grep 'Copyright @copyright{} .*'$$(date +%Y)' Free' $(texi) \
	    >/dev/null \
	  || { echo 'out of date copyright in $(texi); update it' 1>&2; \
	       exit 1; }; \
	fi

vc-diff-check:
	$(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

cvs-check: vc-diff-check

maintainer-distcheck:
	$(MAKE) distcheck
	$(MAKE) my-distcheck

# Use -Wformat -Werror to detect format-string/arg-list mismatches.
# Also, check for shadowing problems with -Wshadow, and for pointer
# arithmetic problems with -Wpointer-arith.
# These CFLAGS are pretty strict.  If you build this target, you probably
# have to have a recent version of gcc and glibc headers.
# The for-loop below ensures that there is a bin/ directory full of all
# of the programs under test (except the few that are required for basic
# Makefile rules), all symlinked to the just-built "false" program.
# This is to ensure that if ever a test neglects to make PATH include
# the build srcdir, these always-failing programs will run.
# Otherwise, it is too easy to test the wrong programs.
# Note that "false" itself is a symlink to true, so it too will malfunction.
TMPDIR ?= /tmp
t=$(TMPDIR)/$(PACKAGE)/test
my-distcheck: $(local-check) check
	-rm -rf $(t)
	mkdir -p $(t)
	GZIP=$(GZIP_ENV) $(AMTAR) -C $(t) -zxf $(distdir).tar.gz
	cd $(t)/$(distdir)				\
	  && ./configure --disable-nls			\
	  && $(MAKE) CFLAGS='$(warn_cflags)'		\
	      AM_MAKEFLAGS='$(null_AM_MAKEFLAGS)'	\
	  && $(MAKE) dvi				\
	  && $(MAKE) distclean
	(cd $(t) && mv $(distdir) $(distdir).old	\
	  && $(AMTAR) -zxf - ) < $(distdir).tar.gz
	diff -ur $(t)/$(distdir).old $(t)/$(distdir)
	if test -f $(srcdir)/src/c99-to-c89.diff; then			\
	  cd $(t)/$(distdir)						\
	    && (cd src && patch -V never --fuzz=0 <c99-to-c89.diff)	\
	    && ./configure --disable-largefile				\
	         CFLAGS='-Werror -ansi -Wno-long-long'			\
	    && $(MAKE);							\
	fi
	-rm -rf $(t)
	@echo "========================"; \
	echo "$(distdir).tar.gz is ready for distribution"; \
	echo "========================"
626

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
cvs-to-git = '\#!/usr/bin/perl\n\
use warnings;\n\
use strict;\n\
use File::Find;\n\
use File::Copy;\n\
\n\
find ({wanted =>\n\
       sub {$$_ eq q/.cvsignore/ or return;\n\
	    my $$gi = q/.gitignore/;\n\
	    unlink $$gi;\n\
	    copy($$_, $$gi) or die qq/copy failed: $$_->$$gi: $$!\\n/;\n\
	    chmod 0444, $$gi;\n\
	    }},\n\
      q!.!);\n'

.PHONY: sync-vcs-ignore-files
c2g = cvs-to-git
644
sync-vcs-ignore-files:
645 646 647 648 649 650
	rm -f $(c2g)-t $(c2g)
	printf $(cvs-to-git) > $(c2g)-t
	chmod a+x-w $(c2g)-t
	mv $(c2g)-t $(c2g)
	perl $(c2g)
	rm -f $(c2g)