# select alternative zmalloc schemes
# commented out: use the slab-like original zmalloc (default)
# _native: use malloc()/free() - useful for memory leak hunting
# _safemalloc: use auto-cleanup malloc - useful if malloc() is preferred over slabs but the context should be cleaned up
#ZMALLOC_FLAVOR = _native

# install these headers in $(INCDIR)/libmawk/
IHEADERS=libmawk.h mawk.h init.h code.h files.h memory.h zmalloc.h \
         symtype.h nstd.h types.h array.h sizes.h num.h num_int.h \
         num_double.h conf.h bi_vars.h vio.h cell.h repl.h array_orig.h \
         array_environ.h array_generic.h vio_orig.h vio_fifo.h zfifo.h \
         execute.h

MAWKMAN = $(MANDIR)/lmawk.$(MANEXT)

VIO_OBJ = files_children.o vio_orig.o

# common objects
CO=memory.o hash.o code.o vars.o da_bin.o da_common.o da_bin_helper.o error.o \
   bi_vars.o bi_funct_common.o array.o array_orig.o array_generic.o \
   field_common.o re_cmpl.o zmalloc$(ZMALLOC_FLAVOR).o fin_common.o files.o matherr.o fcall.o \
   version.o missing.o math_wrap.o cast.o cell.o scancode.o str.o \
   array_environ.o \
   $(VIO_OBJ) $(NUM_OBJ)

# parser objects
PO=parse.o scan.o da_text.o code_dump.o kw.o jmp.o

# execute objects
EO=execute.o bi_funct.o print.o debug.o field_exec.o split.o

REXP_O=rexp/rexp.o rexp/rexp0.o rexp/rexp1.o rexp/rexp2.o\
    rexp/rexp3.o

REXP_C=rexp/rexp.c rexp/rexp0.c rexp/rexp1.c rexp/rexp2.c\
    rexp/rexp3.c

# objects required for the buffer-vio
O_VIO_BUF=zfifo.o vio_fifo.o

# lib object
LO_ALL=$(CO) $(EO) $(PO) init.o libmawk.o fin_exec.o $(REXP_O) $(O_VIO_BUF)

# original all-in-one lmawk executable objects
O = main.o $(CO) $(EO) $(PO) init.o fin_exec.o viohack.o $(REXP_O)

# split shared object
O_COMP = bi_funct_dummy.o init.o print_dummy.o fin_comp.o $(PO) $(REXP_O)
O_EXEC = init_nocomp.o fin_exec.o $(O_VIO_BUF) $(EO) $(REXP_O)

# split executables
OBJ_COMP = main-comp.o viohack.o $(O_COMP) $(CO)
OBJ_EXEC = main-exec.o viohack.o  $(O_EXEC) $(CO)

all: mawk_and_test

include Makefile.conf

BINS = lmawk lmawk-comp lmawk-exec \
       libmawk.so libmawk.a \
       libmawk_common.so libmawk_comp.so libmawk_exec.so \
       regression/re_test/re_test

mawk_and_test : $(BINS)

libmawk.so: $(LO_ALL)
	$(CC) -shared $(LDFLAGS_RDYNAMIC) $(LDFLAGS) $(LDFLAGS_SO) -o libmawk.so $(LO_ALL) $(MATHLIB)

libmawk_comp.so: $(O_COMP)
	$(CC) -shared $(LDFLAGS_RDYNAMIC) $(LDFLAGS) -o libmawk_comp.so $(O_COMP) $(MATHLIB)

libmawk_exec.so: $(O_EXEC)
	$(CC) -shared $(LDFLAGS_RDYNAMIC) $(LDFLAGS) -o libmawk_exec.so $(O_EXEC) $(MATHLIB)

libmawk_common.so: $(CO)
	$(CC) -shared $(LDFLAGS_RDYNAMIC) $(LDFLAGS) -o libmawk_common.so $(CO) $(MATHLIB)

libmawk.a: $(LO_ALL)
	ar rvu $@ $(LO_ALL)
	ranlib $@

lmawk : $(O)
	$(CC) $(CFLAGS) -o lmawk $(O) $(MATHLIB)

lmawk-comp : $(OBJ_COMP)
	$(CC) $(CFLAGS) -o lmawk-comp $(OBJ_COMP) $(MATHLIB)

lmawk-exec : $(OBJ_EXEC)
	$(CC) $(CFLAGS) -o lmawk-exec $(OBJ_EXEC) $(MATHLIB)

main-comp.o: main.c
	$(CC) -c $(CFLAGS) -DMAWK_NO_EXEC=1 main.c -o main-comp.o

main-exec.o: main.c
	$(CC) -c $(CFLAGS) -DMAWK_NO_COMP=1 main.c -o main-exec.o


scancode.c :  makescan.c  scan.h
	$(CC) $(CFLAGS) -o makescan.exe  makescan.c
	rm -f scancode.c
	./makescan.exe > scancode.c
	rm makescan.exe


# compile regression tests implemented in C
# these rules are not in Makefiles under regression/, so
# all the $(CC) and $(CFLAGS) work without any extra hassle
RE_TEST_O = regression/re_test/re_test.o rexp/rexp.o rexp/rexp0.o rexp/rexp1.o rexp/rexp2.o rexp/rexp3.o zmalloc$(ZMALLOC_FLAVOR).o memory.o
regression/re_test/re_test: $(RE_TEST_O)
	$(CC) -o regression/re_test//re_test $(RE_TEST_O)

regression/re_test/re_test.o: regression/re_test/re_test.c
	$(CC) -c $(CFLAGS) regression/re_test/re_test.c -o regression/re_test/re_test.o

