#
#  SPL - The SPL Programming Language
#  Copyright (C) 2004, 2005  Clifford Wolf <clifford@clifford.at>
#
#  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
#

# Autodetecting the host system (default is linux or compatible)
#
BUILDING_FOR_MACOSX := $(shell uname | grep -qvi darwin; echo $$?)
BUILDING_FOR_CYGWIN := $(shell uname | grep -qvi cygwin; echo $$?)
BUILDING_FOR_MINGW  := $(shell uname | grep -qvi mingw;  echo $$?)
BUILDING_FOR_BSD    := $(shell uname | grep -qvi bsd;    echo $$?)
BUILDING_FOR_IRIX   := $(shell uname | grep -qvi irix;   echo $$?)


#### BEGIN CONFIG #####


DESTDIR =

ifeq ($(BUILDING_FOR_MINGW),1)
  prefix = c:/spl
  INSTALL = install.exe
else
  prefix = /usr/local
  INSTALL = install
endif

CC = gcc
CXX = g++
YACC = bison -y

HOST_CC = $(CC)

ifeq ($(CC),$(HOST_CC))
  HOST_SPLRUN = splrun
else
  HOST_SPLRUN = host_splrun
endif

CFLAGS = -std=gnu99 -Wall -I$(shell pwd) $(EXTRA_CFLAGS) $(USER_CFLAGS)
CFLAGS += -Wshadow -D_GNU_SOURCE
LDFLAGS = -L$(shell pwd) $(EXTRA_LDFLAGS) $(USER_LDFLAGS)

ifeq ($(filter clean,$(MAKECMDGOALS)),)
EXTRA_CFLAGS := $(shell sh syscheck.sh extra_cflags)
EXTRA_LDFLAGS := $(shell sh syscheck.sh extra_ldflags)

# Let the user know where we get the configuration from
#
SYSCHECK_MESSAGE_DUMMY := $(shell test -f config.cache && \
	echo "Using cached build configuration from config.cache." >&2 || \
	echo "Auto-generating build configuration.." >&2)

# Autodetecting available libraries
# Set this to '1' or '0' to overwrite the test results.
#
ENABLE_REGEX_SUPPORT        := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p pcre)
ENABLE_EXPAT_SUPPORT        := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p expat)
ENABLE_SQLITE_SUPPORT       := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p sqlite)
ENABLE_MYSQL_SUPPORT        := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p mysql)
ENABLE_POSTGRES_SUPPORT     := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p postgres)
ENABLE_LIBXML2_SUPPORT      := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libxml2)
ENABLE_LIBXSLT_SUPPORT      := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libxslt)
ENABLE_LIBSDL_SUPPORT       := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libsdl)
ENABLE_LIBCURL_SUPPORT      := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libcurl)
ifeq ($(BUILDING_FOR_BSD),1)
  ENABLE_LIBUUID_SUPPORT    := 1
else
  ENABLE_LIBUUID_SUPPORT    := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libuuid)
endif
ENABLE_LIBFANN_SUPPORT      := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libfann)
ENABLE_WSCONS_SUPPORT       := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p wscons)
ENABLE_EPFB_SUPPORT         := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p epfb)
ENABLE_OPENGL_SUPPORT       := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p opengl)
ENABLE_SMOKE_SUPPORT        := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p libsmoke)
ENABLE_READLINE_SUPPORT     := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p readline)
ENABLE_GETTEXT_LIBC_SUPPORT := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p gettext_libc)
ENABLE_GETTEXT_INTL_SUPPORT := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p gettext_intl)
ENABLE_PTHREAD_SUPPORT      := $(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh -p pthread)
endif

# Set this to '1' if you want to profile the performance
# of the SPL compiler and runtime. This is not for profiling
# SPL scripts..
#
BUILD_WITH_PROFILER = 0

# Set this to '1' if you want to build an unoptimized SPL
# library with debug symbols.
#
BUILD_WITH_DEBUG = 1

# Set this to '1' if you are doing SPL core development
#
BUILD_WITH_WERROR = 0

# Set this to '1' for building SPL with MUDFLAP (pointer magic checks)
#
BUILD_WITH_MUDFLAP = 0


#### END CONFIG #####


ifeq ($(BUILDING_FOR_MINGW),1)
  bindir = $(prefix)
  libdir = $(prefix)
  datadir = $(prefix)
  includedir = $(prefix)
  splmod_libdir = $(libdir)/spl_modules
  cgibin_libdir = $(libdir)
