PACKAGE :=	@PACKAGE_NAME@
VERSION :=	@PACKAGE_VERSION@
RELEASE :=	@PACKAGE_RELEASE@
PACKAGE_TARNAME := @PACKAGE_TARNAME@
PACKAGE_BUGREPORT := @PACKAGE_BUGREPORT@

prefix :=	@prefix@
exec_prefix :=	@exec_prefix@
bindir :=	@bindir@
datarootdir :=	@datarootdir@
datadir :=	@datadir@
docdir :=	@docdir@
mandir :=	@mandir@
localedir :=	$(datadir)/locale
emacsdir :=	$(datadir)/emacs/site-lisp
etcdir :=	@sysconfdir@

INSTALL :=	@INSTALL@
POD2MAN :=	@POD2MAN@
COLUMN :=	@COLUMN@
GETOPT :=	@GETOPT@
CP :=		@CP@
DATE :=		@DATE@
PERL :=		/usr/bin/env perl
BASH :=		/usr/bin/env bash
SHELL:=		@BASH@ # It does not work if dash is used as a shell, for example
GREP :=		@GREP@
TAIL :=		@TAIL@
TR :=		@TR@
SED :=		@SED@
AWK :=		@AWK@
FIND :=		@FIND@
XARGS :=	@XARGS@
DIFF :=		@DIFF@
PATCH :=	/usr/bin/env patch
MKTEMP :=	@MKTEMP@
MSGMERGE :=	@MSGMERGE@
MSGFMT :=	@MSGFMT@
XGETTEXT :=	@XGETTEXT@
MSGUNIQ :=	@MSGUNIQ@
MSGCAT :=	@MSGCAT@
DIFFSTAT :=	@DIFFSTAT@
RPMBUILD :=	@RPMBUILD@
SENDMAIL :=	@SENDMAIL@
MD5SUM :=	@MD5SUM@

USE_NLS :=	@USE_NLS@
STAT_HARDLINK := @STAT_HARDLINK@
PATCH_WRAPPER := @PATCH_WRAPPER@

COMPAT_SYMLINKS	:=
COMPAT_PROGRAMS	:=

default: all

#-----------------------------------------------------------------------
DIRT +=		$(shell $(FIND) . -name '*~')
DIRT +=		$(shell $(FIND) . -name '.\#*')

SRC +=		COPYING AUTHORS TODO Makefile.in configure.ac		\
		config/install-sh quilt.spec.in NEWS			\
		bash_completion quilt.quiltrc aclocal.m4 git-desc
DIRT +=		quilt.spec

DIRT +=		$(PACKAGE)-*.tar.gz
DIRT +=		$(PACKAGE)-*.tar.gz.sig
DIRT +=		$(PACKAGE)-*.tar.bz2

BIN_IN :=	quilt guards
BIN_SRC :=	$(BIN_IN:%=%.in)
BIN :=		$(BIN_IN)
SRC +=		$(BIN_SRC:%=bin/%) bin/patch-wrapper.in
DIRT +=		$(BIN_IN:%=bin/%) bin/patch-wrapper

