Context diffs, HELP
Larry Wall
lwall at jpl-devvax.JPL.NASA.GOV
Tue Jul 26 17:24:31 AEST 1988
In article <150 at ispi.UUCP> jbayer at ispi.UUCP writes:
> I have Larry Wall's patch program (it works great), and have a
> need to create some diffs for use with it. I have looked in several
> different manuals and books, but cannot find out how to create the diffs
> with the file names included. According to the patch documentation
> context diffs create a header which specify the file names. However, the
> normal diff command doesn't do that. Is there a PD diff which creates
> diffs in the format that patch likes best? Thanks.
Here's a little thing I whipped together a while back to do just what you want.
It runs your normal diff for you and then turns that into a context diff.
I apologize for posting source to d newsgroups, but this thing's so piddly
small it isn't worth waiting the month for it to get through the moderated
group.
Larry Wall
lwall at jpl-devvax.jpl.nasa.gov
#! /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 $$)
mkdir 2>/dev/null
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 at 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.1.2 87/06/04 11:21:43 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.1.2 87/06/04 11:21:43 lwall
X * Didn't do diffs with less than 3 lines of leading context.
X *
X * Revision 1.1.1.1 87/06/03 11:52:25 lwall
X * Wasn't concatenating overlapping hunks right.
X *
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 if (oldbeg < 1)
X oldbeg = 1;
X newbeg = newmin - context;
X newend = newmax + context;
X if (newbeg < 1)
X newbeg = 1;
X
X if (preoldend < oldbeg - 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 2
!STUFFY!FUNK!
echo ""
echo "End of kit 1 (of 1)"
cat /dev/null >kit1isdone
run=''
config=''
for iskit in 1; do
if test -f kit${iskit}isdone; then
run="$run $iskit"
else
todo="$todo $iskit"
fi
done
case $todo in
'')
echo "You have run all your kits. Please read README."
;;
*) echo "You have run$run."
echo "You still need to run$todo."
;;
esac
: Someone might mail this, so...
exit
More information about the Comp.unix.questions
mailing list