else
  bindir = $(prefix)/bin
  libdir = $(prefix)/lib
  ifeq ($(shell uname),Linux)
    ifeq ($(shell uname --hardware-platform),x86_64)
      libdir = $(prefix)/lib64
    endif
  endif
  datadir = $(prefix)/share
  includedir = $(prefix)/include
  splmod_libdir = $(libdir)/spl_modules
  cgibin_libdir = $(libdir)/cgi-bin
endif

ifeq ($(BUILDING_FOR_BSD),0)
  LDLIBS_DL = -ldl
  LDLIBS_CURSES = -lncurses
else
  LDLIBS_DL =
  LDLIBS_CURSES = -lcurses
  CFLAGS += -DUSEBSDAPI=1
endif

ifeq ($(BUILDING_FOR_IRIX),1)
  CFLAGS += -DUSEIRIXAPI=1
endif

ifeq ($(BUILDING_FOR_CYGWIN)$(BUILDING_FOR_MINGW),00)
  LDLIBS = $(LDLIBS_DL) -lspl -lm
  SPL_LIBS = libspl.a
  MOD_LIBS =
  CFLAGS += -fPIC
  DLL_LIBS += $(LDLIBS_DL)
  ifeq ($(BUILDING_FOR_MACOSX),0)
    ifeq ($(BUILDING_FOR_IRIX),0)
      LDFLAGS += -rdynamic
    endif
  else
    CFLAGS += -DUSEMACOSXAPI=1
  endif
else
  LDLIBS = -lspl -lm
  SPL_LIBS = spl.dll
  MOD_LIBS = -lspl
  DLL_LIBS =
  ENABLE_LIBUUID_SUPPORT := 0
  ifeq ($(BUILDING_FOR_MINGW),1)
    CFLAGS += -Dint32_t=int -Dint16_t=short -Dint8_t=char -DUSEWIN32API=1
  else
    CFLAGS += -DUSECYGWINAPI=1
  endif
endif

ifeq ($(ENABLE_REGEX_SUPPORT),1)
  LDLIBS += $(shell pcre-config --libs)
  DLL_LIBS += $(shell pcre-config --libs)
  CFLAGS += $(shell pcre-config --cflags) -DENABLE_REGEX_SUPPORT
endif

ifeq ($(ENABLE_READLINE_SUPPORT),1)
  CFLAGS += -DENABLE_READLINE_SUPPORT
  LDLIBS += -lreadline $(LDLIBS_CURSES)
  DLL_LIBS += -lreadline $(LDLIBS_CURSES)
endif

ifneq ($(ENABLE_GETTEXT_LIBC_SUPPORT)$(ENABLE_GETTEXT_INTL_SUPPORT),00)
  CFLAGS += -DENABLE_GETTEXT_SUPPORT
endif

ifeq ($(ENABLE_GETTEXT_INTL_SUPPORT),1)
  LDLIBS += -lintl
  DLL_LIBS += -lintl
endif

ifeq ($(ENABLE_PTHREAD_SUPPORT),1)
  ifneq ($(shell $(CC) -pthread 2>&1 | grep -- -pthread | wc -l),0)
    CFLAGS += -D_REENTRANT -DENABLE_PTHREAD_SUPPORT
    LDLIBS += -lpthread
  else
    CFLAGS += -pthread -DENABLE_PTHREAD_SUPPORT
    LDFLAGS += -pthread
  endif
endif

ifeq ($(BUILD_WITH_PROFILER),1)
  CFLAGS += -pg
  LDFLAGS += -pg
endif

ifeq ($(BUILD_WITH_MUDFLAP),1)
  ifeq ($(ENABLE_PTHREAD_SUPPORT),1)
    CFLAGS += -fmudflapth
    LDLIBS += -lmudflapth
  else
    CFLAGS += -fmudflap
    LDLIBS += -lmudflap
  endif
endif

ifeq ($(BUILD_WITH_DEBUG),1)
  CFLAGS += -O1 -ggdb
else
  CFLAGS += -Os -fomit-frame-pointer
endif

ifeq ($(BUILD_WITH_WERROR),1)
  CFLAGS += -Werror -Wextra
endif

SPL_OBJS = state.o exec.o asm.o compiler.o dump.o restore.o clib.o util.o \
		builtins.o optimizer.o report.o treedump.o gc.o rccheck.o \
		debug.o string.o utf8.o hnode.o sha1.o moddir.o spl_op.o

MODULES := $(patsubst %.c,%.so,$(wildcard spl_modules/mod_*.c))			\
           $(foreach s,$(wildcard spl_modules/mod_*.spl),			\
	       $(if $(wildcard $(patsubst %.spl,%.c,$s)),			\
	           $(patsubst %.spl,%.splh,$s),$(patsubst %.spl,%.splb,$s)))