QUILT_IN :=	$(patsubst quilt/%.in,%,$(wildcard quilt/*.in))
QUILT_SRC :=	$(QUILT_IN:%=%.in)
QUILT :=	$(QUILT_IN)
SRC +=		$(QUILT_SRC:%=quilt/%)
DIRT +=		$(QUILT_IN:%=quilt/%)

SCRIPTS_IN :=	patchfns inspect-wrapper dependency-graph edmail	\
		remove-trailing-ws backup-files

SCRIPTS_SRC :=	$(SCRIPTS_IN:%=%.in)
SCRIPTS :=	$(SCRIPTS_IN)
SRC +=		$(SCRIPTS_SRC:%=quilt/scripts/%)
SRC +=		quilt/scripts/utilfns
DIRT +=		$(SCRIPTS_IN:%=quilt/scripts/%)

COMPAT :=	$(COMPAT_PROGRAMS:%=compat/%) $(COMPAT_SYMLINKS:%=compat/%)
SRC +=		$(wildcard compat/*.in) $(wildcard compat/*.sh)
DIRT +=		$(patsubst %.in,%,$(wildcard compat/*.in)) $(COMPAT_SYMLINKS:%=compat/%)

LIB_SRC :=	quilt.el
SRC +=		$(LIB_SRC:%=lib/%)

DOC_IN :=	README quilt.1
DOC_SRC :=	$(DOC_IN:%=doc/%.in)
DOC :=		$(DOC_IN)
SRC +=		$(DOC_SRC)
SRC +=		doc/main.tex doc/quilt.pdf doc/Makefile	\
		doc/README.MAIL doc/README.EMACS
DIRT +=		$(DOC_IN:%=doc/%) doc/reference

MAN1 :=		doc/quilt.1
ifneq ($(POD2MAN),)
MAN1 +=		bin/guards.1
DIRT +=		bin/guards.1
endif

LINGUAS :=	fr de ja ru
PO :=		quilt.pot $(LINGUAS:%=%.po)
SRC +=		$(PO:%=po/%)
DIRT +=		po/*.mo po/*~

SRC +=		$(wildcard test/*.test) test/run test/test.quiltrc

NON_EXEC_IN :=	doc/quilt.1 doc/README quilt/scripts/patchfns quilt/scripts/utilfns

GIT_DESC :=	$(shell ./git-desc | sed -e 's:^v::')

# Tests are sorted to make it easier to compare the results between runs
TESTS :=	$(sort $(wildcard test/*.test))
ifeq ($(PATCH_WRAPPER),)
TESTS :=	$(filter-out test/patch-wrapper.test,$(TESTS))
endif
DIRT +=		test/.depend $(wildcard test/.*.ok)

# Settings for running the uninstalled version of quilt in the source tree:
PATH :=		$(CURDIR)/bin:$(CURDIR)/compat:$(PATH)
QUILT_DIR :=	$(CURDIR)/quilt
QUILTRC :=	$(CURDIR)/test/test.quiltrc
export QUILT_DIR QUILTRC

#-----------------------------------------------------------------------

all : configure scripts compat $(DOC:%=doc/%) $(MAN1) mofiles

ifeq ($(USE_NLS),yes)
mofiles : $(LINGUAS:%=po/%.mo)
else
mofiles :
endif

%.mo : %.po
	$(MSGFMT) --statistics -o $@ $<

%.po : po/quilt.pot
	$(MSGMERGE) -o $@ $@ $^

scripts : $(BIN:%=bin/%) $(QUILT:%=quilt/%)				\
	  $(SCRIPTS:%=quilt/scripts/%)					\
	  $(if $(PATCH_WRAPPER),bin/patch-wrapper)

dist : clean $(PACKAGE)-$(VERSION).tar.gz

publish : dist
	gpg --detach-sign --use-agent $(PACKAGE)-$(VERSION).tar.gz
	scp $(PACKAGE)-$(VERSION).tar.gz{,.sig} \
		dl.sv.nongnu.org:/releases/quilt/

snapshot : $(PACKAGE)-$(GIT_DESC).tar.bz2

rpm rpmbuild : $(PACKAGE)-$(VERSION).tar.gz
	$(RPMBUILD) -ta $<

po/quilt.pot: $(filter-out doc/quilt.1.in doc/README.in,		\
			   $(wildcard */*.in) $(wildcard */*/*.in))
	rm -f po/quilt.pot; touch po/quilt.pot
	for file in $+ ; do						\
	  if test -n "`$(SED) -ne '1{ /@BASH''@/p }' $$file`"		\
	       -o "$$file" = quilt/scripts/patchfns.in; then		\
	    $(BASH) --dump-po-strings $$file ;				\
	  elif test -n "`$(SED) -ne '1{ /@PERL''@/p }' $$file`"; then	\
	    $(XGETTEXT) --from-code=UTF-8 --omit-header --language=Perl	\
			--keyword=_ -o - $$file;			\
	  else								\
	    echo "Don't know how to handle $$file" >&2 ;		\
	    exit 1;							\
	  fi								\
	done								\
	|$(MSGUNIQ)							\
	|$(MSGCAT) --force-po -F - $@ -o $@

doc/README : doc/README.in doc/reference
	@echo "README.in -> README"
	@while read line; do						\
		case "$$line" in					\
		'@REFERENCE''@')					\
			cat doc/reference				\
			;;						\
		*)							\
			echo $$line					\
			;;						\
		esac ;							\
	done 2>&1 < $< > $@

doc/quilt.1: doc/quilt.1.in doc/reference $(COMPAT)
	@echo "quilt.1.in -> quilt.1"
	@while read line; do						\
	  case "$$line" in						\
	  '@REFERENCE''@')						\
	    $(SED) -e 's/^quilt \([^ ]*\)\(.*\)/.IP "\\fB\1\\fP\2 " 4/'	\
		   -e $$'s/^  \\(-[^\t]*\\)\t\\?/.IP "    \\1" 8\\\n/'	\
		   -e $$'s/^  \t\\?//'					\
	    < doc/reference						\
	    ;;								\
	  *@DOCSUBDIR@*)						\
	    echo "$$line" |						\
	    $(SED) -e 's:@DOCSUBDIR''@:$(docdir):g' \
	    ;;								\
	  *)								\
	    echo "$$line"						\
	    ;;								\
	  esac;								\
	done < $< 2>&1 > $@

doc/reference : bin/quilt $(QUILT:%=quilt/%) quilt/scripts/patchfns quilt/scripts/utilfns $(COMPAT)
	@unset LANG LC_MESSAGES LC_CTYPE LC_ALL;			\
	for i in $(sort $(QUILT));					\
	do								\
		echo;							\
		QUILT_PC=.fake_pc quilt $$i -h;				\
		echo;							\
	done |								\
	$(SED) -e 's/\$$EDITOR ([^)]*)/$$EDITOR/'			\
	       -e '/^$$/!s/^/  /'					\
	       -e 's/^  Usage: *//' > $@

bin/guards.1 : bin/guards
	$(POD2MAN) $< > $@

$(PACKAGE)-$(VERSION).tar.gz : $(SRC) configure $(PACKAGE).spec
	rm -f $(PACKAGE)-$(VERSION) $@
	ln -s . $(PACKAGE)-$(VERSION)
	tar chf - $(+:%=$(PACKAGE)-$(VERSION)/%) | gzip -9 > $@
	rm -f $(PACKAGE)-$(VERSION)
	@echo "File $@ created."

$(PACKAGE)-$(GIT_DESC).tar.bz2 : $(SRC) configure $(PACKAGE).spec
	rm -f $(PACKAGE)-$(GIT_DESC) $@
	ln -s . $(PACKAGE)-$(GIT_DESC)
	tar chf - $(+:%=$(PACKAGE)-$(GIT_DESC)/%) | bzip2 -9 > $@
	rm -f $(PACKAGE)-$(GIT_DESC)
	@echo "File $@ created."

$(PACKAGE).spec : $(PACKAGE).spec.in NEWS Makefile
	@echo "Generating spec file" ;					\
	set -e ;							\
	changelog="`sed 						\
		-e 's/^Version \([0-9.]*\) (\(.*\))/* \2 - upstream\n- Update to version \1/' \
		-e 's/^  -/  +/' < NEWS`" ;				\
	$(AWK) '{ gsub(/@VERSION''@/, "$(VERSION)") ;			\
		  gsub(/@RELEASE''@/, "$(RELEASE)") ;			\
		  gsub(/@CHANGELOG''@/, changelog) ;			\
		  print }' changelog="$$changelog" $< > $@

$(patsubst %.in,%,$(wildcard bin/*.in quilt/*.in quilt/scripts/*.in)) :: Makefile
% :: %.in
	@echo "$< -> $@" >&2
	@$(SED) -e 's:@QUILT_DIR''@:$(datadir)/$(PACKAGE):g'		\
		-e 's:@PERL''@:$(PERL):g'				\
		-e 's:@BASH''@:$(BASH):g'				\
		-e 's:@PATCH''@:$(PATCH):g'				\
		-e 's:@STAT_HARDLINK''@:$(STAT_HARDLINK):g'		\
		-e 's:@VERSION''@:$(VERSION):g'				\
		-e 's:@ETCDIR''@:$(etcdir):g'				\
		-e 's:@LOCALEDIR''@:$(localedir):g'			\
		-e 's:@DOCSUBDIR''@:$(docdir):g'			\
		-e '/^### Local Variables:/Q'				\
		$< > $@
	@$(if $(filter $@,$(NON_EXEC_IN)),,chmod +x $@)

configure : configure.ac aclocal.m4
	@touch $@

Makefile : Makefile.in configure
	@touch $@

compat_leftover := $(filter-out $(COMPAT),$(shell $(FIND) compat -type f -perm -0100))

.PHONY :: compat
compat :: $(COMPAT)
	$(if $(compat_leftover),rm -f $(compat_leftover))

# VIRTUAL_SYMLINKS creates a shell script that operates similar to
# a symbolic link.  It is used to workaround the way make treats
# symlinks as targets.
#   Usage: $(call VIRTUAL_SYMLINK, source, target)
define VIRTUAL_SYMLINK
	@echo "Generating $(strip $(1)) wrapper" >&2;
	@printf "#!%s\nexec %s "'"$$@"'"\n" $(BASH) $(strip $(1)) > $(2);
endef

# Rule to create compat/<binary> for each binary in $(COMPAT_SYMLINKS)
$(COMPAT_SYMLINKS:%=compat/%) :: Makefile
	$(call VIRTUAL_SYMLINK, \
		$($(shell echo $@ | $(AWK) '{split($$1, ar, "/"); print toupper(ar[2])}')), \
		$(strip $@))
	@chmod +x $(strip $@)

install-main :: scripts
	$(INSTALL) -d $(BUILD_ROOT)$(bindir)
	$(INSTALL) -m 755 $(BIN:%=bin/%) $(BUILD_ROOT)$(bindir)/

	$(INSTALL) -d $(BUILD_ROOT)$(datadir)/$(PACKAGE)
	$(INSTALL) -m 755 $(QUILT:%=quilt/%) $(BUILD_ROOT)$(datadir)/$(PACKAGE)/

	$(INSTALL) -d $(BUILD_ROOT)$(datadir)/$(PACKAGE)/scripts
	$(INSTALL) -m 755 $(patsubst %,quilt/scripts/%,			\
			  $(filter-out patchfns,$(SCRIPTS)))		\
		   $(BUILD_ROOT)$(datadir)/$(PACKAGE)/scripts
	$(INSTALL) -m 644 quilt/scripts/patchfns quilt/scripts/utilfns	\
		   $(BUILD_ROOT)$(datadir)/$(PACKAGE)/scripts
ifneq ($(PATCH_WRAPPER),)
	$(INSTALL) -d $(BUILD_ROOT)$(datadir)/$(PACKAGE)/wrapper
	$(INSTALL) -m 755 bin/patch-wrapper				\
		   $(BUILD_ROOT)$(datadir)/$(PACKAGE)/wrapper/patch
endif

	$(INSTALL) -d $(BUILD_ROOT)$(docdir)/
	$(INSTALL) -m 644 doc/README					\
		   $(BUILD_ROOT)$(docdir)/
	$(INSTALL) -m 644 doc/quilt.pdf doc/README.MAIL			\
		   $(BUILD_ROOT)$(docdir)/

	$(INSTALL) -d $(BUILD_ROOT)$(mandir)/man1
	$(INSTALL) -m 644 $(MAN1) $(BUILD_ROOT)$(mandir)/man1/

	$(INSTALL) -d $(BUILD_ROOT)$(etcdir)
	$(INSTALL) -d $(BUILD_ROOT)$(etcdir)/bash_completion.d
	$(INSTALL) -m 644 bash_completion				\
		   $(BUILD_ROOT)$(etcdir)/bash_completion.d/quilt
	$(INSTALL) -m 644 quilt.quiltrc $(BUILD_ROOT)$(etcdir)/
	$(INSTALL) -d $(BUILD_ROOT)$(emacsdir)/
	$(INSTALL) -m 644 lib/quilt.el $(BUILD_ROOT)$(emacsdir)/

install-compat: install-compat1 $(COMPAT_SYMLINKS:%=install-compat-symlink-%)
install-compat-symlink-% :: install-compat1
	ln -sf $($(shell echo $* | $(AWK) '{print toupper($$1)}'))	\
	       $(BUILD_ROOT)$(datadir)/$(PACKAGE)/compat/$*

install-compat1:
	rm -rf $(BUILD_ROOT)$(datadir)/$(PACKAGE)/compat
ifneq ($(COMPAT_PROGRAMS)$(COMPAT_SYMLINKS),)
	$(INSTALL) -d $(BUILD_ROOT)$(datadir)/$(PACKAGE)/compat
ifneq ($(COMPAT_PROGRAMS),)
	$(INSTALL) -m 755 $(COMPAT_PROGRAMS:%=compat/%)			\
		   $(BUILD_ROOT)$(datadir)/$(PACKAGE)/compat
endif
endif

install: install-main install-compat

uninstall ::
	rm -rf $(BIN:%=$(BUILD_ROOT)$(bindir)/%)			\
	       $(BUILD_ROOT)$(datadir)/$(PACKAGE)			\
	       $(patsubst %,$(BUILD_ROOT)$(mandir)/man1/%,		\
		   $(notdir $(MAN1)))					\
	       $(BUILD_ROOT)$(etcdir)/bash_completion.d/quilt		\
	       $(BUILD_ROOT)$(etcdir)/quilt.quiltrc			\
	       $(BUILD_ROOT)$(docdir)/					\
	       $(BUILD_ROOT)$(emacsdir)/quilt.el

check: $(TESTS:test/%.test=test/.%.ok)
check-all: $(TESTS:test/%.test=check-%)

check-% : test/.%.ok
	@/bin/true

# Only include the test suite dependencies when required
ifneq ($(findstring test,$(MAKECMDGOALS))$(findstring check,$(MAKECMDGOALS)),)
-include test/.depend
endif # (test|check)

test/.patch-wrapper.ok : bin/patch-wrapper

# Include a run-time generated list of dependencies for each test case
test/.depend : Makefile $(TESTS)
	@(  printf "%s : bin/quilt quilt/scripts/patchfns quilt/scripts/utilfns quilt/scripts/backup-files $(COMPAT)\n" $(TESTS); \
	    $(AWK) 'sub(/.*\$$ *quilt /, "")				\
			{ print FILENAME, ":", "quilt/"$$1}' $(TESTS); \
	    $(AWK) 'sub(/.*\<quilt_command /, "") && ($$1 !~ /[^a-z]/)	\
			{ print FILENAME, ":", "quilt/"$$1 }' quilt/*.in; \
	    $(AWK) 'sub(/.*\$$ *%{QUILT_DIR}\/scripts\//, "")		\
			{ print FILENAME, ":", "quilt/scripts/"$$1 }' $(TESTS); \
	) | sort -u | $(SED) -re 's:^test/(.*)\.test:test/.\1.ok:' \
	    -e 's:quilt/graph:quilt/graph quilt/scripts/dependency-graph:' \
	    -e 's:quilt/mail:quilt/mail quilt/scripts/edmail:' \
	    -e 's:quilt/refresh:quilt/refresh quilt/scripts/remove-trailing-ws:' \
	    -e 's:quilt/setup:quilt/setup quilt/scripts/inspect-wrapper:' \
	  > $@

ifneq ($(shell . $(QUILTRC) ;  echo $$QUILT_PATCHES_PREFIX),)
CHECK_ENV := P=patches/; _P=../patches/; export P _P
endif

# Each tests dependencies are stored in test/.depend
ifneq ($(findstring check-,$(MAKECMDGOALS)),)
test/.%.ok : test/%.test FORCE
else
test/.%.ok : test/%.test
endif
	@LANG=C; LC_ALL=C;						\
	export LANG LC_ALL;						\
	unset POSIXLY_CORRECT;						\
	$(CHECK_ENV);							\
	cd $(@D);							\
	./run -q $(<F)
	@touch $@

clean :
	rm -f $(DIRT)

distclean : clean
	rm -f config.log config.status Makefile
	rm -rf autom4te.cache/

ifeq ($(USE_NLS),yes)
install-main ::
	for lang in $(LINGUAS) ; do					\
		dir=$(BUILD_ROOT)$(localedir)/$$lang/LC_MESSAGES;	\
		$(INSTALL) -d $$dir;					\
		$(INSTALL) -m 644 po/$$lang.mo				\
		    $$dir/quilt.mo ;					\
	done

uninstall ::
	for lang in $(LINGUAS) ; do					\
		dir=$(BUILD_ROOT)$(localedir)/$$lang/LC_MESSAGES;	\
		rm -f $$dir/quilt.mo ;					\
	done
endif

.PHONY :: all install uninstall clean distclean

# Clear the suffix list
.SUFFIXES:
.SUFFIXES: .c .o .in
# Bad gmake, never *ever* try to get a file out of source control by yourself.
%: %,v
%: RCS/%,v
%: RCS/%
%: s.%
%: SCCS/s.%

FORCE:
