* Makefile.am: Adjust.
* GNUmakefile, Makefile.maint: Update from CVS Autoconf, but
keeping local WGET and WGETFLAGS modifications from Paul Eggert.
2003-08-25 Akim Demaille <akim@epita.fr>
+ * config/announce-gen, Makefile.cfg: New.
+ * Makefile.am: Adjust.
+ * GNUmakefile, Makefile.maint: Update from CVS Autoconf, but
+ keeping local WGET and WGETFLAGS modifications from Paul Eggert.
+
+2003-08-25 Akim Demaille <akim@epita.fr>
+
When reducing initial empty rules, Bison parser read an initial
location that is not defined. This results in garbage, and that
affects Bison's own parser. Therefore we need (i) to extend Bison
# It is necessary if you want to build targets usually of interest
# only to the maintainer.
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
# Systems where /bin/sh is not the default shell need this. The $(shell)
# command below won't work with e.g. stock DOS/Windows shells.
+ifeq ($(wildcard /bin/s[h]),/bin/sh)
SHELL = /bin/sh
+else
+# will be used only with the next shell-test line, then overwritten
+# by a configured-in value
+SHELL = sh
+endif
have-Makefile := $(shell test -f Makefile && echo yes)
# give them a diagnostic.
ifeq ($(have-Makefile),yes)
+# Make tar archive easier to reproduce.
+export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner
+
include Makefile
+include $(srcdir)/Makefile.cfg
include $(srcdir)/Makefile.maint
else
## Process this file with automake to produce Makefile.in -*-Makefile-*-
-## Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+## Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
SUBDIRS = config po lib data src doc m4 tests
-EXTRA_DIST = REFERENCES OChangeLog Makefile.maint GNUmakefile
+EXTRA_DIST = REFERENCES OChangeLog Makefile.maint GNUmakefile Makefile.cfg
.PHONY: maintainer-check
maintainer-check:
cd tests && $(MAKE) $(AM_MAKEFLAGS) $@
-
-## ---------------------------- ##
-## Customizing Makefile.maint. ##
-## ---------------------------- ##
-
-move_if_change = $(srcdir)/config/move-if-change
-prev_version_file = $(srcdir)/config/prev-version.txt
-release_archive_dir = releases
-
-# Uploading betas.
-url_dir_list = \
- ftp://alpha.gnu.org/gnu/bison
-
-# Files to update automatically.
-wget_files = $(srcdir)/config/config.guess $(srcdir)/config/config.sub \
- $(srcdir)/config/texinfo.tex
-
-cvs_files = $(srcdir)/config/missing
--- /dev/null
+# Customize Makefile.maint for Bison. -*- makefile -*-
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+prev_version_file = $(srcdir)/config/prev-version.txt
+move_if_change = $(srcdir)/config/move-if-change
+announce_gen = $(srcdir)/config/announce-gen
+release_archive_dir = releases
+
+# Use alpha.gnu.org for alpha and beta releases.
+# Use ftp.gnu.org for major releases.
+gnu_ftp_host-alpha = alpha
+gnu_ftp_host-beta = alpha
+gnu_ftp_host-major = ftp
+gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
+
+url_dir_list = \
+ ftp://$(gnu_rel_host).gnu.org/gnu/bison
+
+# Files to update automatically.
+wget_files = \
+ $(srcdir)/config/config.guess \
+ $(srcdir)/config/config.sub \
+ $(srcdir)/config/texinfo.tex \
+
+cvs_files = \
+ $(srcdir)/config/install-sh \
+ $(srcdir)/config/mdate-sh \
+ $(srcdir)/config/missing \
+ $(srcdir)/config/mkinstalldirs
+
+# Tests not to run.
+# local-checks-to-skip ?= \
+# author_mark_check \
+# strftime-check syntax-check makefile_path_separator_check \
+# makefile-check
# -*-Makefile-*-
-# This Makefile fragment is shared between fileutils, sh-utils, textutils,
+# This Makefile fragment is shared between the coreutils,
# CPPI, Bison, and Autoconf.
-## Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+## Copyright (C) 2001-2003 Free Software Foundation, Inc.
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
## 02111-1307, USA.
+# 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.
-GZIP_ENV = '--no-name --best'
+GZIP_ENV = '--no-name --best --rsyncable'
CVS = cvs
-prev_version_file ?= .prev-version
+ifeq ($(origin prev_version_file), undefined)
+ prev_version_file = .prev-version
+endif
-THIS_VERSION_REGEXP = $(subst .,\.,$(VERSION))
PREV_VERSION := $(shell cat $(prev_version_file))
-PREV_VERSION_REGEXP := $(shell echo $(PREV_VERSION)|sed 's/\./\\./g')
tag-package = $(shell echo "$(PACKAGE)" | tr '[:lower:]' '[:upper:]')
tag-this-version = $(subst .,_,$(VERSION))
-tag-prev-version = $(subst .,_,$(PREV_VERSION))
this-cvs-tag = $(tag-package)-$(tag-this-version)
-prev-cvs-tag = $(tag-package)-$(tag-prev-version)
my_distdir = $(PACKAGE)-$(VERSION)
# Old releases are stored here.
# Used for diffs and xdeltas.
release_archive_dir ?= ../release
+# 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
+
## --------------- ##
# Checks that don't require cvs.
# Run `changelog-check' last, as previous test may reveal problems requiring
# new ChangeLog entries.
-local-check = \
+local-checks-available = \
po-check copyright-check writable-files m4-check author_mark_check \
- changelog-check strftime-check header-check
-.PHONY: $(local-check)
+ changelog-check strftime-check syntax-check makefile_path_separator_check \
+ makefile-check
+.PHONY: $(local-checks-available)
+
+local-check = $(filter-out $(local-checks-to-skip), $(local-checks-available))
# Make sure C source files in src/ don't include xalloc.h directly,
# since they all already include it via sys2.h.
# It's not a big deal -- just aesthetics.
-header-check:
- if test -f $(srcdir)/src/sys2.h; then \
+.PHONY: $(syntax-check-rules)
+syntax-check-rules = \
+ sc_cast_of_argument_to_free \
+ sc_cast_of_x_alloc_return_value \
+ sc_changelog \
+ sc_error_exit_success \
+ sc_space_tab \
+ sc_sun_os_names \
+ sc_system_h_headers \
+ sc_unmarked_diagnostics \
+ sc_xalloc_h_in_src
+
+syntax-check: $(syntax-check-rules)
+# @grep -E '# *include <(limits|std(def|arg|bool))\.h>' \
+# $$(find -type f -name '*.[chly]') && \
+# { echo '$(ME): found conditional include' 1>&2; \
+# exit 1; } || :
+
+# grep -E '^# *include <(string|stdlib)\.h>' \
+# $(srcdir)/{lib,src}/*.[chy] && \
+# { echo '$(ME): FIXME' 1>&2; \
+# exit 1; } || :
+# FIXME: don't allow `#include .strings\.h' anywhere
+
+# 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.
+sc_unmarked_diagnostics:
+ @grep --exclude=$(srcdir)/src/shred.c -E \
+ '\<error \([^"]*"[^"]*[a-z]{3}' $(srcdir)/{lib,src}/*.c \
+ | grep -v '_(' && \
+ { echo '$(ME): found unmarked diagnostic(s)' 1>&2; \
+ exit 1; } || :
+
+sc_cast_of_argument_to_free:
+ @grep -E '\<free \(\(' $(srcdir)/{lib,src}/*.[chly] && \
+ { echo '$(ME): don'\''t cast free argument' 1>&2; \
+ exit 1; } || :
+
+sc_cast_of_x_alloc_return_value:
+ @grep -E --exclude=$(srcdir)/lib/regex.c \
+ '\*\) *x(m|c|re)alloc\>' $(srcdir)/{lib,src}/*.[chy] && \
+ { echo '$(ME): don'\''t cast x*alloc return value' 1>&2; \
+ exit 1; } || :
+
+sc_space_tab:
+ @( cvsu --list ) > /dev/null 2>&1 || : && \
+ grep '[ ] ' \
+ $$(cvsu --list | grep -vEf .x-$@ ) && \
+ { echo '$(ME): found SPACE-TAB sequence; remove the SPACE' \
+ 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 -F 'error (EXIT_SUCCESS,' \
+ $$(find -type f -name '*.[chly]') && \
+ { echo '$(ME): found error (EXIT_SUCCESS' 1>&2; \
+ exit 1; } || :
+
+# FIXME: merge this with sc_system_h_headers below.
+# xalloc.h is included via system.h, so should not be included
+# directly by any file in src/.
+sc_xalloc_h_in_src:
+ @if test -f $(srcdir)/src/sys2.h; then \
if grep 'xalloc\.h' $(srcdir)/src/*.c; then \
exit 1; \
fi; \
fi
+# FIXME: warn about definitions of EXIT_FAILURE, EXIT_SUCCESS, STREQ
+
+# Each nonempty line must start with a year number, or a TAB.
+sc_changelog:
+ @grep '^[^12 ]' $$(find . -name ChangeLog -maxdepth 2) && \
+ { echo '$(ME): found unexpected prefix in a ChangeLog' 1>&2; \
+ exit 1; } || :
+
+header_regexp = \
+ alloca\
+ |closeout\
+ |ctype\
+ |dirent\
+ |errno\
+ |fcntl\
+ |inttypes\
+ |limits\
+ |locale\
+ |pathmax\
+ |std(lib|bool)\
+ |string\
+ |sys/(stat|dir|time)\
+ |time\
+ |unistd\
+ |utime\
+ |version-etc\
+ |xalloc
+h_re := $(shell echo '$(header_regexp)'|tr -d ' ')
+
+# Files in src/ should not include directly any of
+# the headers already included via system.h.
+# Get list of candidates with this:
+# grep -h include src/sys*.h|sed 's/.*include //'|sort -
+sc_system_h_headers:
+ @( cvsu --list ) > /dev/null 2>&1 || : && \
+ grep -E '^# *include ["<]($(h_re))\.h[">]' \
+ $$(cvsu --list src | grep -Ev 'sys(2|tem)\.h$$') \
+ && { echo '$(ME): the above are already included via system.h'\
+ 1>&2; exit 1; } || :
+
+sc_sun_os_names:
+ @( cvsu --list ) > /dev/null 2>&1 || : && \
+ grep -Ei \
+ 'solaris[^[:alnum:]]*2\.(7|8|9|[1-9][0-9])|sunos[^[:alnum:]][6-9]' \
+ $$(cvsu --list | grep -vEf .x-$@ ) && \
+ { echo '$(ME): found misuse of Sun OS version numbers' 1>&2; \
+ exit 1; } || :
+
# 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.
rm -f $@-src $@-info; \
fi
+# 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 -E '@[A-Z_0-9]+@' `find . -name Makefile.am` \
+ && { echo 'Makefile.maint: use $(...), not @...@' 1>&2; exit 1; } || :
+
changelog-check:
if head ChangeLog | grep 'Version $(VERSION)' >/dev/null; then \
:; \
{ 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 '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 \
else :; fi
cvs-diff-check:
- if $(CVS) diff >cvs-diffs; then \
- rm cvs-diffs; \
- else \
- echo "Some files are locally modified:" 1>&2; \
+ if $(CVS) diff >cvs-diffs; then \
+ rm cvs-diffs; \
+ else \
+ echo "Some files are locally modified:" 1>&2; \
cat cvs-diffs; \
exit 1; \
fi
# by the use of _(). The --disable-nls effectively defines away that macro,
# and building with CFLAGS='-Wformat -Werror' causes any format warning to be
# treated as a failure.
-t=./=test
+TMPDIR ?= /tmp
+t=$(TMPDIR)/$(PACKAGE)/test
my-distcheck: $(local-check)
-rm -rf $(t)
- mkdir $(t)
+ mkdir -p $(t)
GZIP=$(GZIP_ENV) $(AMTAR) -C $(t) -zxf $(distdir).tar.gz
cd $(t)/$(distdir) \
&& ./configure --disable-nls \
&& $(MAKE) dvi \
&& $(MAKE) check \
&& $(MAKE) distclean
- cd $(t) && mv $(distdir) $(distdir).old \
- && $(AMTAR) -zxf ../$(distdir).tar.gz
+ (cd $(t) && mv $(distdir) $(distdir).old \
+ && $(AMTAR) -zxf - ) < $(distdir).tar.gz
diff -ur $(t)/$(distdir).old $(t)/$(distdir)
-rm -rf $(t)
@echo "========================"; \
prev-tgz = $(PACKAGE)-$(PREV_VERSION).tar.gz
xd-delta = $(PACKAGE)-$(PREV_VERSION)-$(VERSION).xdelta
-news-r1 = /^[^ ].*$(THIS_VERSION_REGEXP)[]:]/
-news-r2 = /^[^ ].*$(PREV_VERSION_REGEXP)[]:]/
-
-rel-files = $(xd-delta) $(distdir).tar.bz2 $(distdir).tar.gz
-announcement: NEWS ChangeLog $(rel-files)
- @( \
- echo Subject: $(my_distdir) released; \
- echo; \
- echo FIXME: put comments here; \
- echo; \
- for url in $(url_dir_list); do \
- echo " $$url/$(my_distdir).tar.gz ($(tgz-size))"; \
- echo " $$url/$(my_distdir).tar.bz2 ($(bz2-size))"; \
- done; \
- echo; \
- echo And here are xdelta-style diffs; \
- echo; \
- for url in $(url_dir_list); do \
- echo " $$url/$(xd-delta) ($(xd-size))"; \
- done; \
- echo; \
- echo "Here are the MD5 and SHA1 signatures:"; \
- echo; \
- echo "$(tgz-md5) $(my_distdir).tar.gz"; \
- echo "$(bz2-md5) $(my_distdir).tar.bz2"; \
- echo "$(xdelta-md5) $(xd-delta)"; \
- echo "$(tgz-sha1) $(my_distdir).tar.gz"; \
- echo "$(bz2-sha1) $(my_distdir).tar.bz2"; \
- echo "$(xdelta-sha1) $(xd-delta)"; \
- echo; \
- echo NEWS:; \
- sed -n "$(news-r1),$(news-r2)p" NEWS \
- | grep -v '^\['; \
- echo; \
- echo ChangeLog entries:; \
- find . -name ChangeLog -maxdepth 2 \
- | xargs $(CVS) diff -up -r$(prev-cvs-tag) -rHEAD \
- | sed -n 's/^+//p' \
- | perl -ne 'm!^\+\+ (\./)?! or print,next;' \
- -e 'print "\n"."*"x70 ."\n"; s///; print; print "*"x70 ."\n"'; \
- )
+signatures ?= $(distdir).tar.bz2.asc $(distdir).tar.gz.asc
+%.asc: %
+ rm -f $@
+ gpg --armor --detach-sign -o $@ $<
+
+rel-files = $(xd-delta) $(distdir).tar.bz2 $(distdir).tar.gz $(signatures)
+announce_gen ?= ./announce-gen
+announcement: NEWS ChangeLog $(rel-files) $(signatures)
+ @$(announce_gen) \
+ --release-type=$(RELEASE_TYPE) \
+ --package=$(PACKAGE) \
+ --prev=$(PREV_VERSION) \
+ --curr=$(VERSION) \
+ --release-archive-directory=$(release_archive_dir) \
+ --news=NEWS \
+ $(addprefix --url-dir=, $(url_dir_list)) \
## ---------------- ##
## ---------------- ##
ftp-gnu = ftp://ftp.gnu.org/gnu
+www-gnu = http://www.gnu.org
# Use mv, if you don't have/want move-if-change.
move_if_change ?= move-if-change
tmppo=/tmp/$(PACKAGE)-$(VERSION)-po &&\
rm -rf $$tmppo && \
mkdir $$tmppo && \
- (cd $$tmppo && $(WGET) $(WGETFLAGS) -r -l1 -nd --no-parent -A '*.po' $(po_repo)) &&\
+ (cd $$tmppo && \
+ $(WGET) $(WGETFLAGS) -r -l1 -nd --no-parent -A '*.po' $(po_repo)) &&\
cp $$tmppo/*.po po
cd po && $(MAKE) update-po
$(MAKE) po-check
texinfo.tex-url_prefix = $(ftp-gnu)/texinfo/
-standards.texi-url_prefix = $(ftp-gnu)/GNUinfo/
-make-stds.texi-url_prefix = $(ftp-gnu)/GNUinfo/
+standards.texi-url_prefix = $(www-gnu)/prep/
+make-stds.texi-url_prefix = $(standards.texi-url_prefix)
target = $(patsubst get-%, %, $@)
url = $($(notdir $(target))-url_prefix)$(notdir $(target))
$(WGET) $(WGETFLAGS) $(url) -O $(target).t \
&& $(move_if_change) $(target).t $(target)
-cvs_files ?= $(srcdir)/config/depcomp $(srcdir)/config/missing $(srcdir)/config/mkinstalldirs \
- $(srcdir)/config/install-sh $(srcdir)/src/ansi2knr.c
+cvs_files ?= \
+ $(srcdir)/src/ansi2knr.c \
+ $(srcdir)/config/depcomp \
+ $(srcdir)/config/install-sh \
+ $(srcdir)/config/missing \
+ $(srcdir)/config/mkinstalldirs
automake_repo=:pserver:anoncvs:anoncvs@sources.redhat.com:/cvs/automake
.PHONY: wget-update
wget-update: $(get-targets)
.PHONY: cvs-update
cvs-update:
- for f in $(cvs_files); do \
- test -f $$f || { echo "*** skipping $$f" 1>&2; continue; }; \
- file=`basename $$f`; \
- echo checking out $$file...; \
- $(CVS) -d $(automake_repo) co -p automake/lib/$$file> $$f.t \
- && $(move_if_change) $$f.t $$f; \
- done
+ fail=; \
+ for f in $(cvs_files); do \
+ test -f $$f || { echo "*** skipping $$f" 1>&2; continue; }; \
+ cvs diff $$f > /dev/null \
+ || { echo "*** $$f is locally modified; skipping it" 1>&2; \
+ fail=yes; continue; }; \
+ file=$$(basename $$f); \
+ echo checking out $$file...; \
+ $(CVS) -d $(automake_repo) co -p automake/lib/$$file> $$f.t \
+ && $(move_if_change) $$f.t $$f; \
+ done; \
+ test "$$fail" && exit 1
define emit-upload-commands
echo =====================================
$(xd-delta): $(release_archive_dir)/$(prev-tgz) $(distdir).tar.gz
xdelta delta -9 $^ $@ || :
-alpha: $(local-check)
+.PHONY: alpha beta major
+alpha beta major: $(local-check)
$(MAKE) cvs-dist
$(MAKE) $(xd-delta)
- $(MAKE) -s announcement > /tmp/announce-$(my_distdir)
+ $(MAKE) -s announcement RELEASE_TYPE=$@ > /tmp/announce-$(my_distdir)
ln $(rel-files) $(release_archive_dir)
chmod a-w $(rel-files)
echo $(VERSION) > $(prev_version_file)
--- /dev/null
+#!/usr/bin/perl -w
+# Generate an announcement message.
+use strict;
+
+use Getopt::Long;
+use Digest::MD5;
+use Digest::SHA1;
+
+(my $VERSION = '$Revision$ ') =~ tr/[0-9].//cd;
+(my $ME = $0) =~ s|.*/||;
+
+my %valid_release_types = map {$_ => 1} qw (alpha beta major);
+
+END
+{
+ # Nobody ever checks the status of print()s. That's okay, because
+ # if any do fail, we're guaranteed to get an indicator when we close()
+ # the filehandle.
+ #
+ # Close stdout now, and if there were no errors, return happy status.
+ # If stdout has already been closed by the script, though, do nothing.
+ defined fileno STDOUT
+ or return;
+ close STDOUT
+ and return;
+
+ # Errors closing stdout. Indicate that, and hope stderr is OK.
+ warn "$ME: closing standard output: $!\n";
+
+ # Don't be so arrogant as to assume that we're the first END handler
+ # defined, and thus the last one invoked. There may be others yet
+ # to come. $? will be passed on to them, and to the final _exit().
+ #
+ # If it isn't already an error, make it one (and if it _is_ an error,
+ # preserve the value: it might be important).
+ $? ||= 1;
+}
+
+sub usage ($)
+{
+ my ($exit_code) = @_;
+ my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
+ if ($exit_code != 0)
+ {
+ print $STREAM "Try `$ME --help' for more information.\n";
+ }
+ else
+ {
+ my @types = sort keys %valid_release_types;
+ print $STREAM <<EOF;
+Usage: $ME [OPTIONS]
+
+OPTIONS:
+
+ Generate an announcement message.
+
+ FIXME: describe the following
+
+ --release-type=TYPE TYPE must be one of @types
+ --package-name=PACKAGE_NAME
+ --previous-version=VER
+ --current-version=VER
+ --release-archive-directory=DIR
+ --url-directory=URL_DIR
+ --news=NEWS_FILE optional
+
+ --help display this help and exit
+ --version output version information and exit
+
+EOF
+ }
+ exit $exit_code;
+}
+
+sub print_changelog_deltas ($$)
+{
+ my ($package_name, $prev_version) = @_;
+
+ # Print new ChangeLog entries.
+
+ # First find all CVS-controlled ChangeLog files.
+ use File::Find;
+ my @changelog;
+ find ({wanted => sub {$_ eq 'ChangeLog' && -d 'CVS'
+ and push @changelog, $File::Find::name}},
+ '.');
+
+ # If there are no ChangeLog files, we're done.
+ @changelog
+ or return;
+ my %changelog = map {$_ => 1} @changelog;
+
+ # Reorder the list of files so that if there are ChangeLog
+ # files in the specified directories, they're listed first,
+ # in this order:
+ my @dir = qw ( . src lib m4 config doc );
+
+ # A typical @changelog array might look like this:
+ # ./ChangeLog
+ # ./po/ChangeLog
+ # ./m4/ChangeLog
+ # ./lib/ChangeLog
+ # ./doc/ChangeLog
+ # ./config/ChangeLog
+ my @reordered;
+ foreach my $d (@dir)
+ {
+ my $dot_slash = $d eq '.' ? $d : "./$d";
+ my $target = "$dot_slash/ChangeLog";
+ delete $changelog{$target}
+ and push @reordered, $target;
+ }
+
+ # Append any remaining ChangeLog files.
+ push @reordered, sort keys %changelog;
+
+ # Remove leading `./'.
+ @reordered = map { s!^\./!!; $_ } @reordered;
+
+ print "\nChangeLog entries:\n\n";
+ # print join ("\n", @reordered), "\n";
+
+ $prev_version =~ s/\./_/g;
+ my $prev_cvs_tag = "\U$package_name\E-$prev_version";
+
+ my $cmd = "cvs -n diff -u -r$prev_cvs_tag -rHEAD @reordered";
+ open DIFF, '-|', $cmd
+ or die "$ME: cannot run `$cmd': $!\n";
+ # Print two types of lines, making minor changes:
+ # Lines starting with `+++ ', e.g.,
+ # +++ ChangeLog 22 Feb 2003 16:52:51 -0000 1.247
+ # and those starting with `+'.
+ # Don't print the others.
+ my $prev_printed_line_empty = 1;
+ while (defined (my $line = <DIFF>))
+ {
+ if ($line =~ /^\+\+\+ /)
+ {
+ my $separator = "*"x70 ."\n";
+ $line =~ s///;
+ $line =~ s/\s.*//;
+ $prev_printed_line_empty
+ or print "\n";
+ print $separator, $line, $separator;
+ }
+ elsif ($line =~ /^\+/)
+ {
+ $line =~ s///;
+ print $line;
+ $prev_printed_line_empty = ($line =~ /^$/);
+ }
+ }
+ close DIFF;
+
+ # The exit code should be 1.
+ # Allow in case there are no modified ChangeLog entries.
+ $? == 256 || $? == 128
+ or warn "$ME: warning: `cmd' had unexpected exit code or signal ($?)\n";
+}
+
+{
+ my $release_type;
+ my $package_name;
+ my $prev_version;
+ my $curr_version;
+ my $release_archive_dir;
+ my @url_dir_list;
+ my $news_file;
+
+ GetOptions
+ (
+ 'release-type=s' => \$release_type,
+ 'package-name=s' => \$package_name,
+ 'previous-version=s' => \$prev_version,
+ 'current-version=s' => \$curr_version,
+ 'release-archive-directory=s' => \$release_archive_dir,
+ 'url-directory=s@' => \@url_dir_list,
+ 'news=s@' => \$news_file,
+
+ help => sub { usage 0 },
+ version => sub { print "$ME version $VERSION\n"; exit },
+ ) or usage 1;
+
+ my $fail = 0;
+ # Ensure that sure each required option is specified.
+ $release_type
+ or (warn "$ME: release type not specified\n"), $fail = 1;
+ $package_name
+ or (warn "$ME: package name not specified\n"), $fail = 1;
+ $prev_version
+ or (warn "$ME: previous version string not specified\n"), $fail = 1;
+ $curr_version
+ or (warn "$ME: current version string not specified\n"), $fail = 1;
+ $release_archive_dir
+ or (warn "$ME: release directory name not specified\n"), $fail = 1;
+ @url_dir_list
+ or (warn "$ME: URL directory name(s) not specified\n"), $fail = 1;
+
+ exists $valid_release_types{$release_type}
+ or (warn "$ME: `$release_type': invalid release type\n"), $fail = 1;
+
+ @ARGV
+ and (warn "$ME: too many arguments\n"), $fail = 1;
+ $fail
+ and usage 1;
+
+ my $my_distdir = "$package_name-$curr_version";
+ my $tgz = "$my_distdir.tar.gz";
+ my $tbz = "$my_distdir.tar.bz2";
+ my $xd = "$package_name-$prev_version-$curr_version.xdelta";
+
+ my %size;
+
+ foreach my $f (($tgz, $tbz, $xd))
+ {
+ my $cmd = "du --human $f";
+ my $t = `$cmd`;
+ # FIXME-someday: give a better diagnostic, a la $PROCESS_STATUS
+ $@
+ and (warn "$ME: command failed: `$cmd'\n"), $fail = 1;
+ chomp $t;
+ $t =~ s/^([\d.]+[MkK]).*/${1}B/;
+ $size{$f} = $t;
+ }
+
+ $fail
+ and exit 1;
+
+ print <<EOF;
+
+Subject: $my_distdir released
+
+<#secure method=pgpmime mode=sign>
+
+FIXME: put comments here
+
+EOF
+
+ print "Here are the compressed sources:\n";
+ foreach my $url (@url_dir_list)
+ {
+ print " $url/$tgz ($size{$tgz})\n";
+ print " $url/$tbz ($size{$tbz})\n";
+ }
+
+ print "\nAnd here are xdelta-style diffs:\n";
+ foreach my $url (@url_dir_list)
+ {
+ print " $url/$xd ($size{$xd})\n";
+ }
+
+ print "\nHere are GPG detached signatures:\n";
+ foreach my $url (@url_dir_list)
+ {
+ print " $url/$tgz.asc\n";
+ print " $url/$tbz.asc\n";
+ }
+
+ # FIXME: clean up upon interrupt or die
+ my $tmpdir = $ENV{TMPDIR} || '/tmp';
+ my $tmp = "$tmpdir/$ME-$$";
+ unlink $tmp; # ignore failure
+
+ print "\nHere are the MD5 and SHA1 signatures:\n";
+ print "\n";
+ print "<#part type=text/plain filename=\"$tmp\" disposition=inline>\n"
+ . "<#/part>\n";
+
+ open OUT, '>', $tmp
+ or die "$ME: $tmp: cannot open for writing: $!\n";
+
+ foreach my $meth (qw (md5 sha1))
+ {
+ foreach my $f (($tgz, $tbz, $xd))
+ {
+ open IN, '<', $f
+ or die "$ME: $f: cannot open for reading: $!\n";
+ binmode IN;
+ my $dig =
+ ($meth eq 'md5'
+ ? Digest::MD5->new->addfile(*IN)->hexdigest
+ : Digest::SHA1->new->addfile(*IN)->hexdigest);
+ close IN;
+ print OUT "$dig $f\n";
+ }
+ }
+
+ close OUT
+ or die "$ME: $tmp: while writing: $!\n";
+ chmod 0400, $tmp; # ignore failure
+
+ if ($news_file)
+ {
+ print "\nNEWS\n\n";
+
+ # Print all lines from $news_file, starting with the first one
+ # that mentions $curr_version up to but not including
+ # the first occurrence of $prev_version.
+ my $in_items;
+ open NEWS, '<', $news_file
+ or die "$ME: $news_file: cannot open for reading: $!\n";
+ while (defined (my $line = <NEWS>))
+ {
+ if ( ! $in_items)
+ {
+ # Match lines like this one:
+ # * Major changes in release 5.0.1:
+ # but not any other line that starts with a space, *, or -.
+ $line =~ /^(\* Major changes.*|[^ *-].*)\Q$curr_version\E/o
+ or next;
+ $in_items = 1;
+ print $line;
+ }
+ else
+ {
+ # Be careful that this regexp cannot match version numbers
+ # in NEWS items -- they might well say `introduced in 4.5.5',
+ # and we don't want that to match.
+ $line =~ /^(\* Major changes.*|[^ *-].*)\Q$prev_version\E/o
+ and last;
+ print $line;
+ }
+ }
+ close NEWS;
+
+ $in_items
+ or die "$ME: $news_file: no matching lines for `$curr_version'\n";
+ }
+
+ $release_type eq 'major'
+ or print_changelog_deltas ($package_name, $prev_version);
+
+ exit 0;
+}
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
- # in a .u file. This file always lives in the current directory.
- # Also, the AIX compiler puts `$object:' at the start of each line;
- # $object doesn't have directory information.
- stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
- outname="$stripped.o"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
-
stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
fi
if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.