ifeq ($(BUILDING_FOR_MINGW),1)
  MODULES := $(patsubst %.so,%.dll,$(MODULES))
  MODULES := $(filter-out spl_modules/mod_environ.%,$(MODULES))
  MODULES := $(filter-out spl_modules/mod_system.%,$(MODULES))
  MODULES := $(filter-out spl_modules/mod_socket.%,$(MODULES))
endif

ifeq ($(ENABLE_EXPAT_SUPPORT),1)
  spl_modules/mod_format_xml.so: MOD_LIBS += -lexpat
else
  MODULES := $(filter-out spl_modules/mod_format_xml.%,$(MODULES))
endif

ifeq ($(ENABLE_SQLITE_SUPPORT),1)
  spl_modules/mod_sql_sqlite.so: MOD_LIBS += -lsqlite3
else
  MODULES := $(filter-out spl_modules/mod_sql_sqlite.%,$(MODULES))
endif

ifeq ($(ENABLE_MYSQL_SUPPORT),1)
  spl_modules/mod_sql_mysql.so: MOD_LIBS += -lmysqlclient
else
  MODULES := $(filter-out spl_modules/mod_sql_mysql.%,$(MODULES))
endif

ifeq ($(ENABLE_POSTGRES_SUPPORT),1)
  spl_modules/mod_sql_postgres.so: MOD_LIBS += -lpq
  LDFLAGS += -L$(shell pg_config --libdir)
  CFLAGS += -I$(shell pg_config --includedir)
else
  MODULES := $(filter-out spl_modules/mod_sql_postgres.%,$(MODULES))
endif

ifeq ($(ENABLE_LIBXML2_SUPPORT),1)
  ifeq ($(BUILDING_FOR_MINGW),1)
    spl_modules/mod_xml.dll: MOD_LIBS += $(shell xml2-config --libs) -lxml2
    spl_modules/mod_xml.o: CFLAGS += $(shell xml2-config --cflags)
  else
    spl_modules/mod_xml.so: MOD_LIBS += $(shell xml2-config --libs)
    spl_modules/mod_xml.so: CFLAGS += $(shell xml2-config --cflags)
  endif
  ifeq ($(ENABLE_LIBXSLT_SUPPORT),1)
    ifeq ($(BUILDING_FOR_MINGW),1)
      spl_modules/mod_xml.dll: MOD_LIBS += $(shell xslt-config --libs) -lexslt -lxml2 -lxslt
      spl_modules/mod_xml.o: CFLAGS += $(shell xslt-config --cflags) -DENABLE_LIBXSLT_SUPPORT
    else
      spl_modules/mod_xml.so: MOD_LIBS += $(shell xslt-config --libs) -lexslt
      spl_modules/mod_xml.so: CFLAGS += $(shell xslt-config --cflags) -DENABLE_LIBXSLT_SUPPORT
    endif
  endif
else
  MODULES := $(filter-out spl_modules/mod_xml.%,$(MODULES))
endif

ifeq ($(ENABLE_LIBSDL_SUPPORT),1)
  spl_modules/mod_sdl.so: MOD_LIBS += $(shell sdl-config --libs) -lSDL_image
  spl_modules/mod_sdl.so: CFLAGS += $(shell sdl-config --cflags)
else
  MODULES := $(filter-out spl_modules/mod_sdl.%,$(MODULES))
endif

ifeq ($(ENABLE_LIBCURL_SUPPORT),1)
  spl_modules/mod_curl.so: MOD_LIBS += $(shell curl-config --libs)
  spl_modules/mod_curl.so: CFLAGS += $(shell curl-config --cflags)
else
  MODULES := $(filter-out spl_modules/mod_curl.%,$(MODULES))
endif

ifeq ($(ENABLE_LIBUUID_SUPPORT),1)
  ifeq ($(BUILDING_FOR_BSD),0)
    spl_modules/mod_uuidgen.so: MOD_LIBS += -luuid
  endif
else
  MODULES := $(filter-out spl_modules/mod_uuidgen.%,$(MODULES))
endif

ifneq ($(ENABLE_WSCONS_SUPPORT),1)
  MODULES := $(filter-out spl_modules/mod_wscons.%,$(MODULES))
endif

ifneq ($(ENABLE_EPFB_SUPPORT),1)
  MODULES := $(filter-out spl_modules/mod_epfb.%,$(MODULES))
endif

