chip@chinacat.unicom.com (Chip Rosenthal) (01/11/91)
--text follows this line-- This patch allows GNU diff 1.15 to run on SCO XENIX and SCO UNIX, and adds a merged diff format. For example, using the merged format with the command: diff -M76 Distrib/diff.h diff.h gives the result: -------------------------------------+------------------------------------- Distrib/diff.h | diff.h --- insert at 85 --------------------+- 86 -------------------------------- | #if !defined (INT_MAX) /* SCO UNIX g --- insert at 86 --------------------+- 88 -------------------------------- | #endif --- change at 123 -------------------+- 125-128 --------------------------- OUTPUT_IFDEF }; | OUTPUT_IFDEF, | /* Output merged in side-by-side d | OUTPUT_MERGED | }; --- insert at 200 -------------------+- 206-208 --------------------------- | | /* Line width for the merged display | EXTERN int line_width; -------------------------------------+------------------------------------- Two command line switches were added to get the merged format `-M line_width' and `-m'. The only difference is that the latter implies a 80-char line width. The following files are affected by this patch: diff.h merged format support, bugfix for SCO UNIX diff.c merged format support analyze.c merged format support alloca.c bugfix for ansish cpp warnings merged.c new file - print merged format Makefile bugfix for SCO XENIX flags and to make alloca.c work make.sco-xenix new file - see below make.sco-unix new file - see below About the easiest way to `plug and go' under SCO XENIX or UNIX would be to link either `make.sco-xenix' or `make.sco-unix' to `makefile', edit the definitions at the top (most notably `bindir'), and run `make'. BTW...this stuff has been tested under SCO XENIX 2.3.3OS/2.3.1DS and SCO UNIX 3.2.1. --- start of patch ----------------------------------------------------------- Index: diff.h *** Distrib/diff.h Sun Jan 6 17:04:45 1991 --- diff.h Thu Jan 10 18:55:23 1991 *************** *** 83,89 **** --- 83,91 ---- /* Support old-fashioned C compilers. */ #if defined (__STDC__) || defined (__GNUC__) + #if !defined (INT_MAX) /* SCO UNIX grabs this through <stdio.h> */ #include "limits.h" + #endif #else #define INT_MAX 2147483647 #define CHAR_BIT 8 *************** *** 120,126 **** /* Like -f, but output a count of changed lines in each "command" (-n). */ OUTPUT_RCS, /* Output merged #ifdef'd file (-D). */ ! OUTPUT_IFDEF }; /* True for output styles that are robust, i.e. can handle a file that ends in a non-newline. */ --- 122,131 ---- /* Like -f, but output a count of changed lines in each "command" (-n). */ OUTPUT_RCS, /* Output merged #ifdef'd file (-D). */ ! OUTPUT_IFDEF, ! /* Output merged in side-by-side display (-m). */ ! OUTPUT_MERGED ! }; /* True for output styles that are robust, i.e. can handle a file that ends in a non-newline. */ *************** *** 198,203 **** --- 203,211 ---- /* Pipe each file's output through pr (-l). */ EXTERN int paginate_flag; + + /* Line width for the merged display (-m,-M). */ + EXTERN int line_width; /* String to use for #ifdef (-D). */ EXTERN char * ifdef_string; Index: diff.c *** Distrib/diff.c Sun Jan 6 17:53:25 1991 --- diff.c Thu Jan 10 00:41:56 1991 *************** *** 143,153 **** msg_chain = NULL; msg_chain_end = NULL; no_discards = 0; /* Decode the options. */ while ((c = getopt_long (argc, argv, ! "0123456789abBcC:dD:efF:hHiI:lL:nNpqrsS:tTuvw", longopts, &longind)) != EOF) { if (c == 0) /* Long option. */ --- 143,154 ---- msg_chain = NULL; msg_chain_end = NULL; no_discards = 0; + line_width = 0; /* Decode the options. */ while ((c = getopt_long (argc, argv, ! "0123456789abBcC:dD:efF:hHiI:lL:mM:nNpqrsS:tTuvw", longopts, &longind)) != EOF) { if (c == 0) /* Long option. */ *************** *** 281,286 **** --- 282,299 ---- file_label[1] = optarg; else fatal ("too many file label options"); + break; + + case 'm': + /* Make output merged in side-by-side display. */ + specify_style (OUTPUT_MERGED); + line_width = 80; + break; + + case 'M': + /* Make output merged in side-by-side display. */ + specify_style (OUTPUT_MERGED); + line_width = atoi(optarg); break; case 'n': Index: analyze.c *** Distrib/analyze.c Sun Jan 6 17:05:11 1991 --- analyze.c Thu Jan 10 00:53:16 1991 *************** *** 32,37 **** --- 32,38 ---- void print_normal_script (); void print_rcs_script (); void pr_forward_ed_script (); + void print_merged_script (); void setup_output (); extern int no_discards; *************** *** 844,849 **** --- 845,854 ---- case OUTPUT_IFDEF: print_ifdef_script (script); + break; + + case OUTPUT_MERGED: + print_merged_script (script); break; } Index: alloca.c *** Distrib/alloca.c Sun Jan 6 17:25:02 1991 --- alloca.c Thu Jan 10 18:35:07 1991 *************** *** 42,49 **** lose -- must know STACK_DIRECTION at compile-time #endif /* STACK_DIRECTION undefined */ ! #endif static ! #endif emacs #ifdef X3J11 typedef void *pointer; /* generic pointer type */ --- 42,49 ---- lose -- must know STACK_DIRECTION at compile-time #endif /* STACK_DIRECTION undefined */ ! #endif /* static */ ! #endif /* emacs */ #ifdef X3J11 typedef void *pointer; /* generic pointer type */ Index: merged.c *** /dev/null Thu Jan 10 21:10:10 1991 --- merged.c Thu Jan 10 20:52:52 1991 *************** *** 0 **** --- 1,193 ---- + /* + * The merged diff format added by Chip Rosenthal <chip@chinacat.unicom.com> + */ + + #include "diff.h" + + #define TABSTOP 8 /* must be a power of two (e.g. 4, 8, etc.) */ + + #define Fput3(FP,S1,S2,S3) \ + ( fputs((S1),(FP)), fputs((S2),(FP)), fputs((S3),(FP)), putc('\n',(FP)) ) + + #define Strncpy(OUT,IN,LEN) \ + ( (OUT)[(LEN)] = '\0', strncpy((OUT),(IN),(LEN)) ) + + static int field_width; + static char *field0_buf, *field1_buf, *tmp_buf; + + static void print_merged_hunk(); + static void expand_field(); + + extern struct change *find_change(); + + + void print_merged_script(script) + struct changed *script; + { + + /* + * Figure out how big a field to print the file differences in. + */ + field_width = ( line_width - (sizeof("-+-")-1) ) / 2; + if ( field_width < 1 ) { + fputs("diff: bad field width specified\n",stderr); + exit(1); + } + + /* + * Create the space for formatting. + */ + field0_buf = (char*) xmalloc((unsigned)field_width+1); + field1_buf = (char*) xmalloc((unsigned)field_width+1); + tmp_buf = (char*) xmalloc((unsigned)field_width+1); + + /* + * Print the header. + */ + expand_field(tmp_buf, (char*)NULL, field_width, '-'), + Fput3(outfile, tmp_buf, "-+-", tmp_buf); + + (void) Strncpy(tmp_buf, files[0].name, field_width); + expand_field(field0_buf, tmp_buf, field_width, ' '), + (void) Strncpy(tmp_buf, files[1].name, field_width); + expand_field(field1_buf, tmp_buf, field_width, ' '), + Fput3(outfile, field0_buf, " | ", field1_buf); + + /* + * Print the hunks. + */ + print_script(script, find_change, print_merged_hunk); + + /* + * Print the trailer. + */ + expand_field(tmp_buf, (char*)NULL, field_width, '-'), + Fput3(outfile, tmp_buf, "-+-", tmp_buf); + + free(field0_buf); + free(field1_buf); + free(tmp_buf); + } + + + static void print_merged_hunk(hunk) + struct change *hunk; + { + int first0, last0, first1, last1, deletes, inserts, tr_first, tr_last, len; + char *action; + register int i0, i1; + + /* + * Determine range of line numbers involved in each file. + */ + analyze_hunk(hunk, &first0, &last0, &first1, &last1, &deletes, &inserts); + if ( deletes > 0 && inserts > 0 ) + action = "change"; + else if ( deletes > 0 ) + action = "delete"; + else if ( inserts > 0 ) + action = "insert"; + else + return; + + /* + * Print the header for this hunk. + */ + translate_range(&files[0], first0, last0, &tr_first, &tr_last); + if ( tr_last > tr_first ) + (void) sprintf(tmp_buf, "--- %s at %d-%d ", action, tr_first, tr_last); + else + (void) sprintf(tmp_buf, "--- %s at %d ", action, tr_last); + expand_field(field0_buf, tmp_buf, field_width, '-'); + + translate_range(&files[1], first1, last1, &tr_first, &tr_last); + if ( tr_last > tr_first ) + (void) sprintf(tmp_buf, " %d-%d ", tr_first, tr_last); + else + (void) sprintf(tmp_buf, " %d ", tr_last); + expand_field(field1_buf, tmp_buf, field_width, '-'); + + Fput3(outfile, field0_buf, "-+-", field1_buf); + + /* + * Format and print each line in this hunk. + */ + for ( i0 = first0, i1 = first1 ; i0 <= last0 || i1 <= last1 ; ++i0, ++i1 ) { + + if ( i0 <= last0 ) { + len = ( files[0].linbuf[i0].length < field_width ? + files[0].linbuf[i0].length : field_width ); + Strncpy(tmp_buf, files[0].linbuf[i0].text, len); + expand_field(field0_buf, tmp_buf, field_width, ' '); + } else { + expand_field(field0_buf, (char*)NULL, field_width, ' '); + } + + if ( i1 <= last1 ) { + len = ( files[1].linbuf[i1].length < field_width ? + files[1].linbuf[i1].length : field_width ); + Strncpy(tmp_buf, files[1].linbuf[i1].text, len); + expand_field(field1_buf, tmp_buf, field_width, ' '); + } else { + expand_field(field1_buf, (char*)NULL, field_width, ' '); + } + + Fput3(outfile, field0_buf, " | ", field1_buf); + + } + + } + + + /* + * The expand_field() routine performs two functions. First, it goes + * through "inbuf" and reformats the line doing stuff like expanding + * tabs and stripping out newlines. Second, it expands the text to + * "fieldlen" characters, using the "padchar" to fill to this length. + * If the "inbuf" is NULL, we just generate a string of the "padchar". + */ + static void expand_field(outbuf,inbuf,fieldlen,padchar) + char *outbuf; + char *inbuf; + int fieldlen; + int padchar; + { + int currcol; + + /* + * If no string was passed to us, make one of the full field length. + */ + if ( inbuf == NULL ) { + while ( --fieldlen >= 0 ) + *outbuf++ = padchar; + *outbuf = '\0'; + return; + } + + /* + * Go through the string doing translations (tab expansion, etc.). + */ + currcol = 1; + while ( *inbuf != '\0' && fieldlen > 0 ) { + if ( *inbuf == '\t' ) { + do { + *outbuf++ = ' '; + } while ( --fieldlen >= 0 && !( currcol++ & TABSTOP ) ) ; + ++inbuf; + } else if ( isascii(*inbuf) && isprint(*inbuf) ) { + *outbuf++ = *inbuf++; + ++currcol; + --fieldlen; + } else { + ++inbuf; /* elide this character */ + } + } + + /* + * Finally, pad it out to the required length. + */ + while ( --fieldlen >= 0 ) + *outbuf++ = padchar; + *outbuf = '\0'; + } + Index: Makefile *** Distrib/Makefile Sun Jan 6 18:02:56 1991 --- Makefile Thu Jan 10 19:26:28 1991 *************** *** 38,65 **** # Use these definitions for XENIX: # There are rumors of bugs in various Xenix's dirent.h and -ldir. As # a result, we suggest using HAVE_NDIR and not using -ldir. ! # CFLAGS = -O -DUSG -DXENIX -DHAVE_NDIR -DHAVE_DIRECT -DNDIR_IN_SYS ! # LIBS = -lx -lPW # INSTALL = cp # Some System V machines do not come with libPW. If this is true, use # the GNU alloca by switching the comment on the following lines. ALLOCA = ! # ALLOCA = $(archpfx)/alloca.o bindir=/usr/local/bin prefix= # All source files ! srcs=diff.c analyze.c io.c context.c ed.c normal.c ifdef.c util.c dir.c \ ! version.c diff.h regex.c regex.h limits.h diff3.c \ ! getopt.c getopt1.c getopt.h alloca.c # Object files for diff only. objs=$(archpfx)diff.o $(archpfx)analyze.o $(archpfx)io.o $(archpfx)context.o \ ! $(archpfx)ed.o $(archpfx)normal.o $(archpfx)util.o $(archpfx)dir.o \ ! $(archpfx)regex.o $(archpfx)ifdef.o $(archpfx)version.o \ $(archpfx)getopt.o $(archpfx)getopt1.o ! tapefiles = $(srcs) README diagmeet.note Makefile COPYING ChangeLog all: $(archpfx)diff $(archpfx)diff3 --- 38,65 ---- # Use these definitions for XENIX: # There are rumors of bugs in various Xenix's dirent.h and -ldir. As # a result, we suggest using HAVE_NDIR and not using -ldir. ! # CFLAGS = -O -DUSG -DXENIX -DHAVE_NDIR -DHAVE_DIRECT -DNDIR_IN_SYS -Dconst= ! # LIBS = -lx # INSTALL = cp # Some System V machines do not come with libPW. If this is true, use # the GNU alloca by switching the comment on the following lines. ALLOCA = ! # ALLOCA = $(archpfx)alloca.o bindir=/usr/local/bin prefix= # All source files ! srcs=diff.c analyze.c io.c context.c ed.c normal.c ifdef.c merged.c \ ! util.c dir.c version.c regex.c diff3.c getopt.c getopt1.c alloca.c ! hdrs=diff.h regex.h limits.h getopt.h # Object files for diff only. objs=$(archpfx)diff.o $(archpfx)analyze.o $(archpfx)io.o $(archpfx)context.o \ ! $(archpfx)ed.o $(archpfx)normal.o $(archpfx)merged.o $(archpfx)util.o \ ! $(archpfx)dir.o $(archpfx)regex.o $(archpfx)ifdef.o $(archpfx)version.o \ $(archpfx)getopt.o $(archpfx)getopt1.o ! tapefiles = $(srcs) $(hdrs) README diagmeet.note Makefile COPYING ChangeLog all: $(archpfx)diff $(archpfx)diff3 *************** *** 66,78 **** $(archpfx)diff3: $(archpfx)diff3.o $(CC) -o $(archpfx)diff3 $(CFLAGS) $(LDFLAGS) $(archpfx)diff3.o $(LIBS) ! $(archpfx)diff: $(objs) ! $(CC) -o $(archpfx)diff $(CFLAGS) $(LDFLAGS) $(objs) $(LIBS) $(objs): diff.h $(archpfx)context.o $(archpfx)diff.o: regex.h $(archpfx)diff3.o: diff3.c $(CC) -c $(CFLAGS) -DDIFF_PROGRAM=\"$(bindir)/diff\" diff3.c \ $(OUTPUT_OPTION) --- 66,80 ---- $(archpfx)diff3: $(archpfx)diff3.o $(CC) -o $(archpfx)diff3 $(CFLAGS) $(LDFLAGS) $(archpfx)diff3.o $(LIBS) ! $(archpfx)diff: $(objs) $(ALLOCA) ! $(CC) -o $(archpfx)diff $(CFLAGS) $(LDFLAGS) $(objs) $(ALLOCA) $(LIBS) $(objs): diff.h $(archpfx)context.o $(archpfx)diff.o: regex.h + $(archpfx)alloca.o: alloca.c diff.h + $(archpfx)diff3.o: diff3.c $(CC) -c $(CFLAGS) -DDIFF_PROGRAM=\"$(bindir)/diff\" diff3.c \ $(OUTPUT_OPTION) *************** *** 91,96 **** --- 93,103 ---- $(prefix)$(bindir)/diff3: $(archpfx)diff3 $(INSTALL) $(archpfx)diff3 $(prefix)$(bindir)/diff3 + + lint: diff.lint + + diff.lint: $(srcs) + lint $(CFLAGS) $(LDFLAGS) $(srcs) $(LIBS) >$@ diff.tar: $(tapefiles) mkdir tmp Index: make.sco-xenix *** /dev/null Thu Jan 10 21:10:10 1991 --- make.sco-xenix Thu Jan 10 19:26:50 1991 *************** *** 0 **** --- 1,16 ---- + SHELL = /bin/sh + CC = cc + CFLAGS = -O -DUSG -DXENIX -DHAVE_NDIR -DHAVE_DIRECT -DNDIR_IN_SYS -Dconst= + LIBS = -lx + INSTALL = cp + ALLOCA = alloca.o + bindir = /local/bin + + ENV = CC="$(CC)" CFLAGS="$(CFLAGS)" LIBS="$(LIBS)" INSTALL="$(INSTALL)" \ + ALLOCA="$(ALLOCA)" bindir="$(bindir)" + + all: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + clean: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + install: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + lint: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + Index: make.sco-unix *** /dev/null Thu Jan 10 21:10:10 1991 --- make.sco-unix Thu Jan 10 19:26:42 1991 *************** *** 0 **** --- 1,16 ---- + SHELL = /bin/sh + CC = cc + CFLAGS = -O -DUSG -Dconst= + LIBS = + INSTALL = cp + ALLOCA = alloca.o + bindir = /local/bin + + ENV = CC="$(CC)" CFLAGS="$(CFLAGS)" LIBS="$(LIBS)" INSTALL="$(INSTALL)" \ + ALLOCA="$(ALLOCA)" bindir="$(bindir)" + + all: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + clean: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + install: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + lint: ; $(ENV) $(MAKE) -e$(MAKEFLAGS) -f Makefile $@ + --- end of patch ------------------------------------------------------------- -- Chip Rosenthal 512-482-8260 | If software look-and-feel can be protected, Unicom Systems Development | then I'd like to claim a copyright upon <chip@chinacat.Unicom.COM> | `Memory fault - core dumped'.