#!/bin/sh
# texi2dvi -- smartly produce DVI files from texinfo sources
#
# Copyright (C) 1992, 1993 Free Software Foundation.
#
# 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, 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, you can either send email to this
# program's author (see below) or write to:
#
#              Free Software Foundation, Inc.
#              59 Temple Place - Suite 330.
#              Boston, MA 02111-1307, USA. 
#
# Please send bug reports, etc. to friedman@prep.ai.mit.edu
# If possible, please send a copy of the output of the script called with
# the `--debug' option when making a bug report. 
#
# Version 0.3.2
# Last modified 31-Jan-93
#

# Please note that in the interest of general portability, some common
# bourne shell constructs were avoided because they weren't guaranteed to
# be available in some earlier implementations.  I've tried to make this as
# portable as possible. 
#
# Among the more interesting lossages I noticed with some bourne shells
# are:
#       1) Some don't have an `unset' builtin 
#       2) In some implementations the `shift' builtin can't take a
#          numerical argument. 

progname=`basename $0`

usage="Usage: ${progname} {-D} {-h} [file1] {file2} {...}
       {--debug} {--help}

   Options in braces are optional.  Those in brackets are required. 
"

if [ $# -eq 0 ]; then
   echo "${usage}" 1>&2;
   exit 1
fi

backup_extension=".bak"
texindex="texindex"
tex="tex"
bq="\`"  # To prevent hairy quoting and escaping later.
eq="'"
orig_pwd="`pwd`"

if [ "z${TEXINDEX}" != "z" ]; then
   texindex="${TEXINDEX}"
fi

if [ "z${TEX}" != "z" ]; then
   tex="${TEX}"
fi

# Save this so we can construct a new TEXINPUTS path for each file to be
# processed.
TEXINPUTS_orig="${TEXINPUTS}"
export TEXINPUTS

# Parse command line options

# "unset" option variables to make sure they weren't accidentally
# exported
debug=""

# If you add new commands be sure to change the wildcards below to make
# sure they are unambiguous (i.e. only match one possible long option)
# Be sure to show at least one instance of the full long option name to
# document what the long option is canonically called. 
while [ $# -gt 0 ]; do
   case z$1 in
      z-D | z--debug | z--d* )
         debug="t"
         shift
        ;;
      z-h | z--help | z--h* )
         echo "${usage}" 1>&2
         exit 1
        ;;
      z-- )
         shift
         break 
        ;;
      z-* )
         echo "${progname}: ${bq}${1}${eq} is not a valid option." 1>&2
         echo "" 1>&2
         echo "${usage}" 1>&2
         exit 1
        ;;
      * )
         break 
        ;;
   esac
done