ifeq ($(ENABLE_OPENGL_SUPPORT)$(ENABLE_REGEX_SUPPORT)$(BUILD_WITH_MUDFLAP),110)
  spl_modules/mod_gl.so: MOD_LIBS += -lGL
  spl_modules/mod_gl.so: CFLAGS += -DGL_GLEXT_PROTOTYPES
else
  MODULES := $(filter-out spl_modules/mod_gl.%,$(MODULES))
endif

ifeq ($(ENABLE_LIBFANN_SUPPORT)$(ENABLE_REGEX_SUPPORT)$(BUILD_WITH_MUDFLAP),110)
  spl_modules/mod_fann.so: MOD_LIBS += -lfann -lm
  spl_modules/mod_fann.so: CFLAGS += $(shell pkg-config --cflags fann 2> /dev/null)
else
  MODULES := $(filter-out spl_modules/mod_fann.%,$(MODULES))
endif

ifeq ($(ENABLE_SMOKE_SUPPORT),1)
  spl_modules/mod_qt.so: MOD_LIBS += -lqt-mt -lqui $(LDLIBS_DL)
  spl_modules/mod_qt.so: CFLAGS := $(filter-out -std=gnu99 -Wshadow,$(CFLAGS)) -x c++ \
	$(shell CC='$(CC)' CFLAGS='$(CFLAGS)' sh syscheck.sh libsmoke_config)
  spl_modules/mod_qt.so: CC := $(CXX)

  # Some qimage.h files throw this error
  spl_modules/mod_qt.so: CFLAGS += -Wno-parentheses

  # Some Qt structs have virtual functions but non-virtual destructors
  spl_modules/mod_qt.so: CFLAGS += -Wno-non-virtual-dtor
else
  MODULES := $(filter-out spl_modules/mod_qt.%,$(MODULES))
  MODULES := $(filter-out spl_modules/mod_kde.%,$(MODULES))
endif

ifeq ($(BUILDING_FOR_MINGW),1)
  MODULES := $(filter-out spl_modules/mod_crypt.%,$(MODULES))
else
  ifneq ($(BUILDING_FOR_MACOSX),1)
    spl_modules/mod_crypt.so: MOD_LIBS += -lcrypt
  endif
endif

ifneq ($(BUILDING_FOR_CYGWIN)$(BUILDING_FOR_MINGW)$(BUILDING_FOR_MACOSX)$(BUILDING_FOR_BSD),0000)
  MODULES := $(filter-out spl_modules/mod_multimouse.%,$(MODULES))
endif

ifeq ($(BUILDING_FOR_MINGW),0)
  all: $(MODULES) splrun webspl.cgi webspld spl-config
else
  all: $(MODULES) splrun webspl.cgi spl-config
endif

showconfig:
	@echo
	@echo "prefix =" $(prefix)
	@echo
	@echo "export CC='$(CC)'"
	@echo "export CFLAGS='$(CFLAGS)'"
	@echo "export LDFLAGS='$(LDFLAGS)'"
	@echo
	@echo "ENABLE_REGEX_SUPPORT        =" $(ENABLE_REGEX_SUPPORT)
	@echo "ENABLE_EXPAT_SUPPORT        =" $(ENABLE_EXPAT_SUPPORT)
	@echo "ENABLE_SQLITE_SUPPORT       =" $(ENABLE_SQLITE_SUPPORT)
	@echo "ENABLE_MYSQL_SUPPORT        =" $(ENABLE_MYSQL_SUPPORT)
	@echo "ENABLE_POSTGRES_SUPPORT     =" $(ENABLE_POSTGRES_SUPPORT)
	@echo "ENABLE_LIBXML2_SUPPORT      =" $(ENABLE_LIBXML2_SUPPORT)
	@echo "ENABLE_LIBXSLT_SUPPORT      =" $(ENABLE_LIBXSLT_SUPPORT)
	@echo "ENABLE_LIBSDL_SUPPORT       =" $(ENABLE_LIBSDL_SUPPORT)
	@echo "ENABLE_LIBCURL_SUPPORT      =" $(ENABLE_LIBCURL_SUPPORT)
	@echo "ENABLE_LIBUUID_SUPPORT      =" $(ENABLE_LIBUUID_SUPPORT)
	@echo "ENABLE_LIBFANN_SUPPORT      =" $(ENABLE_LIBFANN_SUPPORT)
	@echo "ENABLE_EPFB_SUPPORT         =" $(ENABLE_EPFB_SUPPORT)
	@echo "ENABLE_OPENGL_SUPPORT       =" $(ENABLE_OPENGL_SUPPORT)
	@echo "ENABLE_SMOKE_SUPPORT        =" $(ENABLE_SMOKE_SUPPORT)
	@echo "ENABLE_READLINE_SUPPORT     =" $(ENABLE_READLINE_SUPPORT)
	@echo "ENABLE_GETTEXT_LIBC_SUPPORT =" $(ENABLE_GETTEXT_LIBC_SUPPORT)
	@echo "ENABLE_GETTEXT_INTL_SUPPORT =" $(ENABLE_GETTEXT_INTL_SUPPORT)
	@echo "ENABLE_PTHREAD_SUPPORT      =" $(ENABLE_PTHREAD_SUPPORT)
	@echo
	@echo "BUILDING_FOR_MACOSX =" $(BUILDING_FOR_MACOSX)
	@echo "BUILDING_FOR_CYGWIN =" $(BUILDING_FOR_CYGWIN)
	@echo "BUILDING_FOR_MINGW  =" $(BUILDING_FOR_MINGW)
	@echo "BUILDING_FOR_BSD    =" $(BUILDING_FOR_BSD)
	@echo
	@echo "BUILD_WITH_PROFILER =" $(BUILD_WITH_PROFILER)
	@echo "BUILD_WITH_DEBUG    =" $(BUILD_WITH_DEBUG)
	@echo "BUILD_WITH_WERROR   =" $(BUILD_WITH_WERROR)
	@echo
	@echo "MODULES =" $(MODULES) | sed 's,spl_modules/,,g' | fold -w70 -s
	@echo

