#!/bin/sh
# $Id: pretzel-it,v 2.2 1998/12/03 10:58:39 felix Exp $
#----------------------------------------------------------------------

#
# pretzel-it  ---  transform input files into a pretzel prettyprinter
#
# (history at end)


# SYNOPSIS
#
#	pretzel-it [-iqvdnh] language ppname
#
#
# pretzel-it tries to produce a prettyprinter from the input files
# `language.ft' and `language.fg'. The prettyprinter is encapsulated in
# a minimal main program called `ppname'. It's usgage then is:
#
#     ppname <code >tex-code
#
# pretzel-it will leave the C code of the prettyprinter in the current
# directory. If the -i option is given, all intermediate files, such
# as the flex and Bison files, as well as the object code of the C
# files are left there too.
#
# Filenames of the C code are: language.lex.c, language.tab.c and
# ptokdefs.h for the token header.
#
# pretzel-it expects to find the `pretzel' program in your PATH. Also
# it looks for the pretzel library and include files in the directories
# specified by the environment variables PRETZEL_LIBDIR and PRETZEL_INCLUDE.
#
#
# OPTIONS
#
#       -i     don't remove intermediate products (flex/Bison source
#              and prettyprinter object code)
#       -q     run quietly
#       -v     verbose, print commands before invoking (for debugging)
#	-d     turn prettyprinter debugging features on by default,
#              produce an .output file for detailed diagnosis of parser
#              (for debugging the prettyprinting grammar)
#       -h     print help message
#
#       -n     noweb option: instead of producing a standalone
#              prettyprinter `ppname' it will produce a noweb
#              prettyprinting filter `ppname' that can be used as
#              additional filter with noweb's -filter option
#              (and LaTeX as typesetter). Without the -i option
#              it will remove _all_ intermediates and leave only the
#              filter in the current directory.
#
#
# CAVEATS:
#
#    pretzel-it is very simple and will only produce default
#    prettyprinters. Use the specialized Makefile if you want to do
#    special things like using several prettyprinters within one
#    program.
#
#    The noweb option is new and very experimental.
#
#
# IMPLEMENTATION NOTES
#
#    After checking the arguments, the commands that are used to
#    invoke flex, Bison and the compiler are pieced together and then
#    executed.
#
#    The noweb option builds a normal prettyprinter but links it with
#    a different main function and removes all intermediates.
#

cmd=`basename $0`
usage()
{
	echo "usage: $cmd [-inqvdh] language ppname"	>&2
	echo "use -h option for full usage"		>&2
	exit 1
}

full_usage()
{
	echo "usage: $cmd [-inqvdh] language ppname"		>&2
	echo "options: "					>&2
	echo " -i  don't remove intermediate products"		>&2
	echo " -q  run quietly"					>&2
	echo " -v  verbose, print commands before invoking"	>&2
	echo " -d  turn prettyprinter debugging features on"	>&2
	echo " -h  print this help message"			>&2
	echo " -n  (experimental) noweb option"			>&2
	exit 0
}

envnote()
{
	echo "you need to set the environment variables" >&2
	echo "PRETZEL_LIBDIR and PRETZEL_INCLUDE to the" >&2
	echo "pretzel library and include directories." >&2
	exit 1
}


# normalize and check arguments:

cleanup_intermediates=true
run_noisy=true
verbose_mode=''
build_debug_pp=''
noweb_mode=''

while getopts 'iqvdnh' option
  do   case "$option" in
         i)  cleanup_intermediates=''
             ;;
         q)  run_noisy=''
             ;;
         v)  verbose_mode=true
             ;;
	 d)  build_debug_pp=true
	     ;;
         n)  noweb_mode=true
             ;;
         h)  full_usage
             ;;
         # add more options here
         *)  usage
             ;;
       esac
  done

# number of remaining arguments has to be 2:
shift `expr $OPTIND - 1`
test $# -eq 2 || usage

# check if environment variables have been set

test  $PRETZEL_LIBDIR || export PRETZEL_LIBDIR=/usr/lib/pretzel # envnote
test  $PRETZEL_INCLUDE || export PRETZEL_INCLUDE=/usr/include/pretzel # envnote

# -----------------------------------------------------------------
# Build commands that are invoked by the script:

pretzel_command="pretzel -q $1"

bison_command="bison -d $1.y -o $1.tab.c"

# -v flag produces the .output file for detailed diagnosis

debug_bison_command="bison -v -d $1.y -o $1.tab.c"

after_bison="mv $1.tab.h ptokdefs.h"

flex_command="flex -t $1.l > $1.lex.c"

# don't need link commands on command line

compile_flex="g++ -c -I$PRETZEL_INCLUDE -g $1.lex.c"

compile_bison="g++ -c -I$PRETZEL_INCLUDE -g $1.tab.c"


# note that the order of the arguments is important for portability

link_command="g++ $1.lex.o $1.tab.o $PRETZEL_LIBDIR/plainpp.o \
  -I$PRETZEL_INCLUDE -L$PRETZEL_LIBDIR -lpretzel -g -o $2"

# this is used if you're building a prettyprinter for debugging
debug_link_command="g++ $1.lex.o $1.tab.o $PRETZEL_LIBDIR/plaindpp.o \
  -I$PRETZEL_INCLUDE -L$PRETZEL_LIBDIR -lpretzel -g -o $2"

#

cleanup_command="rm -f $1.l $1.y $1.lex.o $1.tab.o"


# special noweb command (invoked instead of the normal link commands):

