# Copyright 2021, 2022, 2023 Kevin Ryde

# This file 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 3, or (at your option) any later
# version.
#
# This file 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 file.  If not, see <http://www.gnu.org/licenses/>.


# The source file interv.gp is ready to use.  There's no configuration or
# compile.
#
# The "test" rule runs self-tests test.gp and test-wip.gp.
#

VERSION = 3
GP = gp
GPFLAGS =

default:
	@echo 'nothing to build etc, but try "make test" for self-tests'

# "make test" uses test-symbols.txt, and in principle that file should be
# regenerated whenever interv.gp or interv-wip.gp changes, but don't want to
# demand Perl.  "make test-maint" will do it (and more) if desired.
#
# test_is_gnil is used if it can compile and if GP has install(), but the
# tests will run without it too.
#
test:
	-$(MAKE) -$(MAKEFLAGS) test_is_gnil.so
	$(GP) $(GPFLAGS) -f --quiet test.gp     </dev/null
	$(GP) $(GPFLAGS) -f --quiet test-wip.gp </dev/null

test_is_gnil.so: test_is_gnil.c
	$(CC) $(CFLAGS) -shared test_is_gnil.c -lpari -o test_is_gnil.so

# For Emacs `find-tag' etc
TAGS: interv.gp
	etags --lang=none --regex='/^\([a-z][a-zA-Z0-9_]*\)([^)]*) =/\1/' \
	  interv.gp

clean:
	# development temporary files
	rm -f interv-gp.c interv-wip-gp.c test-symbols.tmp test_is_gnil.so
	rm -f TAGS


#------------------------------------------------------------------------------
# Development

version:
	@echo $(VERSION)

# Checking symbols from test.gp makes too many exceptions.
# test.gp test-wip.gp
GP_FILES = interv.gp interv-wip.gp
test-symbols.txt test-funcs.txt: $(GP_FILES)
	tools/my-gp-symbols.pl $(GP_FILES) >test-symbols.tmp
	egrep -v '^(interv_|test_)' test-symbols.tmp >test-symbols.txt
	egrep    '^(interv_|test_)' test-symbols.tmp >test-funcs.txt
#	rm test-symbols.tmp
	wc -l test-symbols.txt test-funcs.txt

test-all: test-maint test
test-maint:
	$(MAKE) -$(MAKEFLAGS) $(DIST_GENERATED_FILES)

# my-check-gp.pl
	for i in interv.gp interv-wip.gp test-wip.gp \
	         examples/*.gp; do \
	  case $$i in \
	    examples/noredefsneededyet.gp) \
	       OPT=--allow-redefinition ;; \
	    *) OPT= ;; \
	  esac; \
	  tools/my-check-gp.pl --verbose $$OPT $$i || exit 1; \
	done
	tools/my-check-gp.pl --verbose --allow-redefinition \
	  test.gp devel/*.gp

# no output from loading interv.gp (no missing final ; on funcs)
	for i in $(GP_FILES); do \
	  OUT=`$(GP) $(GPFLAGS) -f --quiet <$$i`; \
	  if test -n "$$OUT"; then \
	    echo "$$i stray output:"; \
	    echo "$$OUT"; \
	    exit 1; \
	  fi; \
	done

	gp-inline *.gp
	cd devel && gp-inline *.gp

	# grep to ensure no "fetch_user_var()" of global variables
	# pol_x() is ok, being a symbol like 'x
	# subst() becomes a gsubst() call taking fetch_user_var("x") number rather than poly
	# State tables are global variables.
	# install() conditionals end up looking at them as global variables.
	#
	$(MAKE) -$(MAKEFLAGS) interv-gp.c
	if fgrep -v 'pol_x(fetch_user_var("x"))' interv-gp.c \
	  | fgrep -v 'pol_x(fetch_user_var("none"))'  \
	  | fgrep -v 'pol_x(fetch_user_var("unknown"))' \
	  | grep fetch_user_var; then exit 1; else exit 0; fi
	rm interv-gp.c

	$(MAKE) -$(MAKEFLAGS) interv-wip-gp.c
	if fgrep -v 'pol_x(fetch_user_var("x"))' interv-wip-gp.c \
	  | fgrep -v 'pol_x(fetch_user_var("none"))' \
	  | fgrep -v 'pol_x(fetch_user_var("unknown"))' \
	  | grep fetch_user_var; then exit 1; else exit 0; fi
	rm interv-wip-gp.c

	# each examples program should run
	set -x; cd examples && for i in *.gp; do \
	  $(GP) --quiet $(GPFLAGS) $$i </dev/null || exit 1; \
	done

	# slow development tests
	cd devel && $(MAKE)
	cd devel && $(MAKE) test

# gp2c here only to see it can process, not to actually execute.
# gp2c sometimes shows globals or dubious constructs.
# C files are named interv-gp.c etc not interv.gp.c since the latter has a
# danger of the source interv.gp looking like an executable made from the .c.
#
interv-gp.c: interv.gp
	sed -e 's/, )/, 0)/' \
	    -e 's/install(gnot/XXXinstall(gnot/' \
	    -e 's/\bvector,/(n->vector(n)),/' \
	  interv.gp             | gp2c -S >interv-gp.c
interv-wip-gp.c: interv.gp interv-wip.gp
	sed -e 's/, )/, 0)/' \
	    -e 's/install(gnot/XXXinstall(gnot/' \
	    -e 's/\bvector,/(n->vector(n)),/' \
	  interv.gp interv-wip.gp | gp2c -S >interv-wip-gp.c

DISTNAME = interv
DISTVNAME = $(DISTNAME)-$(VERSION)

echo-DISTVNAME:
	@echo $(DISTVNAME)

DIST_GENERATED_FILES = \
  test-funcs.txt \
  test-symbols.txt

DISTFILES = \
  COPYING \
  Makefile \
  *.c \
  *.gp \
  *.txt \
  examples/*.gp \
  devel/Makefile \
  tools/OEIS-data-reader \
  devel/*.gp \
  tools/*.gp \
  tools/*.pl \
  tools/*.sh

distdir:
	$(MAKE) -$(MAKEFLAGS) $(DIST_GENERATED_FILES)
	rm -rf $(DISTVNAME)
	mkdir $(DISTVNAME)
	mkdir $(DISTVNAME)/examples
	mkdir $(DISTVNAME)/devel
	mkdir $(DISTVNAME)/tools
	set -e; for i in $(DISTFILES); do \
	  cp -p $$i $(DISTVNAME)/$$i; \
	done
dist:
	$(MAKE) -$(MAKEFLAGS) distdir
	tar cf $(DISTVNAME).tar --sort=name $(DISTVNAME)
	gzip -9 --force $(DISTVNAME).tar
	rm -rf $(DISTVNAME)

diff-tux:
	diff -u ../../tux/data/pari/interv.gp interv.gp | less


#------------------------------------------------------------------------------
.PHONY: default all test test-maint clean dist distdir version