# See if there are any command line args left (which will be interpreted as
# filename arguments)
if [ $# -eq 0 ]; then
   echo "${progname}: at least one file name is required as an argument." 1>&2
   echo "" 1>&2
   echo "${usage}" 1>&2
   exit 1
fi

test "z${debug}" = "zt" && set -x

# Texify files
for command_line_filename in "$@" ; do
   # Roughly equivalent to `dirname ...`, but more portable
   directory="`echo ${command_line_filename} | sed 's/\/[^\/]*$//'`"
   filename_texi="`basename ${command_line_filename}`"
   # Strip off the last extension part (probably .texinfo or .texi)
   filename_noext="`echo ${filename_texi} | sed 's/\.[^.]*$//'`"

   # If directory and file are the same, then it's probably because there's
   # no pathname component.  Set dirname to `.', the current directory.
   if [ "z${directory}" = "z${command_line_filename}" ]; then
      directory="."
   fi

   # Source file might @include additional texinfo sources.  Put `.' and
   # directory where source file(s) reside in TEXINPUTS before anything
   # else.  `.' goes first to ensure that any old .aux, .cps, etc. files in
   # ${directory} don't get used in preference to fresher files in `.'. 
   TEXINPUTS=".:${directory}:${TEXINPUTS_orig}"

   # "Unset" variables that might have values from previous iterations and
   # which won't be completely reset later.
   definite_index_files=""

   # See if file exists here.  If it doesn't we're in trouble since, even
   # though the user may be able to reenter a valid filename at the tex
   # prompt (assuming they're attending the terminal), this script won't be
   # able to find the right index files and so forth.
   if [ ! -r "${command_line_filename}" ]; then
      echo "${progname}: ${command_line_filename}: No such file or permission denied." 1>&2
      continue; 
   fi

   # Find all files having root filename with a two-letter extension,
   # determine whether they're really index files, and save them.  Foo.aux
   # is actually the cross-references file, but we need to keep track of
   # that too.
   possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`"
   for this_file in ${possible_index_files} ; do
      # If file is empty, forget it.  
      if [ ! -s "${this_file}" ]; then
         continue;
      fi

      # Examine first character of file.  If it's not a backslash or
      # single quote, then it's definitely not an index or xref file.
      first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`"
      if [ "${first_character}" = "\\" -o "${first_character}" = "'" ]; then
         definite_index_files="${definite_index_files} ${this_file}"
      fi
   done
   orig_index_files="${definite_index_files}"
   orig_index_files_sans_aux="`echo ${definite_index_files} \
                                | sed 's/'${filename_noext}'\.aux//;
                                       s/^[ ]*//;s/[ ]*$//;'`"

   # Now save copies of original index files so we have some means of
   # comparison later. 
   for index_file_to_save in ${orig_index_files} ; do
       cp "${index_file_to_save}" "${index_file_to_save}${backup_extension}"
   done

   # Run texindex on current index files.  If they already exist, and
   # after running TeX a first time the index files don't change, then
   # there's no reason to run TeX again.  But we won't know that if the
   # index files are out of date or nonexistent.
   if [ "${orig_index_files_sans_aux}" ]; then
      ${texindex} ${orig_index_files_sans_aux}
   fi

   if ${tex} ${command_line_filename} ; then		# TeX run first time
      definite_index_files=""
      # Get list of new index files
      possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`"
      for this_file in ${possible_index_files} ; do
         # If file is empty, forget it.
         if [ ! -s ${this_file} ]; then
            continue;
         fi

         # Examine first character of file.  If it's not a backslash or
         # single quote, then it's definitely not an index or xref file.
         first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`"
         if [ "${first_character}" = "\\" -o "${first_character}" = "'" ]; then
            definite_index_files="${definite_index_files} ${this_file}"
         fi
      done
      new_index_files="${definite_index_files}"
      new_index_files_sans_aux="`echo ${definite_index_files} \
                                  | sed 's/'${filename_noext}'\.aux//;
                                         s/^[ ]*//;s/[ ]*$//;'`"

      # If old and new list don't at least have the same file list, then one
      # file or another has definitely changed.  
      if [ "${orig_index_files}" != "${new_index_files}" ]; then
         index_files_changed_p=t
      else
         # File list is the same.  We must compare each file until we find a
         # difference.  
         index_files_changed_p=""
         for this_file in ${new_index_files} ; do
            # cmp -s will return nonzero exit status if files differ. 
            cmp -s "${this_file}" "${this_file}${backup_extension}"
            if [ $? -ne 0 ] ; then
               # We only need to keep comparing until we find *one* that
               # differs, because we'll have to run texindex & tex no
               # matter what. 
               index_files_changed_p=t
               break
            fi
         done
      fi

      # If index files have changed since TeX has been run, or if the aux
      # file wasn't present originally, run texindex and TeX again.
      if [ "${index_files_changed_p}" ] ; then
         retval=0
         if [ "${new_index_files_sans_aux}" ]; then
            ${texindex} ${new_index_files_sans_aux} 
            retval=$?
         fi
         if [ ${retval} -eq 0 ]; then
            ${tex} "${command_line_filename}"
         fi
      fi
   fi

   # Generate list of files to delete, then call rm once with the entire
   # list.  This is significantly faster than multiple executions of rm. 
   file_list=""
   for file in ${orig_index_files} ; do
       file_list="${file_list} ${file}${backup_extension}"
   done
   if [ "${file_list}" ]; then
      rm -f ${file_list}
   fi
done

#
# eof
#