c-api-tests: examples/c-api-test1 examples/c-api-test2 examples/c-api-test3 examples/c-api-test4

test: all c-api-tests
	@[ -f spl.dll ] && cp -v spl.dll examples/ ; true
	@cd examples; for x in c-api-test1 c-api-test2 c-api-test3 c-api-test4; do \
		echo -n "Running './$$x' in 'examples/' .."; \
		./$$x 2>&1 | tr -d '\r' > $$x.tmp; \
		if cmp -s $$x.expected $$x.tmp; then echo " ok."; \
		else echo " ERROR!"; cat $$x.tmp; echo; fi \
	done
	@cd examples; for x in example*.spl; do \
	  if [ -z "$(SPLRUN_TEST_FLAGS)" -o "$$x" != "example27.spl" ]; then \
		echo -n "Running '../splrun $(SPLRUN_TEST_FLAGS) -M../spl_modules $$x' in 'examples/' .."; \
		if ( [ $(ENABLE_REGEX_SUPPORT)   = 0 ] && grep -q SKIP_IF_NO_REGEX   $$x; ) || \
		   ( [ $(ENABLE_EXPAT_SUPPORT)   = 0 ] && grep -q SKIP_IF_NO_EXPAT   $$x; ) || \
		   ( [ $(ENABLE_SQLITE_SUPPORT)  = 0 ] && grep -q SKIP_IF_NO_SQLITE  $$x; ) || \
		   ( [ $(ENABLE_LIBXML2_SUPPORT) = 0 ] && grep -q SKIP_IF_NO_LIBXML2 $$x; ) || \
		   ( [ $(ENABLE_LIBXSLT_SUPPORT) = 0 ] && grep -q SKIP_IF_NO_LIBXSLT $$x; ) || \
		   ( [ $(BUILD_WITH_MUDFLAP) = 1 ] && [ "$$x" == "example27.spl" ]; ) \
		then echo " SKIP."; continue; fi; \
		../splrun $(SPLRUN_TEST_FLAGS) -M../spl_modules $$x 2>&1 | tr -d '\r' | \
			sed '/^in:/ s/[0-9][0-9]*/NUM/; /^called by:/ s/[0-9][0-9]*/NUM/' > $${x%.spl}.tmp; \
		if cmp -s $${x%.spl}.expected $${x%.spl}.tmp; then echo " ok."; \
		else echo " ERROR!"; diff -u $${x%.spl}.expected  $${x%.spl}.tmp; echo; fi \
	  fi \
	done

dumptest:
	make SPLRUN_TEST_FLAGS='-d dumpfile.tmp -ss' test

vgtest: all
	@cd examples; for x in example*.spl; do \
	  if [ "$$x" != "example27.spl" ]; then \
		echo -n "Running 'valgrind [...] ../splrun [...] $$x' in 'examples/' .."; \
		errors="$$( valgrind --suppressions=../vgsuppress.txt \
			--tool=memcheck --leak-check=full --show-reachable=yes \
			../splrun $(SPLRUN_TEST_FLAGS) -M../spl_modules $$x 2>&1 | \
			egrep '^==.* ((ERROR SUMMARY|definitely lost|possibly lost|still reachable):|No malloc.d blocks) '; )"; \
		if echo "$$errors" | egrep -q '^==.*ERROR SUMMARY: 0 ' && \
		   ( echo "$$errors" | egrep -q '^==.* No malloc.d blocks ' || \
		     [ `echo "$$errors" | grep ': 0 ' | wc -l` -eq 4 ]; ); \
		then echo " ok."; else echo " ERROR!"; echo "$$errors"; fi \
	  fi \
	done