noweb_link_command="g++ $1.lex.o $1.tab.o $PRETZEL_LIBDIR/nowebpretzelpp.o \
  -I$PRETZEL_INCLUDE -L$PRETZEL_LIBDIR -lpretzel -g -o $2"

# currently the same as noweb_link_command:
noweb_debug_link_command="g++ $1.lex.o $1.tab.o $PRETZEL_LIBDIR/nowebpretzelpp.o \
  -I$PRETZEL_INCLUDE -L$PRETZEL_LIBDIR -lpretzel -g -o $2"

noweb_cleanup_command="rm -f $1.l $1.y $1.lex.o $1.tab.o $1.lex.c	\
	$1.tab.c ptokdefs.h"


# ------------------------------------------------------------------
# now go to work: let's run the different programs on the files one
# at a time and be sure to bail out when one of them returns with an
# error.

# now go to work: run pretzel on the input files.

if [ "$run_noisy" ]
   then echo "starting to pretzel..."
fi

if [ "$verbose_mode" ]
   then echo $pretzel_command
fi
eval $pretzel_command || exit 1

# now run flex and Bison on them and try to compile...

if [ "$run_noisy" ]
   then echo "preprocessing..."
fi
if [ "$verbose_mode" ]
   then echo $bison_command
fi
if [ "$build_debug_pp" ]
   then eval $debug_bison_command || exit 1
else
   eval $bison_command  || exit 1
fi
eval $after_bison

if [ "$verbose_mode" ]
   then echo $flex_command
fi
eval $flex_command || exit 1

if [ "$run_noisy" ]
   then echo "processing .ft file..."
fi
if [ "$verbose_mode" ]
   then echo $compile_flex
fi
eval $compile_flex || exit 1

if [ "$run_noisy" ]
   then echo "processing .fg file..."
fi
if [ "$verbose_mode" ]
   then echo $compile_bison
fi
eval $compile_bison || exit 1


if [ "$build_debug_pp" ]
then
  if [ "$noweb_mode" ]
  then

    # case 1: debug and noweb

    if [ "$run_noisy" ]
       then echo "building noweb filter $2 (turning debug features on)..."
    fi
    if [ "$verbose_mode" ]
       then echo $noweb_debug_link_command
    fi
    eval $noweb_debug_link_command || exit 1

  else

    # case 2: debug and not noweb

    if [ "$run_noisy" ]
       then echo "building prettyprinter $2 (turning debug features on)..."
    fi
    if [ "$verbose_mode" ]
       then echo $debug_link_command
    fi
    eval $debug_link_command || exit 1
  fi
else
  if [ "$noweb_mode" ]
  then

    # case 3: normal noweb

    if [ "$run_noisy" ]
       then echo "building noweb filter $2..."
    fi
    if [ "$verbose_mode" ]
       then echo $noweb_link_command
    fi
    eval $noweb_link_command || exit 1
  else

    # case 4: normal

    if [ "$run_noisy" ]
       then echo "building prettyprinter $2..."
    fi
    if [ "$verbose_mode" ]
       then echo $link_command
    fi
    eval $link_command || exit 1
  fi
fi

#
if [ "$cleanup_intermediates" ]
then
  if [ "$noweb_mode" ]
  then
    if [ "$run_noisy" ]
       then echo "cleaning up and leaving only noweb filter..."
    fi
    if [ "$verbose_mode" ]
       then echo $noweb_cleanup_command
    fi
    eval $noweb_cleanup_command
  else               # cleanup but not in noweb mode
    if [ "$run_noisy" ]
       then echo "cleaning up..."
    fi
    if [ "$verbose_mode" ]
       then echo $cleanup_command
    fi
    eval $cleanup_command
  fi
fi


if [ "$run_noisy" ]
   then echo "done."
fi


#======================================================================
#
# $Log: pretzel-it,v $
# Revision 2.2  1998/12/03 10:58:39  felix
# can use standard search paths for PRETZEL_XXX if variables are
# not set (thanks to I think Dave Wilson).
#
# Revision 2.1  1998/04/25 08:03:09  gaertner
# produces .output file from bison when -d option is given for
# detailed grammar diagnosis in the presence of conflicts.
#
# Revision 2.0  1996/12/16 17:35:52  gaertner
# release 2.0
#
# Revision 1.10  1996/11/14 18:13:23  gaertner
# noweb option should work now. Changes the text lines that are
# printed out to the screen because they show too many internals.
#
# Revision 1.9  1996/11/14  18:03:13  gaertner
# Added noweb option. Added -h option.
#
# Revision 1.8  1996/09/17  13:46:37  gaertner
# Changed CC to g++ in compiler lines. Also added the `cleanup' option.
#
# Revision 1.7  1996/03/22  10:10:11  gaertner
# added -d option for grammar debugging.
#
# Revision 1.6  1996/03/21  11:08:29  gaertner
# Corrected argument checking and enhanced documentation.
#
# Revision 1.5  1996/02/06  19:24:59  gaertner
# Added new options -i -q -v. Bails out when an error is encountered.
# Invoked commands are configured in one place to ease maintenance.
#
# Revision 1.4  1996/02/06  17:28:07  gaertner
# Version before re-writing the tool.
#
# Revision 1.3  1995/08/30  17:51:57  gaertner
# tex->lex in rm-line.
#
# Revision 1.2  1995/08/30  17:48:41  gaertner
# Moved link objects to the front of the compiler line. Some
# compilers need this.
#
# Revision 1.1  1995/08/30  17:45:49  gaertner
# Initial revision
#
#
