VER      ?= 10
DESTDIR  ?= "`cat .prefix`"
GCC      != if $(CC) --version 2>&1 | grep -qi 'Free Software Foundation' || \
	$(CC) --version 2>&1 | grep -qi clang; then echo 1; else echo 0; fi
CFLAGS   ?= -O2
XFLAGS   != [ 'X$(GCC)' = X1 ] && echo -fPIC -shared -std=c11 -pedantic-errors \
	|| echo -G; echo -Wall
LDFLAGS  ?= -s
FEAT_DEF  = _DEFAULT_SOURCE _BSD_SOURCE __BSD_VISIBLE _NETBSD_SOURCE \
	__EXTENSIONS__
VINST    != sys=`uname -s`; if [ "X$$sys" != 'XOpenBSD' ]; then echo -v; fi
LIBNAME  ?= build/libarguments.so
PCNAME   ?= build/arguments.pc

help: .prefix
	@echo
	@echo 'Targets:'
	@echo '  all      build library'
	@echo '  install  install files'
	@echo '  clean    repository cleanup'
	@echo
	@echo '  man      check and update man pages'
	@echo
	@echo "PREFIX    `cat .prefix`"
	@echo 'CC        $(CC)'
	@echo 'CFLAGS    $(CFLAGS)'
	@echo 'XFLAGS    $(XFLAGS)'
	@echo 'LDFLAGS   $(LDFLAGS)'
	@echo

all: $(LIBNAME) $(PCNAME)

install: .prefix all
	for d in $(DESTDIR)/lib $(DESTDIR)/lib/pkgconfig $(DESTDIR)/include \
		$(DESTDIR)/share $(DESTDIR)/share/man $(DESTDIR)/share/man/man3; \
		do install -d $(VINST) "$$d" || exit 1; done
	install -C -m 0755 $(VINST) $(LIBNAME) $(DESTDIR)/lib
	install -C -m 0644 $(VINST) arguments.h $(DESTDIR)/include
	install -C -m 0644 $(VINST) $(PCNAME) $(DESTDIR)/lib/pkgconfig
	for m in man3/*.3; do install -C -m 0644 $(VINST) "$$m" \
		$(DESTDIR)/share/man/man3 || exit 1; done
	for l in arguments_sprintf arguments_error_printf; do \
		ln $(VINST) -s -f arguments_vsprintf.3 $(DESTDIR)/share/man/man3/"$$l".3 \
		|| exit 1; done

clean:
	rm -rf build .prefix .defs

man: .FORCE
	mkdir -p build
	for m in man3/*.3; do e="`groff -mandoc -ww -z $$m 2>&1 >/dev/null`"; \
		if [ -n "$$e" ]; then echo "$$m: $$e" 1>&2; exit 1; fi; done
	for m in man3/*.3; do export LC_ALL=C; export LC_TIME=C; \
		[ -n "`git diff HEAD -- $$m`" ] && d=`date +'%B %-d, %Y'` || \
		d=`git log -1 --pretty='format:%ad' --date='format:%B %-d, %Y' $$m`; \
		[ -n "$$d" ] || exit 1; sed 's/^[.]Dd.*$$/.Dd '"$$d/" < $$m \
		> "build/$${m#*/}" && cp "build/$${m#*/}" $$m || exit 1; done

$(LIBNAME): .defs *.c *.h *.map
	mkdir -p build
	$(CC) $(CFLAGS) $(XFLAGS) `cat .defs` -o $(LIBNAME) arguments.c $(LDFLAGS)

$(PCNAME): .prefix *.pc
	mkdir -p build
	sed -e 's"__PREFIX__"'`cat .prefix`'"g;s/__VERSION__/$(VER)/g' \
		arguments.pc > build/arguments.pc

.prefix: .FORCE
	@[ -n "$(PREFIX)" ] && p="$(PREFIX)" || p=/opt; if ! [ -f .prefix ] || \
		( [ -n "$(PREFIX)" ] && [ "$(PREFIX)" != "`cat .prefix`" ] ); then \
		printf %s "$$p" > .prefix; else exit 0; fi

.defs: Makefile
	mkdir -p build
	printf 'int main (void) { return 0; }\n' > build/test.c
	$(CC) $(CFLAGS) -o build/test build/test.c
	echo > build/.defs
	printf 'TEST {\n\tglobal:\n\t\t*;\n};' > build/test.map
	if $(CC) $(CFLAGS) -Wl,--version-script=build/test.map -o build/test \
		build/test.c >/dev/null 2>&1; then echo -Wl,--version-script=exports.map \
		>> build/.defs; fi
	printf '#include <syslog.h>\nint main (void) { return (int) vsyslog; }\n' \
		> build/test.c
	for f in $(FEAT_DEF); do if \
		$(CC) -D_XOPEN_SOURCE=700 -D$$f $(CFLAGS) -o build/test build/test.c \
		>/dev/null 2>&1; then echo "-D$$f -DHAVE_VSYSLOG" >> build/.defs; break; \
		fi; done
	printf \
		'#include <stdlib.h>\nint main (void) { return (long) getprogname; }\n' \
		> build/test.c
	for f in $(FEAT_DEF); do if \
		$(CC) -D_XOPEN_SOURCE=700 -D$$f $(CFLAGS) -o build/test build/test.c \
		>/dev/null 2>&1; then echo "-D$$f -DHAVE_GETPROGNAME" >> build/.defs; \
		break; fi; done
	printf \
		'#include <stdlib.h>\n%s;\nint main (void) { return (long) %s; }\n' \
		'extern char *program_invocation_short_name' \
		'program_invocation_short_name' > build/test.c && if \
		$(CC) $(CFLAGS) -o build/test build/test.c \
		>/dev/null 2>&1; then echo '-DHAVE_INV_NAME' >> build/.defs; fi
	printf \
		'#include <stdlib.h>\n#include <syslog.h>\nint main (void) { %s; }\n' \
		'return (long) facilitynames' > build/test.c
	for f in '' -D_DEFAULT_SOURCE; do if \
		$(CC) $$f -D_XOPEN_SOURCE=700 -DSYSLOG_NAMES $(CFLAGS) -o build/test \
		build/test.c >/dev/null 2>&1; then echo "$$f -DSYSLOG_NAMES" \
		>> build/.defs; break; fi; done
	cp build/.defs .

.FORCE:

.PHONY: all help clean install