moddir.c: GNUmakefile
	echo '#include "spl.h"' > moddir.c.new
	echo 'const char *spl_system_modules_dir(void) { return "$(splmod_libdir)"; }' >> moddir.c.new
	mv moddir.c.new moddir.c

examples/c-api-test%: examples/c-api-test%.o $(SPL_LIBS)
	$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@

spl_modules/mod_%.so: spl_modules/mod_%.o $(SPL_LIBS)
ifeq ($(BUILDING_FOR_MACOSX),1)
	$(CC) $(LDFLAGS) -bundle -flat_namespace -undefined suppress $< $(MOD_LIBS) -o $@
else
	$(CC) $(LDFLAGS) -shared $< $(MOD_LIBS) -o $@
endif

spl_modules/mod_%.dll: spl_modules/mod_%.o $(SPL_LIBS)
	$(CC) $(LDFLAGS) -shared $< $(MOD_LIBS) -o $@

spl_modules/moc_mod_qt.c: spl_modules/mod_qt.c
	moc -o spl_modules/moc_mod_qt.c spl_modules/mod_qt.c

spl_modules/mod_fann.c: splrun spl_modules/gen_fann.spl spl_modules/mod_array.so spl_modules/mod_system.so
	./splrun -M spl_modules -e -pinfiles="$$( echo '#include <fann.h>' | $(CC) $(CFLAGS) $(shell pkg-config --cflags fann 2> /dev/null) -E - | grep '^#' | cut -f2 -d'"' | \
		sort -u | grep '/fann[._]' | tr '\n' ' '; )" spl_modules/gen_fann.spl > spl_modules/mod_fann.c.new
	mv spl_modules/mod_fann.c.new spl_modules/mod_fann.c

spl_modules/mod_gl.c: splrun spl_modules/gen_gl.spl spl_modules/mod_array.so spl_modules/mod_file.so
	./splrun -M spl_modules -e -p srcfile="$(shell CC='$(CC)' CXX='$(CXX)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' sh syscheck.sh opengl_file)" spl_modules/gen_gl.spl > spl_modules/mod_gl.c.new
	mv spl_modules/mod_gl.c.new spl_modules/mod_gl.c

%.splh: %.splb splb2splh.sh
ifeq ($(BUILDING_FOR_MINGW),0)
	sh splb2splh.sh $< > $@.new
	mv $@.new $@
else
	sh splb2splh.sh $< > $@.new
	mv $@.new $@
endif

%.splb: %.spl $(HOST_SPLRUN)
ifeq ($(BUILD_WITH_DEBUG),1)
	./$(HOST_SPLRUN) -N -e -x $@ $<
else
	./$(HOST_SPLRUN) -N -x $@ $<
endif

splrun: splrun.o $(SPL_LIBS)
	$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@

host_splrun: splrun.c $(patsubst %.o,%.c,$(SPL_OBJS)) spl_op.o
	$(HOST_CC) -std=gnu99 -Wall splrun.c $(patsubst %.o,%.c,$(SPL_OBJS)) -lm -ldl -o $@

webspl.cgi: webspl.o webspl_common.o spl_modules/mod_cgi.o $(SPL_LIBS)
	$(CC) $(LDFLAGS) webspl_common.o spl_modules/mod_cgi.o $< $(patsubst -lspl,$(SPL_OBJS),$(LDLIBS)) -o $@

webspld: webspld.o webspl_common.o httpsrv.o spl_modules/mod_cgi.o $(SPL_LIBS)
	$(CC) $(LDFLAGS) webspl_common.o httpsrv.o spl_modules/mod_cgi.o $< $(patsubst -lspl,$(SPL_OBJS),$(LDLIBS)) -o $@

libspl.a: $(SPL_OBJS)
	rm -f $@
	ar qc $@ $^
ifeq ($(BUILDING_FOR_IRIX),0)
	ranlib $@
endif

spl.dll: $(SPL_OBJS)
	$(CC) $(LDFLAGS) -shared $^ $(DLL_LIBS) -o $@

