* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)chgbars.c 5.1 (Berkeley) %G%";
* Derived from original program by A. Dain Samples.
* The program chgbars will accept the output from a diff comparison of
* two versions of a file. It will then read the new version of the file
* and insert the appropriate troff commands to put change bars in the
* right margin. Typing 'chgbars' without any arguments will give you
* some documentation and an example.
* Caveat: If you make a change inside an equation or table, the
* preprocessors eqn and tbl may not like what chgbars does to the file.
* You may have to go into the output from chgbars to remove or rearrange
* some of the lines of the form '.mc | \"open' or '.mc \"close' in
* order to get through tbl or eqn.
* Unfortunately, users of RCS will be disappointed: one cannot use rcsdiff.
* Rcsdiff compares the files in the wrong order.
* There is a relatively easy way to do the job with the tools sed and awk.
* However, sed does not allow enough commands to process large documents.
* In the true spirit of a filter/tool, chgbars is limited only by the
* amount of memory on the machine, and is fast and useful.
* The modifications necessary are outlined:
* FORM OF DIFF OUTPUT COMMENT NEW SED COMMANDS
* ================================================================
* 100a means those lines 100a\\
* L1 were deleted from .mc |\\
* ----------------------------------------------------------------
* means that line 100 in newfile replaced all those lines in oldfile.
* ----------------------------------------------------------------
* 100d that line was added 100a\\
* ----------------------------------------------------------------
* 100,200d those lines were 200a\\
* ----------------------------------------------------------------
* means lines 100 to 200 of newfile replaced all the following lines
* ----------------------------------------------------------------
#define dbg(s) /* fprintf(stderr,"s\n") */
"@(#) Copyright (c) 1986 Regents of the University of California.\n\
if (strcmp(argv
[1], "-") == 0) {
} else if ((file1
= fopen(argv
[1], "r")) == NULL
) {
fprintf(stderr
, "error: can't open %s\n", argv
[1]);
* read each entry setting the appropriate entry in action[]
* get the first line number: since diff -e puts the numbers out
* in reverse order, this tells us how big to make the file
action
= (char (*)[]) malloc(t
+ 1);
for (p
= (char *) action
, i
= 0; i
< t
; i
++)
(*action
)[num1
- 1] = open
;
file2
= fopen(argv
[2], "r");
fprintf(stderr
, "can't open %2\n", argv
[2]);
switch ((*action
)[line
]) {
printf(".mc | \\\"open\n");
printf(".mc \\\"close\n");
printf(".mc | \\\"both\n");
fgets(linebuf
, sizeof(linebuf
), file2
);
fprintf(stderr
, "oops: number of lines read does not match\n");
fprintf(stderr
, "number of lines expected\n");
fprintf(stderr
, "Usage:\n");
fprintf(stderr
, "\tchgbars diff.out\n");
fprintf(stderr
, "\t\t\treads the output from diff, and expects the\n");
fprintf(stderr
, "\t\t\tfile to be modified on stdin\n");
fprintf(stderr
, "\tchgbars diff.out file.tbm\n");
fprintf(stderr
, "\t\t\tboth the output from diff and the file to be\n");
fprintf(stderr
, "\t\t\tmodified are stated explicitly\n");
fprintf(stderr
, "\tchgbars - file.tbm\n");
fprintf(stderr
, "\t\t\treads the output from diff on stdin\n");
fprintf(stderr
, "\nE.g.\n");
fprintf(stderr
, "diff -b -e newfile oldfile | chgbars - newfile | vtroff -ms\n");
fprintf(stderr
, "\t(note the order of the files in the diff command!)\n");
fprintf(stderr
, "\n\nBe forewarned: chgbars does not know about tables or equations.\n");
fprintf(stderr
, "If any part of a table or equation is changed, chgbars will insert the\n");
fprintf(stderr
, ".mc commands, whether tbl or eqn likes it or not.\n");
fprintf(stderr
, "This means that you may have to do some hand editing of the output of\n");
fprintf(stderr
, "chgbars to make it acceptable to one or both of these preprocessors.\n");
while (isdigit(nextch
)) {
num
= num
* 10 + nextch
- '0';
if (fgets(linebuf
, sizeof(linebuf
), file1
) == NULL
) {
fprintf(stderr
, "error reading file1\n");
} while (strcmp(linebuf
, ".\n") != 0);