summaryrefslogtreecommitdiffstats
path: root/contrib/gdiffmk/gdiffmk.sh
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gdiffmk/gdiffmk.sh')
-rw-r--r--contrib/gdiffmk/gdiffmk.sh367
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