# Copyright 2012-2024, Alexander Shibakov
# This file is part of SPLinT
#
# SPLinT 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 of the License, or
# (at your option) any later version.
#
# SPLinT 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 SPLinT.  If not, see <http://www.gnu.org/licenses/>.
docs:				splint.pdf

include ../makefile.inc

tables:				${SPLINT_PTABLES} ${SPLINT_LTABLES}

bdout bbout bgout \
bfout:b%out:			mkeparser.c b%.c
				${CC} ${BISON_STATE} -DPARSER_FILE=\"$(lastword $^)\" -DYYPARSE_PARAMETERS= -o $@ $<

bd.yy bg.yy \
bb.yy bf.yy:b%.yy:		bo.u bo.m
				${CTANGLE} $<

bd.yx bg.yx \
bb.yx bf.yx:%.yx:           	%.yy
				${BRACK} --replace-only --bison-link=bo.m $*.yy $*.yx

bd.y bg.y \
bb.y bf.y:%.y:			%.yx
				cp -f $^ $@

byytab.tex gyytab.tex \
dyytab.tex fyytab.tex:\
%yytab.tex:			b%out
				${SPLINT_DRIVER_DIR}/$< --optimize-actions $@

ltab.tex:			ltout
				${SPLINT_DRIVER_DIR}/$< --optimize-actions $@

ltout:				mkscanner.c lo_states.h lo.c
				${CC} -DLEXER_FILE=\"$(lastword $^)\" -o $@ $<

lo.ll: %.ll:			%.x
				${CTANGLE} $< && rm $(patsubst %.x, %.c, $^)

fil.ll:				so.x
				${CTANGLE} $< && rm $(patsubst %.x, %.c, $^)

fip.yy rep.yy rap.yy ddp.yy:	fo.x
				${CTANGLE} $< && rm $(patsubst %.x, %.c, $^)

# flex parser

fil.c:				fil.l
				${FLEX} -o $@ $<

fil_out:			mkscanner.c fil_states.h fil.c
				${CC} -DLEXER_FILE=\"$(lastword $^)\" -o $@ $<

filtab.tex:			fil_out
				${SPLINT_DRIVER_DIR}/$< --optimize-actions --optimize-tables $@

# state parsing for the \flex\ input scanner

fil_states.h:			so.tex ssfstab.tex ddptab.tex ${SPLINT_ROOT}tex/grabstates.sty
				@echo "Generating state list for the flex lexer ..."
				@${PDFTEX} $<

fip.c rep.c rap.c ddp.c:%.c:	%.y
				${BISON} -o $@ $<

fip_out rap_out \
ddp_out rep_out:%_out:		mkeparser.c %.c
				${CC} ${BISON_STATE} -DPARSER_FILE=\"$(lastword $^)\" -DYYPARSE_PARAMETERS= -o $@ $<

fiptab.tex raptab.tex \
ddptab.tex reptab.tex:%tab.tex:	%_out
				${SPLINT_DRIVER_DIR}/$< --optimize-actions --optimize-tables $@

so.tex:				so.x
				${CWEAVE} $<

fo.tex:				fo.x
				-${CWEAVE} $<

fo.tok:				fo.tex ltab.tex dyytab.tex bo.tok
				@echo "Generating token equivalences for flex input parser ..."
				@${TEX} ${MODEBOOTSTRAP} \\input $<

lo.c:				lo.l
				${FLEX} -o $@ $<

mkscanner.c mkeparser.c: \
%.c:				%.w
				${CTANGLE} $<

# bootstrap flex parser

ssfs.ll:			so.x
				${CTANGLE} $< && rm $(patsubst %.x, %.c, $^)

ssfs.c:				ssfs.l
				${FLEX} -o $@ $<

ssfs_out:			mkscanner.c ssfs.c
				${CC} -DLEXER_FILE=\"$(lastword $^)\" -o $@ $<

ssfstab.tex:			ssfs_out
				${SPLINT_DRIVER_DIR}/$< --optimize-actions --optimize-tables $@

# name parser 

smallp_out:			mkeparser.c small_parser.c
				${CC} ${BISON_STATE} -DPARSER_FILE=\"$(lastword $^)\" -DYYPARSE_PARAMETERS= -o $@ $<

smalll_out:			mkscanner.c small_lexer.c
				${CC} -DLEXER_FILE=\"$(lastword $^)\" -o $@ $<

small_tab.tex:			smallp_out
				${SPLINT_DRIVER_DIR}/$< --optimize-actions $@

small_dfa.tex:			smalll_out
				${SPLINT_DRIVER_DIR}/$< --optimize-actions $@

small_parser.yy \
small_lexer.ll:			np.x
				@${CTANGLE} $<

bo.tex:				bo.x
				-${CWEAVE} -x $< 1>/dev/null

splint.tex \
splint.idx \
splint.scn:			splint.x bo.x lo.x fo.x so.x np.x common.w bs.w \
				fk.w philosophy.w checklists.w references.w alphas.hx
				-${CWEAVE} $< 1>/dev/null

alphas.hx:
				@${MISCCW} --alpha-list --alpha-length=1 $@

bo.tok:				bo.tex ltab.tex byytab.tex
				@echo "Making token equivalence tables for the bison parser ..."
				@${TEX} ${MODEBOOTSTRAP} \\input $< #1>/dev/null

splint.gdx splint.aux:		${SPLINT_DOC_PREREQS_XREF}
				@echo "Making the bison and TeX indices ..."
				@${PDFTEX} splint.tex #1>/dev/null

# remove the implicit rule before building the main index

%.gdy:				%.gdx

splint.gdy:			splint.gdx
				${BINDX} --fine $^ $@

splint.pdf: %.pdf:		${SPLINT_DOC_PREREQS_XREF} %.gdy %.aux
				@echo "Generating SPLinT documentation (splint.pdf) ..."
				while test "`diff --new-file splint.pdf /tmp/splint.pdf`"; do \
					echo "Files differ" && mv splint.pdf /tmp/; \
					${PDFTEX} \\input $*.tex && touch $*.gdy && touch $*.pdf; \
				done

splint.dvi: %.dvi:		${SPLINT_DOC_PREREQS_XREF} %.gdy
				@${TEX} $*.tex && touch $*.gdy && touch $*.dvi && rm $*.ftn

# state parsing

lo.tex:				lo.x
				${CWEAVE} $<

lo_states.h:			lo.tex ssfstab.tex ddptab.tex ${SPLINT_ROOT}tex/grabstates.sty
				@echo "Generating state list for the bison lexer ..."
				@${PDFTEX} $<

# clean will erase all automatically generated files in the current directory

clean:				clean_core
				-rm -f ctablesout b?out ltout smallp_out /tmp/splint.pdf \
				smalll_out ssfs_out fil_out fip_out rep_out rap_out ddp_out

include ${SPLINT_ROOT}makefile.loc

# since bg.yy is not an intermediate file in examples/symbols/Makefile, repeated 'make all'
# remakes bg.yy thereby forcing make to update byytab.tex, etc., which results in remaking
# of bo.tok, lo.tex, eventually leading to remaking of splint.pdf;
# the special target below tells make to treat bg.yy as if it were not an intermediate file

.PRECIOUS:			%.yy bo.tok fo.tok %.ll b%.y splint.gdx

# the files below appear as targets but are really intermediaries for other files

.INTERMEDIATE:			smallp_out smalll_out ssfs_out ltout fil_out \
				fip_out rep_out rap_out ddp_out splint.gdx