### misc: installation, clean, etc. ###

test: all
	cd regression && make

PWD=`pwd`

install_ :  lmawk libmawk.so
	$(MKDIR) $(BINDIR)
	$(MKDIR) $(MANDIR)
	$(MKDIR) $(MAN3DIR)
	$(MKDIR) $(MAN7DIR)
	$(MKDIR) $(INCDIR)
	$(MKDIR) $(LIBARCHDIR)
	$(CP) $(PWD)/lmawk $(BINDIR)/lmawk
	$(CHMODX)  $(BINDIR)/lmawk
	$(CP)  $(PWD)/man/lmawk.1  $(MAWKMAN)
	$(CP)  $(PWD)/man/libmawk_append_input.3libmawk         $(MAN3DIR)/libmawk_append_input.3libmawk
	$(CP)  $(PWD)/man/libmawk_call_function.3libmawk        $(MAN3DIR)/libmawk_call_function.3libmawk
	$(CP)  $(PWD)/man/libmawk_cell_destroy.3libmawk         $(MAN3DIR)/libmawk_cell_destroy.3libmawk
	$(CP)  $(PWD)/man/libmawk_get_var.3libmawk              $(MAN3DIR)/libmawk_get_var.3libmawk
	$(CP)  $(PWD)/man/libmawk_initialize.3libmawk           $(MAN3DIR)/libmawk_initialize.3libmawk
	$(CP)  $(PWD)/man/libmawk_initialize_stage.3libmawk     $(MAN3DIR)/libmawk_initialize_stage.3libmawk
	$(CP)  $(PWD)/man/libmawk_register_function.3libmawk    $(MAN3DIR)/libmawk_register_function.3libmawk
	$(CP)  $(PWD)/man/libmawk_run_main.3libmawk             $(MAN3DIR)/libmawk_run_main.3libmawk
	$(CP)  $(PWD)/man/libmawk_set_cell.3libmawk             $(MAN3DIR)/libmawk_set_cell.3libmawk
	$(CP)  $(PWD)/man/libmawk_uninitialize.3libmawk         $(MAN3DIR)/libmawk_uninitialize.3libmawk
	$(CP)  $(PWD)/man/example.7libmawk                      $(MAN7DIR)/example.7libmawk
	$(CHMOD)  0644  $(MAWKMAN)
	$(CP) $(PWD)/libmawk.so $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3)
	rm $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2) $(LIBARCHDIR)/libmawk.so.$(SOVER1) 2>/dev/null ; true
	ln -s libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2)
	ln -s libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) $(LIBARCHDIR)/libmawk.so.$(SOVER1)
	ln -s libmawk.so.$(SOVER1) $(LIBARCHDIR)/libmawk.so
	for h in $(IHEADERS); do $(CP) $(PWD)/$$h $(INCDIR)/$$h; done
	$(CP) $(PWD)/../libmawk.h $(INCDIR)/../libmawk.h

uninstall:
	$(RM) $(BINDIR)/lmawk $(MAWKMAN) $(MAN3DIR)/libmawk_append_input.3libmawk $(MAN3DIR)/libmawk_call_function.3libmawk $(MAN3DIR)/libmawk_cell_destroy.3libmawk $(MAN3DIR)/libmawk_get_var.3libmawk $(MAN3DIR)/libmawk_initialize.3libmawk $(MAN3DIR)/libmawk_initialize_stage.3libmawk $(MAN3DIR)/libmawk_register_function.3libmawk $(MAN3DIR)/libmawk_run_main.3libmawk $(MAN3DIR)/libmawk_set_cell.3libmawk $(MAN3DIR)/libmawk_uninitialize.3libmawk $(MAN7DIR)/example.7libmawk $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2).$(SOVER3) $(LIBARCHDIR)/libmawk.so.$(SOVER1).$(SOVER2) $(LIBARCHDIR)/libmawk.so.$(SOVER1) $(LIBARCHDIR)/libmawk.so
	for h in $(IHEADERS); do $(RM) $(INCDIR)/$$h; done
	$(RM) $(INCDIR)/../libmawk.h

install:
	make install_ CP="cp"

linstall:
	make install_ CP="ln -s"



rexp/rexp.o: rexp/rexp.c
	$(CC) -c $(CFLAGS) -o rexp/rexp.o rexp/rexp.c

rexp/rexp0.o: rexp/rexp0.c
	$(CC) -c $(CFLAGS) -o rexp/rexp0.o rexp/rexp0.c

rexp/rexp1.o: rexp/rexp1.c
	$(CC) -c $(CFLAGS) -o rexp/rexp1.o rexp/rexp1.c

rexp/rexp2.o: rexp/rexp2.c
	$(CC) -c $(CFLAGS) -o rexp/rexp2.o rexp/rexp2.c

rexp/rexp3.o: rexp/rexp3.c
	$(CC) -c $(CFLAGS) -o rexp/rexp3.o rexp/rexp3.c

$(NUM_OBJ): $(NUM_SRC) num.h

init_nocomp.o: init_nocomp.c
	$(CC) -c $(CFLAGS) -o init_nocomp.o init_nocomp.c

init_nocomp.o: init.c


clean :
	rm -f *.o rexp/*.o $(BINS)
	cd regression && make clean

distclean :  clean
	rm -f defines.out maxint.out conf.h Makefile.conf

include Makefile.dep

depend:
	@echo "# Generated by \"make depend\"" > Makefile.dep
	gcc $(CFLAGS) -MM `echo $(LO_ALL) | sed "s/\.o/.c/g"` >> Makefile.dep

FORCE:
