diff options
Diffstat (limited to 'contrib/gdiffmk/gdiffmk.sh')
-rw-r--r-- | contrib/gdiffmk/gdiffmk.sh | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/contrib/gdiffmk/gdiffmk.sh b/contrib/gdiffmk/gdiffmk.sh new file mode 100644 index 0000000..2473fb1 --- /dev/null +++ b/contrib/gdiffmk/gdiffmk.sh @@ -0,0 +1,367 @@ +#!@BASH_PROG@ +# Copyright (C) 2004-2020 Free Software Foundation, Inc. +# Written by Mike Bianchi <MBianchi@Foveal.com <mailto:MBianchi@Foveal.com>> +# Thanks to Peter Bray for debugging. + +# This file is part of the gdiffmk utility, which is part of groff. + +# groff 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. + +# groff 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, see <http://www.gnu.org/licenses/>. +# This file is part of GNU gdiffmk. + + +CMD=`basename $0` + +Usage () { + if test $# -gt 0 + then + echo >&2 "${CMD}: $@" + fi + echo >&2 "\ + +Usage: ${CMD} [ OPTIONS ] FILE1 FILE2 [ OUTPUT ] +Place difference marks into the new version of a groff/nroff/troff document. +FILE1 and FILE2 are compared, using 'diff', and FILE2 is output with +groff '.mc' requests added to indicate how it is different from FILE1. + + FILE1 Previous version of the groff file. '-' means standard input. + FILE2 Current version of the groff file. '-' means standard input. + Either FILE1 or FILE2 can be standard input, but not both. + OUTPUT Copy of FILE2 with '.mc' commands added. + '-' means standard output (the default). + If the shell's 'test' does not support option -ef, OUTPUT + can only be the standard output. + +OPTIONS: + -a ADDMARK Mark for added groff source lines. Default: '+'. + -c CHANGEMARK Mark for changed groff source lines. Default: '|'. + -d DELETEMARK Mark for deleted groff source lines. Default: '*'. + + -D Show the deleted portions from changed and deleted text. + Default delimiting marks: '[[' .... ']]'. + -B By default, the deleted texts marked by the '-D' option end + with an added troff '.br' command. This option prevents + the added '.br'. + -M MARK1 MARK2 Change the delimiting marks for the '-D' option. + + -x DIFFCMD Use a different diff(1) command; + one that accepts the '-Dname' option, such as GNU diff. + -s SEDCMD Use a different sed(1) command; + such as GNU sed. + --version Print version information on the standard output and exit. + --help Print this message on the standard error. +" + exit 255 +} + + +Exit () { + exitcode=$1 + shift + for arg + do + echo >&2 "${CMD}: $1" + shift + done + exit ${exitcode} +} + +# Usage: FileRead exit_code filename +# +# Check for existence and readability of given file name. +# If not found or not readable, print message and exit with EXIT_CODE. +FileRead () { + case "$2" in + -) + return + ;; + esac + + if test ! -f "$2" + then + Exit $1 "File '$2' not found." + fi + if test ! -r "$2" + then + Exit $1 "File '$2' not readable." + fi +} + + +# Usage: FileCreate exit_code filename +# +# Create the given filename if it doesn't exist. +# If unable to create or write, print message and exit with EXIT_CODE. +FileCreate () { + case "$2" in + -) + return + ;; + esac + + touch "$2" 2>/dev/null + if test $? -ne 0 + then + if test ! -f "$2" + then + Exit $1 "File '$2' not created; " \ + "Cannot write directory '`dirname "$2"`'." + fi + Exit $1 "File '$2' not writeable." + fi +} + +WouldClobber () { + case "$2" in + -) + return + ;; + esac + + # BASH_PROG is set to /bin/sh if bash was not found + if test "$HAVE_TEST_EF_OPTION" = "no" -a "$BASH_PROG" = "/bin/sh" + then + Exit 3 \ + "Your shell does support test -ef, [OUTPUT] can only be the" \ + "standard output." + else + if test "$1" -ef "$3" + then + Exit 3 \ + "The $2 and OUTPUT arguments both point to the same file," \ + "'$1', and it would be overwritten." + fi + fi +} + +ADDMARK='+' +CHANGEMARK='|' +DELETEMARK='*' +MARK1='[[' +MARK2=']]' + +RequiresArgument () { + # Process flags that take either concatenated or + # separated values. + case "$1" in + -??*) + expr "$1" : '-.\(.*\)' + return 1 + ;; + esac + + if test $# -lt 2 + then + Exit 255 "Option '$1' requires a value." + fi + + echo "$2" + return 0 +} + +HAVE_TEST_EF_OPTION=@HAVE_TEST_EF_OPTION@ +BASH_PROG=@BASH_PROG@ +BADOPTION= +DIFFCMD=@DIFF_PROG@ +SEDCMD=sed +D_option= +br=.br +while [ $# -gt 0 ] +do + OPTION="$1" + case "${OPTION}" in + -a*) + ADDMARK=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -c*) + CHANGEMARK=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -d*) + DELETEMARK=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -D ) + D_option=D_option + ;; + -M* ) + MARK1=`RequiresArgument "${OPTION}" "$2"` && + shift + if [ $# -lt 2 ] + then + Usage "Option '-M' is missing the MARK2 value." + fi + MARK2="$2" + shift + ;; + -B ) + br=. + ;; + -s* ) + SEDCMD=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -x* ) + DIFFCMD=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + --version) + echo "${CMD} (groff) version @VERSION@" + exit 0 + ;; + --help) + Usage + ;; + --) + # What follows -- are file arguments + shift + break + ;; + -) + break + ;; + -*) + BADOPTION="${CMD}: invalid option '$1'" + ;; + *) + break + ;; + esac + shift +done + +${DIFFCMD} -Dx /dev/null /dev/null >/dev/null 2>&1 || + Usage "The '${DIFFCMD}' program does not accept" \ + "the required '-Dname' option. +Use GNU diff instead. See the '-x DIFFCMD' option. You can also +install GNU diff as gdiff on your system" + +if test -n "${BADOPTION}" +then + Usage "${BADOPTION}" +fi + +if test $# -lt 2 -o $# -gt 3 +then + Usage "Incorrect number of arguments." +fi + +if test "1$1" = "1-" -a "2$2" = "2-" +then + Usage "Both FILE1 and FILE2 are '-'." +fi + +FILE1="$1" +FILE2="$2" + +FileRead 1 "${FILE1}" +FileRead 2 "${FILE2}" + +if test $# = 3 +then + case "$3" in + -) + # output goes to standard output + ;; + *) + # output goes to a file + WouldClobber "${FILE1}" FILE1 "$3" + WouldClobber "${FILE2}" FILE2 "$3" + + FileCreate 3 "$3" + exec >$3 + ;; + esac +fi + +# To make a very unlikely LABEL even more unlikely ... +LABEL=__diffmk_$$__ + +SED_SCRIPT=' + /^#ifdef '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { + /^#ifdef '"${LABEL}"'/ s/.*/.mc '"${ADDMARK}"'/ + /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } + /^#ifndef '"${LABEL}"'/,/^#endif \/\* [!not ]*'"${LABEL}"'/ { + /^#else \/\* '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { + /^#else \/\* '"${LABEL}"'/ s/.*/.mc '"${CHANGEMARK}"'/ + /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } + /^#endif \/\* [!not ]*'"${LABEL}"'/ { + s/.*/.mc '"${DELETEMARK}"'/p + a\ +.mc + } + d + } + p + ' + +if [ ${D_option} ] +then + SED_SCRIPT=' + /^#ifdef '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { + /^#ifdef '"${LABEL}"'/ s/.*/.mc '"${ADDMARK}"'/ + /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } + /^#ifndef '"${LABEL}"'/,/^#endif \/\* [!not ]*'"${LABEL}"'/ { + /^#ifndef '"${LABEL}"'/ { + i\ +'"${MARK1}"' + d + } + /^#else \/\* '"${LABEL}"'/ !{ + /^#endif \/\* [!not ]*'"${LABEL}"'/ !{ + p + d + } + } + /^#else \/\* '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { + /^#else \/\* '"${LABEL}"'/ { + i\ +'"${MARK2}"'\ +'"${br}"' + s/.*/.mc '"${CHANGEMARK}"'/ + a\ +.mc '"${CHANGEMARK}"' + d + } + /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } + /^#endif \/\* [!not ]*'"${LABEL}"'/ { + i\ +'"${MARK2}"'\ +'"${br}"' + s/.*/.mc '"${DELETEMARK}"'/p + a\ +.mc + } + d + } + p + ' +fi + +${DIFFCMD} -D"${LABEL}" -- "${FILE1}" "${FILE2}" | + ${SEDCMD} -n "${SED_SCRIPT}" + +# EOF |