kk@hpkronos.hpl.hp.com (Konstantinos Konstantinides) (08/04/90)
Submitted-by: Konstantinos Konstantinides <kk@hpkronos.hpl.hp.com> Posting-number: Volume 8, Issue 61 Archive-name: xdiff/part01 xdiff is a modified version of cdiff and can display context diffs either on a terminal or under X windows. xdiff produces output similar to the output produced by the 4.3BSD -c option of diff but displays the differences of the two files side by side. xdiff calls diff (1) to generate the raw difference between the two files. To compile you need the Motif libraries. Edit the Makefile, and run "make" Append XDiff into your .Xdefaults file, or put it in /usr/lib/X11/app-defaults. K. Konstantinides kk@hpkronos.hpl.hp.com #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of shell archive." # Contents: xdiff xdiff/Imakefile xdiff/MANIFEST xdiff/Makefile # xdiff/README xdiff/XDiff xdiff/patchlevel.h xdiff/xdiff.1 # xdiff/xdiff.c # Wrapped by argv@turnpike on Fri Aug 3 19:15:30 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test ! -d 'xdiff' ; then echo shar: Creating directory \"'xdiff'\" mkdir 'xdiff' fi if test -f 'xdiff/Imakefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/Imakefile'\" else echo shar: Extracting \"'xdiff/Imakefile'\" \(233 characters\) sed "s/^X//" >'xdiff/Imakefile' <<'END_OF_FILE' X#-------------------------------------------------- X#Imakefile for xdiff X DEFINES = XLOCAL_LIBRARIES = X SYS_LIBRARIES = -lmalloc -lXm -lXt -lX11 X SRCS = xdiff.c X OBJS = xdiff.o X XComplexProgramTarget(xdiff) END_OF_FILE if test 233 -ne `wc -c <'xdiff/Imakefile'`; then echo shar: \"'xdiff/Imakefile'\" unpacked with wrong size! fi # end of 'xdiff/Imakefile' fi if test -f 'xdiff/MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/MANIFEST'\" else echo shar: Extracting \"'xdiff/MANIFEST'\" \(364 characters\) sed "s/^X//" >'xdiff/MANIFEST' <<'END_OF_FILE' XAfter all the xdiff kits are run you should have the following files: X XFilename Kit Description X-------- --- ----------- XMANIFEST 1 This file. XREADME 1 Instructions. Xxdiff.c 1 The program. Xpatchlevel.h 1 The patch level of xdiff Xxdiff.1 1 The man page XXDiff 1 /usr/lib/X11/app-defaults/XDiff X END_OF_FILE if test 364 -ne `wc -c <'xdiff/MANIFEST'`; then echo shar: \"'xdiff/MANIFEST'\" unpacked with wrong size! fi # end of 'xdiff/MANIFEST' fi if test -f 'xdiff/Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/Makefile'\" else echo shar: Extracting \"'xdiff/Makefile'\" \(368 characters\) sed "s/^X//" >'xdiff/Makefile' <<'END_OF_FILE' XDEFS = XCFLAGS = $(DEFS) -O XLDFLAGS = XLIBS = -lmalloc -lXm -lXt -lX11 # -lm X XOBJECTS = xdiff.o X XARCH_FILES = xdiff.c Makefile XDiff patchlevel.h xdiff.1 X Xall: xdiff X Xxdiff: $(OBJECTS) X $(CC) -o xdiff $(LDFLAGS) $(OBJECTS) $(LIBS) X Xtar: xdiff.tar.Z X Xxdiff.tar.Z: $(ARCH_FILES) X tar cf - $(ARCH_FILES) | compress > xdiff.tar.Z X Xclean: X rm -f xdiff *.o core tags a.out END_OF_FILE if test 368 -ne `wc -c <'xdiff/Makefile'`; then echo shar: \"'xdiff/Makefile'\" unpacked with wrong size! fi # end of 'xdiff/Makefile' fi if test -f 'xdiff/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/README'\" else echo shar: Extracting \"'xdiff/README'\" \(528 characters\) sed "s/^X//" >'xdiff/README' <<'END_OF_FILE' Xxdiff is a modified version of cdiff and can display context Xdiffs either on a terminal or under X windows. xdiff Xproduces output similar to the output produced by the 4.3BSD X-c option of diff but displays the differences of the two Xfiles side by side. xdiff calls diff (1) to generate the Xraw difference between the two files. X XTo compile you need the Motif libraries. XEdit the Makefile, and run "make" XAppend XDiff into your .Xdefaults file, or put it in X/usr/lib/X11/app-defaults. X XK. Konstantinides Xkk@hpkronos.hpl.hp.com END_OF_FILE if test 528 -ne `wc -c <'xdiff/README'`; then echo shar: \"'xdiff/README'\" unpacked with wrong size! fi # end of 'xdiff/README' fi if test -f 'xdiff/XDiff' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/XDiff'\" else echo shar: Extracting \"'xdiff/XDiff'\" \(264 characters\) sed "s/^X//" >'xdiff/XDiff' <<'END_OF_FILE' X! X!App-defaults for xdiff X! Xxdiff*geometry: 1100x767 X X!quit operation X Xxdiff*XmText.translations: <Key>q: activate() X X!optional resources X X!xdiff*file1*text.background: X!xdiff*file2*text.background: X!xdiff*text.fontList: hp8.8x16 END_OF_FILE if test 264 -ne `wc -c <'xdiff/XDiff'`; then echo shar: \"'xdiff/XDiff'\" unpacked with wrong size! fi # end of 'xdiff/XDiff' fi if test -f 'xdiff/patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/patchlevel.h'\" else echo shar: Extracting \"'xdiff/patchlevel.h'\" \(85 characters\) sed "s/^X//" >'xdiff/patchlevel.h' <<'END_OF_FILE' X/* #define PATCHLEVEL 4 */ X#define PATCHLEVEL 0 /* new numbering for xdiff.c */ END_OF_FILE if test 85 -ne `wc -c <'xdiff/patchlevel.h'`; then echo shar: \"'xdiff/patchlevel.h'\" unpacked with wrong size! fi # end of 'xdiff/patchlevel.h' fi if test -f 'xdiff/xdiff.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/xdiff.1'\" else echo shar: Extracting \"'xdiff/xdiff.1'\" \(1529 characters\) sed "s/^X//" >'xdiff/xdiff.1' <<'END_OF_FILE' X.\" use -man macros X.TH XDIFF 1L "" "" HP-UX X.\" ========== X.SH NAME Xxdiff \- context diff under X windows X.\" ========== X.SH SYNOPSIS X.B xdiff X[ X.I \-bvt X] [ X.I \-c context X] X.I file1 X.I file2 X.\" ========== X.SH DESCRIPTION X.I xdiff\^ Xis a modified version of \fIcdiff\fR and can display Xcontext diffs either on a terminal or under X windows. X.I xdiff\^ Xproduces output similar to the output produced by the 4.3BSD \-c option of X.I diff Xbut displays the differences of the two files side by side. X\fIxdiff\fR calls \fIdiff (1)\fR to generate the raw difference Xbetween the two files. X.SS OPTIONS X.TP X.I \-b XSimilar to the \-b option in \fIdiff (1)\fR. X.TP X.I \-t XTerminal mode. Display the output on stdout instead of the X display. X(Similar to \fIcdiff\fR). X.TP X.I \-v XPrint the version and patchlevel and exit. X.TP X.I \-c context XUse "context" lines of context instead of the default three. X.SS RESOURCES XUnder X windows the following resources can be used. Additional Xresources can be found in /usr/lib/X11/app-defaults/XDiff, or Xone can use resources specified by \fIXmText(3X)\fR. X X#Geometry X.br Xxdiff*geometry: 1100x767 X.br X#Type "q" over any text to quit xdiff X.br Xxdiff*XmText.translations: <Key>q: activate() X.br X#Text font X.br Xxdiff*text.fontList: X.\" ========== X.SH AUTHORS XLarry Wall, for the original cdiff. X.br XKonstantinos Konstantinides, for the X Window display portion. X.\" ========== X.SH FILES X.I /bin/sh Xis used to locate a X.I diff Xexecutable. X.\" ========== X.SH SEE ALSO X.IR diff (1) END_OF_FILE if test 1529 -ne `wc -c <'xdiff/xdiff.1'`; then echo shar: \"'xdiff/xdiff.1'\" unpacked with wrong size! fi # end of 'xdiff/xdiff.1' fi if test -f 'xdiff/xdiff.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xdiff/xdiff.c'\" else echo shar: Extracting \"'xdiff/xdiff.c'\" \(11667 characters\) sed "s/^X//" >'xdiff/xdiff.c' <<'END_OF_FILE' Xstatic char rcsid[] = "$Header: xdiff.c,v 1.3 90/04/24 11:25:06 kk Exp $"; X X/* cdiff - turns a regular diff into a new-style context diff X * X * Modified as xdiff to display the differences under X windows X * and Motif X * Motif is a trademark of Open Software Foundation, Inc. X * X Window System is a trademark of the Massachusetts Institute of X * Technology. X * X * Usage: xdiff [-b] [-vt] [-c#] file1 file2 X * X * $Log: xdiff.c,v $ X * Revision 1.3 90/04/24 11:25:06 11:25:06 kk (Konstantinos Konstantinides) X * Use getopt to parse arguments X * X * Revision 1.2 90/04/24 09:28:34 09:28:34 kk (Konstantinos Konstantinides) X * X * Revision 1.1 90/04/23 17:29:36 17:29:36 kk (Konstantinos Konstantinides) X * Initial revision for X11 X * Author: K. Konstantinides, Hewlett-Packard Laboratories X * e-mail: konstantinos_konstantinides@hplabs.hp.com X * Copyright: HEWLETT-PACKARD, 1990. X * X * Revision 1.1.1.4 89/01/06 12:31:41 lwall X * patch4: now passes diff switches through X * patch4: handles directories better X * patch4: now quotes filenames passed to subshell X * X * Revision 1.1.1.3 88/08/04 16:08:18 lwall X * patch3: include <stat.h> => <sys/stat.h> X * 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 <sys/stat.h> X#include <ctype.h> X X#include <X11/Intrinsic.h> X#include <X11/Shell.h> X#include <X11/StringDefs.h> X#include <Xm/Xm.h> X#include <Xm/Label.h> X#include <Xm/PushB.h> X#include <Xm/RowColumn.h> X#include <Xm/ScrolledW.h> X#include <Xm/Text.h> X Xchar buf[512] = "diff "; 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; Xint xflag = 1; /* Default - use X windows */ 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 XWidget rowcol1, rowcol2; XDimension oldtop=0, newtop=0; X Xvoid show_buffer(); Xvoid w_print(); Xvoid quitCB(); 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 Widget toplevel; X Widget sw,form; X Widget toplabel1, toplabel2; X Dimension height; X int c; X extern char *optarg; X extern int optind; X X Arg wargs[10]; X int n=0; X X X oldalloc = 512; X oldhunk = malloc(oldalloc); X newalloc = 512; X newhunk = malloc(newalloc); X X X X while(( c=getopt(argc,argv, "bc:tv")) != EOF) X switch(c) { X case 'b': X sprintf(buf+strlen(buf), "-b "); X break; X case 'c': X context = atoi(optarg); X break; X case 'v': X printf("%s\n Patch level: %d\n",rcsid,PATCHLEVEL); X exit(0); X break; X case 't': X xflag = 0; X break; X case '?': X fprintf(stderr,"xdiff [-bvt] [-c context] file1 file2\n"); X exit(1); X break; X } X X if(optind < argc) { X old = argv[optind]; X optind++; X } X else { X fprintf(stderr,"xdiff [-bvt] [-c context] file1 file2\n"); X exit(1); X } X if(optind < argc) new = argv[optind]; X else { X fprintf(stderr,"xdiff [-bvt] [-c context] file1 file2\n"); X exit(1); X } X X if(xflag == 1) X toplevel = XtInitialize(argv[0], "XDiff", NULL, 0, &argc, argv); X X sprintf(buf+strlen(buf), "'%s' '%s'", old, new); X inputfp = popen(buf, "r"); X if (!inputfp) { X fprintf(stderr, "Can't execute %s\n", buf); X exit(1); X } X X stat(old,&statbuf); X if((statbuf.st_mode&S_IFMT) == S_IFDIR) { X sprintf(buf, "%s/%s", old, new); X old = buf; X stat(old,&statbuf); X } X oldfp = fopen(old,"r"); X if (!oldfp) { X fprintf(stderr, "Can't open %s\n", old); X exit(1); X } X X stat(new,&statbuf); X if((statbuf.st_mode&S_IFMT) == S_IFDIR) { X sprintf(buf, "%s/%s", new, old); X new = buf; X stat(new,&statbuf); X } X newfp = fopen(new,"r"); X if (!newfp) { X fprintf(stderr, "Can't open %s\n", new); X exit(1); X } X if(xflag == 0) { X printf("*** %s\t%s", old, ctime(&statbuf.st_mtime)); X printf("--- %s\t%s", new, ctime(&statbuf.st_mtime)); X } X preoldend = -1000; X X if(xflag == 1) { X /* create a scrolled widget */ X n= 0; X XtSetArg(wargs[0], XmNscrollingPolicy, XmAUTOMATIC); X sw = XtCreateManagedWidget("swindow", X xmScrolledWindowWidgetClass, toplevel, wargs, 1); X X n=0; X XtSetArg(wargs[n], XmNorientation,XmHORIZONTAL); n++; X form = XtCreateManagedWidget("form",xmRowColumnWidgetClass, X sw,wargs,n); X X /* create two rowcol widgets for the two files */ X n=0; X XtSetArg(wargs[n], XmNorientation,XmVERTICAL); n++; X XtSetArg(wargs[n], XmNpacking,XmPACK_NONE); n++; X rowcol1 = XtCreateManagedWidget("file1",xmRowColumnWidgetClass, X form,wargs,n); X n=0; X XtSetArg(wargs[n], XmNorientation,XmVERTICAL); n++; X XtSetArg(wargs[n], XmNpacking,XmPACK_NONE); n++; X rowcol2 = XtCreateManagedWidget("file2",xmRowColumnWidgetClass, X form,wargs,n); X X /* put the labels with the file names */ X n=0; X toplabel1 = XtCreateManagedWidget("label1",xmLabelWidgetClass, X rowcol1,NULL,n); X w_print(toplabel1, old); X X toplabel2 = XtCreateManagedWidget("label2",xmLabelWidgetClass, X rowcol2,NULL,n); X w_print(toplabel2, new); X X XtSetArg(wargs[0], XtNheight, &height); X XtGetValues(toplabel2,wargs, 1); X oldtop = newtop = height; X } X X /* This is from cdiff.c */ 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 if(xflag == 1) { X XtRealizeWidget(toplevel); X XtMainLoop(); X } X } X else exit(0); 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 if (xflag == 0) { X fputs("***************\n",stdout); X if (preoldbeg >= preoldend) { X printf("*** %d ****\n", preoldend); X } else { X printf("*** %d,%d ****\n", preoldbeg, preoldend); X } X } X if(xflag == 0) { X if (oldwanted) fputs(oldhunk,stdout); X } X else show_buffer(0, oldhunk); X X oldsize = 0; X *oldhunk = '\0'; X if(xflag == 0) { X if (prenewbeg >= prenewend) { X printf("--- %d ----\n", prenewend); X } else { X printf("--- %d,%d ----\n", prenewbeg, prenewend); X } X } X newwanted = 1; X if(xflag == 0) { X if (newwanted) fputs(newhunk,stdout); X } X else show_buffer(1, newhunk); X X newsize = 0; X *newhunk = '\0'; X} X Xchar * getold(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 * getnew(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} X/*-------------------functions for X11 ---------------------*/ X/* Display text in a XmText widget */ X Xvoid show_buffer(sel, inbuf) X X char *inbuf; X int sel; X{ X Widget text; X int n=0; X Arg wargs[7]; X Position Ypos, Xpos; X Dimension height; X X n=0; X XtSetArg (wargs[n], XmNeditable, FALSE); n++; X XtSetArg (wargs[n], XmNresizeWidth, TRUE); n++; X XtSetArg (wargs[n], XmNresizeHeight, TRUE); n++; X XtSetArg (wargs[n], XmNcolumns, 85); n++; X XtSetArg (wargs[n], XmNy, oldtop); n++; X if(sel == 0) X text = XmCreateText(rowcol1, "text", wargs, n); X else X text = XmCreateText(rowcol2, "text", wargs, n); X X XtManageChild(text); X XmTextSetString(text, inbuf); X X XtSetArg(wargs[0], XtNheight, &height); X XtGetValues(text,wargs, 1); X if(height+oldtop > newtop) newtop = oldtop+height+2; X X if(sel == 1) oldtop = newtop; X X /* add callback to quit */ X XtAddCallback(text, XmNactivateCallback, quitCB,NULL); X} X X/* Print a string on a widget */ X Xvoid w_print(w, string) X Widget w; X char *string; X{ X XmString xmstr; X Arg wargs[2]; X X xmstr = XmStringLtoRCreate(string, XmSTRING_DEFAULT_CHARSET); X XtSetArg(wargs[0], XmNlabelString, xmstr); X XtSetValues(w,wargs, 1); X} X X/* Quit Routine */ X Xvoid quitCB(w, call_data, event) X Widget w; X caddr_t call_data; X XButtonEvent *event; X{ X XtCloseDisplay(XtDisplay(w)); X exit(0); X} X END_OF_FILE if test 11667 -ne `wc -c <'xdiff/xdiff.c'`; then echo shar: \"'xdiff/xdiff.c'\" unpacked with wrong size! fi # end of 'xdiff/xdiff.c' fi echo shar: End of shell archive. exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.