Import Mike's `gdiffmk' package.
[s-roff.git] / contrib / gdiffmk / gdiffmk.sh
bloba055ace39bc94f6535dae5e781dc8d69c4370a32
1 #!/bin/sh
2 # This file is part of GNU gdiffmk.
4 # GNU gdiffmk is free software; you can redistribute it and/or modify it
5 # under the terms of the GNU General Public License as published by the
6 # Free Software Foundation; either version 2, or (at your option) any
7 # later version.
9 # GNU gdiffmk is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with gdiffmk; see the file COPYING. If not, write to the
16 # Free Software Foundation, Inc.
17 # 59 Temple Place - Suite 330
18 # Boston, MA 02111-1307, USA.
21 cmd=$( basename $0 )
23 diff -Dx /dev/null /dev/null >/dev/null 2>&1 ||
25 echo >&2 "${cmd}: " \
26 "The \`diff' program does not accept " \
27 "the required -DNAME option."
28 echo >&2 "${cmd}: " \
29 "Use GNU diff instead."
30 exit 126
33 function Usage {
34 if test "$#" -gt 0
35 then
36 echo >&2 "${cmd}: $@"
38 echo >&2 "\
40 Usage: ${cmd} [ OPTIONS ] FILE1 FILE2 [ OUTPUT ]
41 Place difference marks into the new version of a groff/nroff/troff document.
42 FILE1 and FILE2 are compared, using \`diff', and FILE2 is output with
43 groff \`.mc' requests added to indicate how it is different from FILE1.
45 FILE1 Previous version of the groff file. \`-' means standard input.
46 FILE2 Current version of the groff file. \`-' means standard input.
47 Either FILE1 or FILE2 can be standard input, but not both.
48 OUTPUT Copy of FILE2 with \`.mc' commands added.
49 \`-' means standard output (the default).
51 options:
52 -a addmark Mark for added groff source lines. Default: +.
53 -c changemark Mark for changed groff source lines. Default: |.
54 -d deletemark Mark for deleted groff source lines. Default: *.
55 --version Print version information on standard output and exit.
56 --help Print this message on standard error.
58 exit 255
62 function Exit {
63 exitcode=$1
64 shift
65 echo >&2 "${cmd}: $@"
66 exit ${exitcode}
69 # Usage: FileRead exit_code filename
71 # Check for existence and readability of given file name.
72 # If not found or not readable, print message and exit with EXIT_CODE.
73 function FileRead {
74 case "$2" in
76 return
78 esac
80 if test ! -e "$2"
81 then
82 Exit $1 "File \`$2' not found."
84 if test ! -r "$2"
85 then
86 Exit $1 "File \`$2' not readable."
91 # Usage: FileCreate exit_code filename
93 # Create the given filename if it doesn't exist.
94 # If unable to create or write, print message and exit with EXIT_CODE.
95 function FileCreate {
96 case "$2" in
98 return
100 esac
102 if ! touch "$2" 2>/dev/null
103 then
104 if test ! -e "$2"
105 then
106 Exit $1 "File \`$2' not created; " \
107 "Cannot write directory \`$( dirname "$2" )'."
109 Exit $1 "File \`$2' not writeable."
113 function WouldClobber {
114 case "$2" in
116 return
118 esac
120 if test "$1" -ef "$3"
121 then
122 Exit 3 "\`$3' is the same as \`$2' and would be clobbered."
126 addmark='+'
127 changemark='|'
128 deletemark='*'
130 function RequiresArgument {
131 # Process flags that take either concatenated or
132 # separated values.
133 case "$1" in
134 -??*)
135 expr "$1" : '-.\(.*\)'
136 return 1
138 esac
140 if test "$#" -lt 2
141 then
142 Exit 255 "Option \`$1' requires a value."
145 echo "$2"
146 return 0
149 badoption=
150 for option
152 case "${option}" in
153 -a*)
154 addmark=$( RequiresArgument "${option}" $2 ) &&
155 shift
157 -c*)
158 changemark=$( RequiresArgument "${option}" $2 ) &&
159 shift
161 -d*)
162 deletemark=$( RequiresArgument "${option}" $2 ) &&
163 shift
165 --version)
166 echo "GNU ${cmd} (groff) version @VERSION@"
167 exit 0
169 --help)
170 Usage
173 # What follows -- are file arguments
174 shift
175 break
178 break
181 badoption="${cmd}: invalid option \`$1'"
184 break
186 esac
187 shift
188 done
190 if test -n "${badoption}"
191 then
192 Usage "${badoption}"
195 if test "$#" -lt 2 -o "$#" -gt 3
196 then
197 Usage "Incorrect number of arguments."
200 if test "1$1" = 1- -a "2$2" = 2-
201 then
202 Usage "Both FILE1 and FILE2 are \`-'."
205 FILE1=$1
206 FILE2=$2
208 FileRead 1 "${FILE1}"
209 FileRead 2 "${FILE2}"
211 if test "$#" = 3
212 then
213 case "$3" in
215 # output goes to standard output
218 # output goes to a file
219 WouldClobber "${FILE1}" FILE1 "$3"
220 WouldClobber "${FILE2}" FILE2 "$3"
222 FileCreate 3 "$3"
223 exec >$3
225 esac
228 # To make a very unlikely label even more unlikely ...
229 label=__diffmk_$$__
231 diff -D"${label}" -- ${FILE1} ${FILE2} |
232 sed -n '
233 /^#ifdef '"${label}"'/,/^#endif \/\* '"${label}"'/ {
234 /^#ifdef '"${label}"'/ s/.*/.mc '"${addmark}"'/
235 /^#endif \/\* '"${label}"'/ s/.*/.mc/
239 /^#ifndef '"${label}"'/,/^#endif \/\* [not ]*'"${label}"'/ {
240 /^#else \/\* '"${label}"'/,/^#endif \/\* '"${label}"'/ {
241 /^#else \/\* '"${label}"'/ s/.*/.mc '"${changemark}"'/
242 /^#endif \/\* '"${label}"'/ s/.*/.mc/
246 /^#endif \/\* not '"${label}"'/ s/.*/.mc '"${deletemark}"'/p
252 # EOF