chip@chinacat.Lonestar.ORG (Chip Rosenthal) (02/25/90)
[ Original was in comp.unix.xenix -- followups directed back there. ] In article <10306@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes: >[summary: patches are the way to go] >If your variant of Xenix doesn't have "diff -c", which generates >"context diffs" (the best kind of patches), you can also get free >programs that will generate them, including GNU Diff and "cdiff". The XENIX diff does not do context diffs. The GNU diff does, but it requires a couple of small hacks to get it running under XENIX. Below are two patches. One fixes GNU diff to run under XENIX. The second patch adds a "merged" diff option. If you want to run GNU diff under XENIX, you will obviously need to first grab a copy of the diff v1.7 sources. (osu-cis is a good place to snarf GNU stuff via anon uucp.) Besides my patch, you will also need a version of "alloca()" which runs on XENIX. These have been floating around; I remember one or two posted to comp.unix.xenix. My patch assumes that your alloca() is found in a library called SlibPW.a. The second patch gives you a merged diff feature which lets you do something like "diff -m diff.h~ diff.h" to get: ---------------------------------+--------------------------------- diff.h~ | diff.h --- insert at 106 ---------------+---- 107-108 -------------------- | /* Output the differences merg | OUTPUT_MERGED, --- insert at 181 ---------------+---- 184-186 -------------------- | | /* Output page width for merged | EXTERN int page_width; ---------------------------------+--------------------------------- If you need the XENIX 386 alloca.s, I suppose I can make it available. (I *do not* have a 286 version.) Also, I've archived a couple of other diff fixes/enhancements which have appeared in gnu.utils.bugs. Drop me a line if you need any of this stuff. --- cut here ----------------------------------------------------------------- #! /bin/sh # this is a "shar" archive - run through "/bin/sh" to extract 2 files: # Patch-1-xnx Patch-2-mopt # Wrapped by bin@chinacat on Sat Feb 24 14:14:53 CST 1990 # Unpacking this archive requires: sed test wc (possibly mkdir) # Existing files will not be clobbered unless "-c" is specified on the cmd line. if test -f Patch-1-xnx -a "$1" != "-c" ; then echo "Patch-1-xnx: file exists - will not be overwritten" else echo "x - Patch-1-xnx (file 1 of 2, 1771 chars)" sed -e 's/^X//' << 'END_OF_FILE_Patch-1-xnx' > Patch-1-xnx XThis patch ports GNU diff to SCO XENIX 386. Note that the "Makefile" Xassumes that you have "alloca()" available in libPW. X XChip Rosenthal X<chip@vector.Dallas.TX.US> X X XIndex: Makefile X*** Makefile~ Sat Aug 12 21:12:20 1989 X--- Makefile Sat Aug 12 21:19:28 1989 X*************** X*** 21,34 **** X # You can compile this with ordinary cc as well, X # but gcc makes it faster. X # Also, gcc supports -O and -g together. X! CC=gcc -O X! CFLAGS = -g X! INSTALL = install X X # On system V, enable these three lines: X # CFLAGS = -g -DUSG X # LIBS = -lPW X # INSTALL = cp X X bindir=/usr/local/bin X prefix= X--- 21,39 ---- X # You can compile this with ordinary cc as well, X # but gcc makes it faster. X # Also, gcc supports -O and -g together. X! # CC=gcc -O X! # CFLAGS = -g X! # INSTALL = install X X # On system V, enable these three lines: X # CFLAGS = -g -DUSG X # LIBS = -lPW X # INSTALL = cp X+ X+ # Use these definitions for XENIX: X+ CFLAGS = -O -DUSG -DXENIX X+ LIBS = -lx -lPW X+ INSTALL = cp X X bindir=/usr/local/bin X prefix= XIndex: diff.h X*** diff.h~ Sat Aug 12 21:12:23 1989 X--- diff.h Sat Aug 12 21:13:38 1989 X*************** X*** 28,37 **** X--- 28,43 ---- X #ifdef hp9000s800 X #include <ndir.h> X #else X+ #ifdef XENIX X+ #include <sys/ndir.h> X+ #else X #include <dirent.h> X #endif X+ #endif X #include <fcntl.h> X+ #ifndef XENIX X #define direct dirent X+ #endif X #else X #include <sys/time.h> X #include <sys/dir.h> XIndex: diff3.c X*** diff3.c~ Sat Aug 12 21:12:26 1989 X--- diff3.c Sat Aug 12 21:12:25 1989 X*************** X*** 31,37 **** X--- 31,39 ---- X #define bcmp(s1,s2,n) memcmp((s1),(s2),(n)) X #define bzero(s,n) memset((s),0,(n)) X X+ #ifndef XENIX X #define dup2(f,t) (close(t),fcntl((f),F_DUPFD,(t))) X+ #endif X X #define vfork fork X #define index strchr END_OF_FILE_Patch-1-xnx size="`wc -c < Patch-1-xnx`" if test 1771 -ne "$size" ; then echo "Patch-1-xnx: extraction error - got $size chars" fi fi if test -f Patch-2-mopt -a "$1" != "-c" ; then echo "Patch-2-mopt: file exists - will not be overwritten" else echo "x - Patch-2-mopt (file 2 of 2, 7939 chars)" sed -e 's/^X//' << 'END_OF_FILE_Patch-2-mopt' > Patch-2-mopt XThis patch adds "-m" and "-M width" options to GNU diff. For example, the Xcommand "diff -M 68 diff.h~ diff.h" generates: X X ---------------------------------+--------------------------------- X diff.h~ | diff.h X --- insert at 106 ---------------+---- 107-108 -------------------- X | /* Output the differences merg X | OUTPUT_MERGED, X --- insert at 181 ---------------+---- 184-186 -------------------- X | X | /* Output page width for merged X | EXTERN int page_width; X ---------------------------------+--------------------------------- X XChip Rosenthal X<chip@vector.Dallas.TX.US> X X XIndex: diff.h X*** diff.h~ Sat Aug 12 21:21:59 1989 X--- diff.h Sat Aug 12 21:10:14 1989 X*************** X*** 104,109 **** X--- 104,111 ---- X OUTPUT_ED, X /* Output the diff as a forward ed script (-f). */ X OUTPUT_FORWARD_ED, X+ /* Output the differences merged side-by-side (-m,-M). */ X+ OUTPUT_MERGED, X /* Like -f, but output a count of changed lines in each "command" (-n). */ X OUTPUT_RCS }; X X*************** X*** 179,184 **** X--- 181,189 ---- X X /* Nonzero means use heuristics for better speed. */ X EXTERN int heuristic; X+ X+ /* Output page width for merged (side-by-side) diff output. (-M,-m) */ X+ EXTERN int page_width; X X /* Name of program the user invoked (for error messages). */ X EXTERN char * program; XIndex: diff.c X*** diff.c~ Sat Aug 12 21:11:49 1989 X--- diff.c Sat Aug 12 21:10:17 1989 X*************** X*** 102,111 **** X msg_chain = NULL; X msg_chain_end = NULL; X no_discards = 0; X X /* Decode the options. */ X X! while ((c = getopt (argc, argv, "0123456789abBcC:defF:hHiI:lnNprsS:tTw")) X != EOF) X { X switch (c) X--- 102,112 ---- X msg_chain = NULL; X msg_chain_end = NULL; X no_discards = 0; X+ page_width = 80; X X /* Decode the options. */ X X! while ((c = getopt (argc, argv, "0123456789abBcC:defF:hHiI:lmM:nNprsS:tTw")) X != EOF) X { X switch (c) X*************** X*** 216,221 **** X--- 217,239 ---- X case 'l': X /* Pass the output through `pr' to paginate it. */ X paginate_flag = 1; X+ break; X+ X+ case 'm': X+ /* Print the differences side-by-side using default page width. */ X+ specify_style (OUTPUT_MERGED); X+ break; X+ X+ case 'M': X+ /* Print the differences side-by-side using specified page width. */ X+ { X+ char *p; X+ for (p = optarg; *p; p++) X+ if (*p < '0' || *p > '9') X+ fatal ("invalid page width argument (-M option)"); X+ } X+ specify_style (OUTPUT_MERGED); X+ page_width = atoi(optarg); X break; X X case 'n': XIndex: analyze.c X*** analyze.c~ Sat Aug 12 21:11:43 1989 X--- analyze.c Sat Aug 12 21:10:24 1989 X*************** X*** 760,765 **** X--- 760,769 ---- X print_rcs_script (script); X break; X X+ case OUTPUT_MERGED: X+ print_merged_script (script); X+ break; X+ X case OUTPUT_NORMAL: X print_normal_script (script); X break; XIndex: merged.c X*** merged.c~ Sat Aug 12 21:20:15 1989 X--- merged.c Sat Aug 12 21:09:59 1989 X*************** X*** 0 **** X--- 1,147 ---- X+ #include "diff.h" X+ X+ void print_merged_hunk (); X+ void print_number_range (); X+ struct change *find_change (); X+ X+ static void print_merged_hunk(); X+ static void print_merged_header(); X+ static void print_1_field(); X+ static void print_dashes(); X+ X+ static int field_width; X+ X+ void print_merged_script(script) X+ struct change *script; X+ { X+ register int i; X+ X+ field_width = ( page_width - 3 ) / 2; X+ X+ print_dashes( outfile, field_width ); X+ fputs( "-+-", outfile ); X+ print_dashes( outfile, field_width ); X+ putc( '\n', outfile ); X+ X+ print_1_field( files[0].name, strlen(files[0].name), field_width ); X+ fputs( " | ", outfile ); X+ print_1_field( files[1].name, strlen(files[1].name), field_width ); X+ putc( '\n', outfile ); X+ X+ print_script (script, find_change, print_merged_hunk); X+ X+ print_dashes( outfile, field_width ); X+ fputs( "-+-", outfile ); X+ print_dashes( outfile, field_width ); X+ putc( '\n', outfile ); X+ } X+ X+ X+ static void print_merged_hunk(hunk) X+ struct change *hunk; X+ { X+ int first0, last0, first1, last1, deletes, inserts; X+ register int i0, i1; X+ X+ /* Determine range of line numbers involved in each file. */ X+ analyze_hunk(hunk, &first0, &last0, &first1, &last1, &deletes, &inserts); X+ if (!deletes && !inserts) X+ return; X+ X+ /* Print header. */ X+ print_merged_header(outfile, &files[0], X+ first0, last0, field_width, deletes, inserts); X+ fputs("-+-", outfile); X+ print_merged_header(outfile, &files[1], X+ first1, last1, field_width, 0, 0); X+ putc('\n', outfile); X+ X+ for ( i0 = first0, i1 = first1 ; i0 <= last0 || i1 <= last1 ; ++i0, ++i1 ) { X+ if ( i0 <= last0 ) X+ print_1_field(files[0].linbuf[i0].text, X+ files[0].linbuf[i0].length, field_width); X+ else X+ fprintf(outfile, "%*s", field_width, ""); X+ fputs( " | ", outfile ); X+ if ( i1 <= last1 ) X+ print_1_field(files[1].linbuf[i1].text, X+ files[1].linbuf[i1].length, field_width); X+ else X+ fprintf(outfile, "%*s", field_width, ""); X+ putc('\n', outfile); X+ } X+ X+ } X+ X+ X+ static void print_merged_header(fp,file,first,last,width,delflag,insflag) X+ FILE *fp; X+ struct file_data *file; X+ int first, last, width, delflag, insflag; X+ { X+ char numbuf[64], *s; X+ int trans_first, trans_last; X+ X+ if ( delflag && insflag ) X+ s = "--- change at "; X+ else if ( delflag ) X+ s = "--- delete at "; X+ else if ( insflag ) X+ s = "--- insert at "; X+ else X+ s = "--- "; X+ fputs(s,fp); X+ width -= strlen(s); X+ X+ translate_range(file, first, last, &trans_first, &trans_last); X+ if ( trans_last > trans_first ) X+ (void) sprintf(numbuf,"%d-%d ",trans_first,trans_last); X+ else X+ (void) sprintf(numbuf,"%d ",trans_last); X+ fputs(numbuf,fp); X+ width -= strlen(numbuf); X+ X+ print_dashes(fp,width); X+ } X+ X+ X+ static void print_1_field(line,linelen,width) X+ register char *line; X+ int linelen; X+ int width; X+ { X+ register int col, i; X+ X+ for ( X+ col = 0, i = 0 ; X+ col < width && *line && *line != '\n' && i <= linelen ; X+ ++i, ++line X+ ) { X+ switch ( *line ) { X+ case '\t': X+ do { X+ putc (' ',outfile); X+ } while ( (++col & 7) != 0 && col < width ); X+ break; X+ case '\b': X+ putc(*line,outfile); X+ --col; X+ break; X+ default: X+ putc(*line,outfile); X+ ++col; X+ break; X+ } X+ } X+ while ( ++col <= width ) X+ putc(' ',outfile); X+ } X+ X+ X+ static void print_dashes(fp,n) X+ FILE *fp; X+ register int n; X+ { X+ while ( --n >= 0 ) X+ putc('-',fp); X+ } XIndex: Makefile X*** Makefile~ Sat Aug 12 21:20:06 1989 X--- Makefile Sat Aug 12 21:20:57 1989 X*************** X*** 39,48 **** X prefix= X X # All source files X! srcs=diff.c analyze.c io.c context.c ed.c normal.c util.c dir.c diff.h \ X! regex.c regex.h limits.h diff3.c X # Object files for diff only. X! objs=diff.o analyze.o io.o context.o ed.o normal.o util.o dir.o regex.o X tapefiles = $(srcs) README diagmeet.note Makefile COPYING X X all: diff diff3 X--- 39,48 ---- X prefix= X X # All source files X! srcs=diff.c analyze.c io.c context.c ed.c normal.c mreged.c util.c dir.c \ X! diff.h regex.c regex.h limits.h diff3.c X # Object files for diff only. X! objs=diff.o analyze.o io.o context.o ed.o normal.o merged.o util.o dir.o regex.o X tapefiles = $(srcs) README diagmeet.note Makefile COPYING X X all: diff diff3 END_OF_FILE_Patch-2-mopt size="`wc -c < Patch-2-mopt`" if test 7939 -ne "$size" ; then echo "Patch-2-mopt: extraction error - got $size chars" fi fi echo "done - 2 files extracted" exit 0 -- Chip Rosenthal | Yes, you're a happy man and you're chip@chinacat.Lonestar.ORG | a lucky man, but are you a smart Unicom Systems Development, 512-482-8260 | man? -David Bromberg