lwall@sdcrdcf.UUCP (06/02/87)
If you use the following program to produce your patches, people will be able to apply your patches using the patch program even if their line numbers don't match your line numbers. This program produces 4.3bsd-style context diffs, which are considerably more compact than old-style context diffs, yet are much less error-prone to apply than normal diffs, since patch has more information to decide if it is putting the patch in the right place. In the worst case (that is, an append), a normal diff applied by patch can insert lines in the wrong place in your program and never tell you about it because all it has to go on is the line number. Note that cdiff uses a normal diff as a back end, so you'll still need Erik Baalbergen's diff program that he just posted if you want to run this under MINIX. Don't be confused, however, between his patch program and mine. His will only apply normal diffs, and only if you haven't modified your file. By the way, this is an unobfuscated version of a program I entered in the Obfuscated C Code Contest. Exercise #1: How would you go about shrinking this to under 1K of source? It's currently over 5K. Enjoy. Larry Wall {allegra,burdvax,cbosgd,hplabs,ihnp4,sdcsvax}!sdcrdcf!lwall #! /bin/sh # Make a new directory for the cdiff sources, cd to it, and run kits 1 # thru 1 through sh. When all 1 kits have been run, read README. echo "This is cdiff 1.1 kit 1 (of 1). If kit 1 is complete, the line" echo '"'"End of kit 1 (of 1)"'" will echo at the end.' echo "" export PATH || (echo "You didn't use sh, you clunch." ; kill $$) echo Extracting README sed >README <<'!STUFFY!FUNK!' -e 's/X//' XThis program runs a normal diff as input to a pipe, and transforms that into Xa 4.3bsd-style context diff. X XTo compile, just type "cc -o cdiff cdiff.c". You might want to throw in Xa -Dvoid=int if your C compiler doesn't grok the void type. X XTo run, just say "cdiff file1 file2". Cdiff will run a "diff file1 file2" Xfor you, and modify that output to make the context diff. If you don't have Xa normal diff program, there is a PD version available from Erik Baalbergen Xat erikb@cs.vu.nl. !STUFFY!FUNK! echo Extracting cdiff.c sed >cdiff.c <<'!STUFFY!FUNK!' -e 's/X//' Xstatic char rcsid[] = "$Header: cdiff.c,v 1.1 87/06/01 16:05:57 lwall Exp $"; X X/* cdiff - turns a regular diff into a new-style context diff X * X * Usage: cdiff file1 file2 X * X * $Log: cdiff.c,v $ X * Revision 1.1 87/06/01 16:05:57 lwall X * Initial revision X * X */ X X#include "patchlevel.h" X#include <stdio.h> X#include <sys/types.h> X#include <stat.h> X#include <ctype.h> X Xchar buf[512]; X XFILE *inputfp, *oldfp, *newfp; X Xint oldmin, oldmax, newmin, newmax; Xint oldbeg, oldend, newbeg, newend; Xint preoldmax, prenewmax; Xint preoldbeg, preoldend, prenewbeg, prenewend; Xint oldwanted, newwanted; X Xchar *oldhunk, *newhunk; Xunsigned oldsize, oldalloc, newsize, newalloc; X Xvoid dumphunk(); Xchar *getold(); Xchar *getnew(); Xchar *malloc(); Xchar *realloc(); Xchar *fgets(); XFILE *popen(); X X#define Nullfp (FILE*)0 X#define Nullch (char*)0 X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X char *old, *new; X int context = 3; X struct stat statbuf; X register char *s; X char op; X char *newmark, *oldmark; X int len; X char *line; X int i; X X oldalloc = 512; X oldhunk = malloc(oldalloc); X newalloc = 512; X newhunk = malloc(newalloc); X X for (argc--,argv++; argc; argc--,argv++) { X if (argv[0][0] != '-') X break; X if (argv[0][1] == 'v') { X printf("%s\n Patch level: %d\n",rcsid,PATCHLEVEL); X exit(0); X } X if (argv[0][1] == 'c') X context = atoi(argv[0]+2); X } X X if (argc != 2) { X fprintf(stderr,"cdiff old new\n"); X exit(1); X } X X old = argv[0]; X new = argv[1]; X X sprintf(buf,"diff %s %s", old, new); X inputfp = popen(buf, "r"); X if (!inputfp) { X fprintf(stderr, "Can't execute diff %s %s\n", old, new); X exit(1); X } X X oldfp = fopen(old,"r"); X if (!oldfp) { X fprintf(stderr, "Can't open %s\n", old); X exit(1); X } X newfp = fopen(new,"r"); X if (!newfp) { X fprintf(stderr, "Can't open %s\n", new); X exit(1); X } X X fstat(fileno(oldfp),&statbuf); X printf("*** %s\t%s", old, ctime(&statbuf.st_mtime)); X fstat(fileno(newfp),&statbuf); X printf("--- %s\t%s", new, ctime(&statbuf.st_mtime)); X X preoldend = -1000; X X while (fgets(buf, sizeof buf, inputfp) != Nullch) { X if (isdigit(*buf)) { X oldmin = atoi(buf); X for (s = buf; isdigit(*s); s++) ; X if (*s == ',') { X s++; X oldmax = atoi(s); X for ( ; isdigit(*s); s++) ; X } X else { X oldmax = oldmin; X } X if (*s != 'a' && *s != 'd' && *s != 'c') { X fprintf(stderr, "Unparseable input: %s", s); X exit(1); X } X op = *s; X s++; X newmin = atoi(s); X for ( ; isdigit(*s); s++) ; X if (*s == ',') { X s++; X newmax = atoi(s); X for ( ; isdigit(*s); s++) ; X } X else { X newmax = newmin; X } X if (*s != '\n' && *s != ' ') { X fprintf(stderr, "Unparseable input: %s", s); X exit(1); X } X X newmark = oldmark = "! "; X if (op == 'a') { X oldmin++; X newmark = "+ "; X } X if (op == 'd') { X newmin++; X oldmark = "- "; X } X X oldbeg = oldmin - context; X oldend = oldmax + context; X newbeg = newmin - context; X newend = newmax + context; X X if (preoldend < newbeg - 1) { X if (preoldend >= 0) { X dumphunk(); X } X preoldbeg = oldbeg; X prenewbeg = newbeg; X oldwanted = newwanted = 0; X oldsize = newsize = 0; X } else { /* we want to append to previous hunk */ X oldbeg = preoldmax + 1; X newbeg = prenewmax + 1; X } X X for (i = oldbeg; i <= oldmax; i++) { X line = getold(i); X if (!*line) { X oldend = oldmax = i - 1; X break; X } X len = strlen(line) + 2; X if (oldsize + len + 1 >= oldalloc) { X oldalloc *= 2; X oldhunk = realloc(oldhunk, oldalloc); X } X if (i >= oldmin) { X strcpy(oldhunk+oldsize, oldmark); X oldwanted++; X } X else { X strcpy(oldhunk+oldsize, " "); X } X strcpy(oldhunk+oldsize+2,line); X oldsize += len; X } X preoldmax = oldmax; X preoldend = oldend; X X for (i = newbeg; i <= newmax; i++) { X line = getnew(i); X if (!*line) { X newend = newmax = i - 1; X break; X } X len = strlen(line) + 2; X if (newsize + len + 1 >= newalloc) { X newalloc *= 2; X newhunk = realloc(newhunk, newalloc); X } X if (i >= newmin) { X strcpy(newhunk+newsize, newmark); X newwanted++; X } X else { X strcpy(newhunk+newsize, " "); X } X strcpy(newhunk+newsize+2,line); X newsize += len; X } X prenewmax = newmax; X prenewend = newend; X } X } X X if (preoldend >= 0) { X dumphunk(); X } X} X Xvoid Xdumphunk() X{ X int i; X char *line; X int len; X X for (i = preoldmax + 1; i <= preoldend; i++) { X line = getold(i); X if (!line) { X preoldend = i - 1; X break; X } X len = strlen(line) + 2; X if (oldsize + len + 1 >= oldalloc) { X oldalloc *= 2; X oldhunk = realloc(oldhunk, oldalloc); X } X strcpy(oldhunk+oldsize, " "); X strcpy(oldhunk+oldsize+2, line); X oldsize += len; X } X for (i = prenewmax + 1; i <= prenewend; i++) { X line = getnew(i); X if (!line) { X prenewend = i - 1; X break; X } X len = strlen(line) + 2; X if (newsize + len + 1 >= newalloc) { X newalloc *= 2; X newhunk = realloc(newhunk, newalloc); X } X strcpy(newhunk+newsize, " "); X strcpy(newhunk+newsize+2, line); X newsize += len; X } X fputs("***************\n",stdout); X if (preoldbeg >= preoldend) { X printf("*** %d ****\n", preoldend); X } else { X printf("*** %d,%d ****\n", preoldbeg, preoldend); X } X if (oldwanted) { X fputs(oldhunk,stdout); X } X oldsize = 0; X *oldhunk = '\0'; X if (prenewbeg >= prenewend) { X printf("--- %d ----\n", prenewend); X } else { X printf("--- %d,%d ----\n", prenewbeg, prenewend); X } X if (newwanted) { X fputs(newhunk,stdout); X } X newsize = 0; X *newhunk = '\0'; X} X Xchar * Xgetold(targ) Xint targ; X{ X static int oldline = 0; X X while (fgets(buf, sizeof buf, oldfp) != Nullch) { X oldline++; X if (oldline == targ) X return buf; X } X return Nullch; X} X Xchar * Xgetnew(targ) Xint targ; X{ X static int newline = 0; X X while (fgets(buf, sizeof buf, newfp) != Nullch) { X newline++; X if (newline == targ) X return buf; X } X return Nullch; X} !STUFFY!FUNK! echo Extracting MANIFEST sed >MANIFEST <<'!STUFFY!FUNK!' -e 's/X//' XAfter all the cdiff kits are run you should have the following files: X XFilename Kit Description X-------- --- ----------- XMANIFEST 1 This file. XREADME 1 Instructions. Xcdiff.c 1 The program. Xpatchlevel.h 1 The patch level of cdiff. !STUFFY!FUNK! echo Extracting patchlevel.h sed >patchlevel.h <<'!STUFFY!FUNK!' -e 's/X//' X#define PATCHLEVEL 0 !STUFFY!FUNK! echo "" echo "End of kit 1 (of 1)" : Someone might mail this, so... exit
aeusemrs@csun.UUCP (06/03/87)
Larry, I am having a little problem with your cdiff program. We are on a 3b5, System V R2.0, using the normal diff, everything works fine. But I compiled your program, and it doesn't produce coherent output. Is there a problem with the output format of our diff, or with cdiff? $ diff /tmp/ojove.c /tmp/jove.c 370a371,372 > #ifdef SYSV > int proc_child(); 371a374,375 > signal(SIGCHLD, SIG_DFL); > #else SYSV 374a379 > #endif SYSV 380a386 > #ifndef SYSV 383a390 > #endif SYSV 391a399,401 > #ifdef SYSV > signal(SIGCHLD, proc_child); > #else SYSV 394a405 > #endif SYSV 401c412 < int OKXonXoff = 0, /* ^S and ^Q initially DON'T work */ --- > int OKXonXoff = 1, /* ^S and ^Q initially DON'T work */ 499a511,512 > if (OKXonXoff) > sg2.c_iflag &= ~IXON; /* disable tty xon/xoff processing */ $ cdiff /tmp/ojove.c /tmp/jove.c *** /tmp/ojove.c Tue Jun 2 18:35:52 1987 --- /tmp/jove.c Tue Jun 2 18:35:27 1987 *************** *** 368,374 **** --- 368,378 ---- int pid, (*old_int)() = signal(SIGINT, SIG_IGN), (*old_quit)() = signal(SIGQUIT, SIG_IGN); + #ifdef SYSV + int proc_child(); + signal(SIGCHLD, SIG_DFL); + #else SYSV #ifdef IPROCS sighold(SIGCHLD); #endif *************** *** 371 **** --- 375 ---- *************** *** 377 **** --- 382 ---- *************** *** 380 **** --- 386 ---- *************** *** 388 **** --- 395 ---- *************** *** 391 **** --- 401 ---- *************** *** 397 **** --- 408 ---- *************** *** 496 **** --- 507 ---- $ exit -- Mike Stump, Cal State Univ, Northridge Comp Sci Department uucp: {sdcrdcf, ihnp4, hplabs, ttidca, psivax, csustan}!csun!aeusemrs
clark@b14.UUCP (06/13/87)
In article <4663@sdcrdcf.UUCP>, lwall@sdcrdcf.UUCP (Larry Wall) writes: > Note that cdiff uses a normal diff as a back end, so you'll still need Erik > Baalbergen's diff program that he just posted if you want to run this under Our site seems to have missed Erik's posting. Would some kind soul please mail me the sources for his diff? ------------------------------------------------------------------------------ Clark Williams Intergraph Corp. UUCP: ihnp4!ingr!b14!clark One Madison Industrial Park <<<-------- USnail: mail stop DB1402 Huntsville, AL 35807