spl_op.c: spl.h
	awk 'BEGIN{							\
		print "#include \"spl.h\"";				\
		print "const struct spl_asm_op spl_ops[] = {" }		\
	    /^#define SPL_OP_/{						\
		gsub("SPL_OP_", "");					\
		optype=0; q="'\''";					\
		if ($$5 == "JUMP")      optype="J";			\
		if ($$5 == "BRANCH")    optype="B";			\
		if ($$5 == "CONDIT")    optype="C";			\
		if ($$5 == "ENDBRANCH") optype="E";			\
		if ($$5 == "UNARYOP")   optype="1";			\
		if ($$5 == "BINARYOP")  optype="2";			\
		if ($$5 == "STATICOP")  optype="S";			\
		print "\t{ \"" $$2 "\",\t"$$3 ",\t" q optype q " }," }	\
	    END{							\
		print "{ 0, 0, 0 }";					\
		print "};"; }' $< > $@.new
	mv $@.new $@

spl-config: spl-config.templ
	sed -e 's;@CFLAGS@;-I$(includedir);' \
	    -e 's;@MODDIR@;$(splmod_libdir);' \
	    -e 's;@LDFLAGS@;$(subst $(shell pwd),$(libdir),$(LDFLAGS));' \
	    -e 's;@LDLIBS@;$(subst $(shell pwd),$(libdir),$(LDLIBS));' \
	        < spl-config.templ > spl-config.new
	chmod +x spl-config.new
	mv spl-config.new spl-config

spldoc: all
	rm -rf spldoc; mkdir -p spldoc
	@for mod in $$( ls spl_modules/mod_*.spl spl_modules/mod_*.c builtins.c | cut -f1 -d. | sort -u; ); do \
		x="./splrun -M spl_modules -pinfile=$$( ls $$mod.spl $$mod.c 2> /dev/null | \
			tr '\n' , ) -poutdir=spldoc spldoc.spl"; \
		echo $$x; eval $$x || exit 1; \
	done
	./splrun -pinfile=$$( { ls -f README INSTALL README.LANG README.WEBSPL spldoc/builtins.txt; \
			ls spldoc/*.txt | grep -vx spldoc/builtins.txt; echo README.API; } | tr '\n' ','; ) \
		-ptitle='SPL Reference Manual http://www.clifford.at/spl/' \
		-pauthor="Clifford Wolf" -poutfile=manual.tex -M spl_modules txt2tex.spl
	echo '<html><head><title>SPL Module Documentation: Index</title>' > spldoc/index.new
	echo '<style type="text/css"><!-- a { text-decoration:none; } --></style>' >> spldoc/index.new
	echo '</head><body bgcolor="#dddddd"><h1>SPL Module Documentation: Index</h1>' >> spldoc/index.new
	awk '/ BEGIN / { idx=1; print "<hr>"; } idx { print; } / END / { idx=0; }' spldoc/*.html >> spldoc/index.new
	echo '<hr><table width="100%"><tr><td>Generated by SPLDOC.</td><td align="right">' >> spldoc/index.new
	echo '<a href="http://www.clifford.at/spl/">http://www.clifford.at/spl/</a>' >> spldoc/index.new
	echo '</td></tr></table></body></html>' >> spldoc/index.new
	mv spldoc/index.new spldoc/index.html

extfileslist:
	make clean
	strace -ff -o extfileslist.strace -e file make test
	set -e; grep -v ' = -1 ' extfileslist.strace* | cut -f2 -d'"' -s | egrep -v "^([^/]|/proc|/tmp|/etc|/dev|/sys|`pwd -P`)" | sort -u | while read fn; do [ -f "$$fn" ] && echo "$$(cd $${fn%/*} && pwd -P)/$${fn##*/}"; done > extfileslist.txt; rm -f extfileslist.strace*
	if [ -d /var/adm/flists ]; then sed 's,^/,,' < extfileslist.txt | grep '\.h$' | grep -Ff - -lr /var/adm/flists | cut -f5 -d/ | sort -u | egrep -v '^(glibc|gcc|linux)' | fmt | sed 's,^,    ,'; fi
	@echo "External files list written to 'extfileslist.txt'."

GNUmakefile.deps:
ifeq ($(BUILDING_FOR_CYGWIN)$(BUILDING_FOR_MINGW)$(BUILDING_FOR_MACOSX)$(BUILDING_FOR_BSD)$(BUILDING_FOR_IRIX),00000)
	@echo "Recreating $@ ..."
	@sh make-deps.sh $(CC) $(CFLAGS)
	@echo "Recreating ABI checksum ..."
	@sh make-abick.sh
endif

clean: compiler.c
	rm -rf *.o */*.o examples/c-api-test[0-9] examples/c-api-test3.splb
	rm -rf libspl.a core spl_op.c webspl_cache/ apache.pid gmon.out
	rm -rf spl_modules/*.so spl_modules/*.splb spl_modules/*.splh
	rm -rf examples/*.tmp examples/*.exe *.exe examples/spl.dll splrun
	rm -rf spl-config core.* */core */core.* vgcore.* manual.log
	rm -rf spl_modules/*.dll spl.dll y.output y.tab.c webspld spldoc
	rm -rf manual.toc manual.aux manual.tex manual.pdf manual.dvi
	rm -rf manual.ps moddir.c apache_error.log webspl.cgi host_splrun
	rm -rf spl_modules/moc_mod_qt.c extfileslist.* sha1_test config.cache
	rm -rf spl_modules/mod_fann.c spl_modules/mod_gl.c

install: all
	$(INSTALL) -d $(DESTDIR)$(bindir)
	$(INSTALL) -d $(DESTDIR)$(libdir)
	$(INSTALL) -d $(DESTDIR)$(includedir)
	$(INSTALL) -d $(DESTDIR)$(cgibin_libdir)
	$(INSTALL) -d $(DESTDIR)$(splmod_libdir)
	$(INSTALL) -d $(DESTDIR)$(datadir)
	$(INSTALL) splrun $(DESTDIR)$(bindir)
ifeq ($(BUILDING_FOR_MINGW),0)
	$(INSTALL) webspld $(DESTDIR)$(bindir)
endif
	$(INSTALL) webspl.cgi $(DESTDIR)$(cgibin_libdir)
ifeq ($(BUILDING_FOR_CYGWIN)$(BUILDING_FOR_MINGW),00)
	$(INSTALL) -m 644 libspl.a $(DESTDIR)$(libdir)
	$(INSTALL) $(filter %.so,$(MODULES)) $(DESTDIR)$(splmod_libdir)
else
	$(INSTALL) spl.dll $(DESTDIR)$(libdir)
	$(INSTALL) $(filter %.dll,$(MODULES)) $(DESTDIR)$(splmod_libdir)
endif
	$(INSTALL) -m 644 $(filter %.splb,$(MODULES)) $(DESTDIR)$(splmod_libdir)
	$(INSTALL) -m 644 spl.h $(DESTDIR)$(includedir)
ifeq ($(BUILDING_FOR_MINGW),0)
	$(INSTALL) -d $(DESTDIR)$(datadir)/aclocal
	$(INSTALL) -m 644 ac-spl.m4 $(DESTDIR)$(datadir)/aclocal/spl.m4
	$(INSTALL) spl-config $(DESTDIR)$(bindir)
endif
	sh addline.sh $(DESTDIR)$(splmod_libdir)/moddir.list '/usr/lib/spl_modules'
	sh addline.sh $(DESTDIR)$(splmod_libdir)/moddir.list '/usr/local/lib/spl_modules'
	sh addline.sh $(DESTDIR)$(splmod_libdir)/moddir.list '/opt/*/lib/spl_modules'

uninstall:
	rm -f $(DESTDIR)$(bindir)/splrun
ifeq ($(BUILDING_FOR_MINGW),0)
	rm -f $(DESTDIR)$(bindir)/webspld
endif
	rm -f $(DESTDIR)$(cgibin_libdir)/webspl.cgi
ifeq ($(BUILDING_FOR_CYGWIN)$(BUILDING_FOR_MINGW),00)
	rm -f $(DESTDIR)$(libdir)/libspl.a
	rm -f $(addprefix $(DESTDIR)$(splmod_libdir)/,$(notdir $(filter %.so,$(MODULES))))
else
	rm -f $(DESTDIR)$(libdir)/spl.dll
	rm -f $(addprefix $(DESTDIR)$(splmod_libdir)/,$(notdir $(filter %.dll,$(MODULES))))
endif
	rm -f $(addprefix $(DESTDIR)$(splmod_libdir)/,$(notdir $(filter %.splb,$(MODULES))))
	rm -f $(DESTDIR)$(splmod_libdir)/moddir.list
	rm -f $(DESTDIR)$(includedir)/spl.h
ifeq ($(BUILDING_FOR_MINGW),0)
	rm -f $(DESTDIR)$(datadir)/aclocal/spl.m4
	rm -f $(DESTDIR)$(bindir)/spl-config
endif

.PHONY: all showconfig c-api-tests test clean extfileslist spldoc


#### additional dependencies ####
ifeq ($(filter clean,$(MAKECMDGOALS)),)
include GNUmakefile.deps
endif
