Path: utzoo!utgpu!water!watmath!uunet!lll-winken!lll-tis!pacbell!att!mtunx!mtune!ethos!pcid!gizzmo!fthood!egray From: egray@fthood.UUCP Newsgroups: unix-pc.sources Subject: Larry Wall's patch v2.0-11 (2 of 3) Message-ID: <6800071@fthood> Date: 7 Jun 88 16:43:00 GMT Lines: 1993 Nf-ID: #N:fthood:6800071:000:52229 Nf-From: fthood.UUCP!egray Jun 7 11:43:00 1988 This is part 2 of 3 to Larry Wall's patch 2.0-11 Emmet P. Gray US Army, HQ III Corps & Fort Hood ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV Directorate of Engineering & Housing Environmental Management Office Fort Hood, TX 76544-5057 ------------------------------------------------------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # config.h.SH # inp.c # inp.h # malloc.c # patch.c # util.h # version.c # version.h # This archive created: Tue Jun 7 11:32:44 1988 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'config.h.SH'" '(4619 characters)' if test -f 'config.h.SH' then echo shar: "will not over-write existing file 'config.h.SH'" else sed 's/^X//' << \SHAR_EOF > 'config.h.SH' Xcase $CONFIG in X'') X if test ! -f config.sh; then X ln ../config.sh . || \ X ln ../../config.sh . || \ X ln ../../../config.sh . || \ X (echo "Can't find config.sh."; exit 1) X echo "Using config.sh from above..." X fi X . ./config.sh X ;; Xesac Xecho "Extracting config.h (with variable substitutions)" Xcat <config.h X/* config.h X * This file was produced by running the config.h.SH script, which X * gets its values from config.sh, which is generally produced by X * running Configure. X * X * Feel free to modify any of this as the need arises. Note, however, X * that running config.h.SH again will wipe out any changes you've made. X * For a more permanent change edit config.sh and rerun config.h.SH. X */ X X X/* EUNICE: X * This symbol, if defined, indicates that the program is being compiled X * under the EUNICE package under VMS. The program will need to handle X * things like files that don't go away the first time you unlink them, X * due to version numbering. It will also need to compensate for lack X * of a respectable link() command. X */ X/* VMS: X * This symbol, if defined, indicates that the program is running under X * VMS. It is currently only set in conjunction with the EUNICE symbol. X */ X#$d_eunice EUNICE /**/ X#$d_eunice VMS /**/ X X/* CPPSTDIN: X * This symbol contains the first part of the string which will invoke X * the C preprocessor on the standard input and produce to standard X * output. Typical value of "cc -E" or "/lib/cpp". X */ X/* CPPMINUS: X * This symbol contains the second part of the string which will invoke X * the C preprocessor on the standard input and produce to standard X * output. This symbol will have the value "-" if CPPSTDIN needs a minus X * to specify standard input, otherwise the value is "". X */ X#define CPPSTDIN "$cppstdin" X#define CPPMINUS "$cppminus" X X/* CHARSPRINTF: X * This symbol is defined if this system declares "char *sprintf()" in X * stdio.h. The trend seems to be to declare it as "int sprintf()". It X * is up to the package author to declare sprintf correctly based on the X * symbol. X */ X#$d_charsprf CHARSPRINTF /**/ X X/* FLEXFILENAMES: X * This symbol, if defined, indicates that the system supports filenames X * longer than 14 characters. X */ X#$d_flexfnam FLEXFILENAMES /**/ X X/* index: X * This preprocessor symbol is defined, along with rindex, if the system X * uses the strchr and strrchr routines instead. X */ X/* rindex: X * This preprocessor symbol is defined, along with index, if the system X * uses the strchr and strrchr routines instead. X */ X#$d_index index strchr /* cultural */ X#$d_index rindex strrchr /* differences? */ X X/* VOIDSIG: X * This symbol is defined if this system declares "void (*signal())()" in X * signal.h. The old way was to declare it as "int (*signal())()". It X * is up to the package author to declare things correctly based on the X * symbol. X */ X#$d_voidsig VOIDSIG /**/ X X/* Reg1: X * This symbol, along with Reg2, Reg3, etc. is either the word "register" X * or null, depending on whether the C compiler pays attention to this X * many register declarations. The intent is that you don't have to X * order your register declarations in the order of importance, so you X * can freely declare register variables in sub-blocks of code and as X * function parameters. Do not use Reg more than once per routine. X */ X X#define Reg1 $reg1 /**/ X#define Reg2 $reg2 /**/ X#define Reg3 $reg3 /**/ X#define Reg4 $reg4 /**/ X#define Reg5 $reg5 /**/ X#define Reg6 $reg6 /**/ X#define Reg7 $reg7 /**/ X#define Reg8 $reg8 /**/ X#define Reg9 $reg9 /**/ X#define Reg10 $reg10 /**/ X#define Reg11 $reg11 /**/ X#define Reg12 $reg12 /**/ X#define Reg13 $reg13 /**/ X#define Reg14 $reg14 /**/ X#define Reg15 $reg15 /**/ X#define Reg16 $reg16 /**/ X X/* VOIDFLAGS: X * This symbol indicates how much support of the void type is given by this X * compiler. What various bits mean: X * X * 1 = supports declaration of void X * 2 = supports arrays of pointers to functions returning void X * 4 = supports comparisons between pointers to void functions and X * addresses of void functions X * X * The package designer should define VOIDUSED to indicate the requirements X * of the package. This can be done either by #defining VOIDUSED before X * including config.h, or by defining defvoidused in Myinit.U. If the X * level of void support necessary is not present, defines void to int. X */ X#ifndef VOIDUSED X#define VOIDUSED $defvoidused X#endif X#define VOIDFLAGS $voidflags X#if (VOIDFLAGS & VOIDUSED) != VOIDUSED X#$define void int /* is void to be avoided? */ X#$define M_VOID /* Xenix strikes again */ X#endif X X!GROK!THIS! SHAR_EOF if test 4619 -ne "`wc -c < 'config.h.SH'`" then echo shar: "error transmitting 'config.h.SH'" '(should have been 4619 characters)' fi fi echo shar: "extracting 'inp.c'" '(8134 characters)' if test -f 'inp.c' then echo shar: "will not over-write existing file 'inp.c'" else sed 's/^X//' << \SHAR_EOF > 'inp.c' X/* $Header: inp.c,v 2.0.1.1 88/06/03 15:06:13 lwall Locked $ X * X * $Log: inp.c,v $ X * Revision 2.0.1.1 88/06/03 15:06:13 lwall X * patch10: made a little smarter about sccs files X * X * Revision 2.0 86/09/17 15:37:02 lwall X * Baseline for netwide release. X * X */ X X#include "EXTERN.h" X#include "common.h" X#include "util.h" X#include "pch.h" X#include "INTERN.h" X#include "inp.h" X X/* Input-file-with-indexable-lines abstract type */ X Xstatic long i_size; /* size of the input file */ Xstatic char *i_womp; /* plan a buffer for entire file */ Xstatic char **i_ptr; /* pointers to lines in i_womp */ X Xstatic int tifd = -1; /* plan b virtual string array */ Xstatic char *tibuf[2]; /* plan b buffers */ Xstatic LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */ Xstatic LINENUM lines_per_buf; /* how many lines per buffer */ Xstatic int tireclen; /* length of records in tmp file */ X X/* New patch--prepare to edit another file. */ X Xvoid Xre_input() X{ X if (using_plan_a) { X i_size = 0; X#ifndef lint X if (i_ptr != Null(char**)) X free((char *)i_ptr); X#endif X if (i_womp != Nullch) X free(i_womp); X i_womp = Nullch; X i_ptr = Null(char **); X } X else { X using_plan_a = TRUE; /* maybe the next one is smaller */ X Close(tifd); X tifd = -1; X free(tibuf[0]); X free(tibuf[1]); X tibuf[0] = tibuf[1] = Nullch; X tiline[0] = tiline[1] = -1; X tireclen = 0; X } X} X X/* Constuct the line index, somehow or other. */ X Xvoid Xscan_input(filename) Xchar *filename; X{ X if (!plan_a(filename)) X plan_b(filename); X if (verbose) { X say3("Patching file %s using Plan %s...\n", filename, X (using_plan_a ? "A" : "B") ); X } X} X X/* Try keeping everything in memory. */ X Xbool Xplan_a(filename) Xchar *filename; X{ X int ifd; X Reg1 char *s; X Reg2 LINENUM iline; X X if (ok_to_create_file && stat(filename, &filestat) < 0) { X if (verbose) X say2("(Creating file %s...)\n",filename); X makedirs(filename, TRUE); X close(creat(filename, 0666)); X } X if (stat(filename, &filestat) < 0) { X Sprintf(buf, "RCS/%s%s", filename, RCSSUFFIX); X if (stat(buf, &filestat) >= 0 || stat(buf+4, &filestat) >= 0) { X Sprintf(buf, CHECKOUT, filename); X if (verbose) X say2("Can't find %s--attempting to check it out from RCS.\n", X filename); X if (system(buf) || stat(filename, &filestat)) X fatal2("Can't check out %s.\n", filename); X } X else { X Sprintf(buf+20, "SCCS/%s%s", SCCSPREFIX, filename); X if (stat(s=buf+20, &filestat) >= 0 || X stat(s=buf+25, &filestat) >= 0) { X Sprintf(buf, GET, s); X if (verbose) X say2("Can't find %s--attempting to get it from SCCS.\n", X filename); X if (system(buf) || stat(filename, &filestat)) X fatal2("Can't get %s.\n", filename); X } X else X fatal2("Can't find %s.\n", filename); X } X } X filemode = filestat.st_mode; X if ((filemode & S_IFMT) & ~S_IFREG) X fatal2("%s is not a normal file--can't patch.\n", filename); X i_size = filestat.st_size; X if (out_of_mem) { X set_hunkmax(); /* make sure dynamic arrays are allocated */ X out_of_mem = FALSE; X return FALSE; /* force plan b because plan a bombed */ X } X#ifdef lint X i_womp = Nullch; X#else X i_womp = malloc((MEM)(i_size+2)); /* lint says this may alloc less than */ X /* i_size, but that's okay, I think. */ X#endif X if (i_womp == Nullch) X return FALSE; X if ((ifd = open(filename, 0)) < 0) X fatal2("Can't open file %s\n", filename); X#ifndef lint X if (read(ifd, i_womp, (int)i_size) != i_size) { X Close(ifd); /* probably means i_size > 15 or 16 bits worth */ X free(i_womp); /* at this point it doesn't matter if i_womp was */ X return FALSE; /* undersized. */ X } X#endif X Close(ifd); X if (i_size && i_womp[i_size-1] != '\n') X i_womp[i_size++] = '\n'; X i_womp[i_size] = '\0'; X X /* count the lines in the buffer so we know how many pointers we need */ X X iline = 0; X for (s=i_womp; *s; s++) { X if (*s == '\n') X iline++; X } X#ifdef lint X i_ptr = Null(char**); X#else X i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *))); X#endif X if (i_ptr == Null(char **)) { /* shucks, it was a near thing */ X free((char *)i_womp); X return FALSE; X } X X /* now scan the buffer and build pointer array */ X X iline = 1; X i_ptr[iline] = i_womp; X for (s=i_womp; *s; s++) { X if (*s == '\n') X i_ptr[++iline] = s+1; /* these are NOT null terminated */ X } X input_lines = iline - 1; X X /* now check for revision, if any */ X X if (revision != Nullch) { X if (!rev_in_string(i_womp)) { X if (force) { X if (verbose) X say2( X"Warning: this file doesn't appear to be the %s version--patching anyway.\n", X revision); X } X else { X ask2( X"This file doesn't appear to be the %s version--patch anyway? [n] ", X revision); X if (*buf != 'y') X fatal1("Aborted.\n"); X } X } X else if (verbose) X say2("Good. This file appears to be the %s version.\n", X revision); X } X return TRUE; /* plan a will work */ X} X X/* Keep (virtually) nothing in memory. */ X Xvoid Xplan_b(filename) Xchar *filename; X{ X Reg3 FILE *ifp; X Reg1 int i = 0; X Reg2 int maxlen = 1; X Reg4 bool found_revision = (revision == Nullch); X X using_plan_a = FALSE; X if ((ifp = fopen(filename, "r")) == Nullfp) X fatal2("Can't open file %s\n", filename); X if ((tifd = creat(TMPINNAME, 0666)) < 0) X fatal2("Can't open file %s\n", TMPINNAME); X while (fgets(buf, sizeof buf, ifp) != Nullch) { X if (revision != Nullch && !found_revision && rev_in_string(buf)) X found_revision = TRUE; X if ((i = strlen(buf)) > maxlen) X maxlen = i; /* find longest line */ X } X if (revision != Nullch) { X if (!found_revision) { X if (force) { X if (verbose) X say2( X"Warning: this file doesn't appear to be the %s version--patching anyway.\n", X revision); X } X else { X ask2( X"This file doesn't appear to be the %s version--patch anyway? [n] ", X revision); X if (*buf != 'y') X fatal1("Aborted.\n"); X } X } X else if (verbose) X say2("Good. This file appears to be the %s version.\n", X revision); X } X Fseek(ifp, 0L, 0); /* rewind file */ X lines_per_buf = BUFFERSIZE / maxlen; X tireclen = maxlen; X tibuf[0] = malloc((MEM)(BUFFERSIZE + 1)); X tibuf[1] = malloc((MEM)(BUFFERSIZE + 1)); X if (tibuf[1] == Nullch) X fatal1("Can't seem to get enough memory.\n"); X for (i=1; ; i++) { X if (! (i % lines_per_buf)) /* new block */ X if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE) X fatal1("patch: can't write temp file.\n"); X if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp) X == Nullch) { X input_lines = i - 1; X if (i % lines_per_buf) X if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE) X fatal1("patch: can't write temp file.\n"); X break; X } X } X Fclose(ifp); X Close(tifd); X if ((tifd = open(TMPINNAME, 0)) < 0) { X fatal2("Can't reopen file %s\n", TMPINNAME); X } X} X X/* Fetch a line from the input file, \n terminated, not necessarily \0. */ X Xchar * Xifetch(line,whichbuf) XReg1 LINENUM line; Xint whichbuf; /* ignored when file in memory */ X{ X if (line < 1 || line > input_lines) X return ""; X if (using_plan_a) X return i_ptr[line]; X else { X LINENUM offline = line % lines_per_buf; X LINENUM baseline = line - offline; X X if (tiline[0] == baseline) X whichbuf = 0; X else if (tiline[1] == baseline) X whichbuf = 1; X else { X tiline[whichbuf] = baseline; X#ifndef lint /* complains of long accuracy */ X Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0); X#endif X if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0) X fatal2("Error reading tmp file %s.\n", TMPINNAME); X } X return tibuf[whichbuf] + (tireclen*offline); X } X} X X/* True if the string argument contains the revision number we want. */ X Xbool Xrev_in_string(string) Xchar *string; X{ X Reg1 char *s; X Reg2 int patlen; X X if (revision == Nullch) X return TRUE; X patlen = strlen(revision); X if (strnEQ(string,revision,patlen) && isspace(s[patlen])) X return TRUE; X for (s = string; *s; s++) { X if (isspace(*s) && strnEQ(s+1, revision, patlen) && X isspace(s[patlen+1] )) { X return TRUE; X } X } X return FALSE; X} X SHAR_EOF if test 8134 -ne "`wc -c < 'inp.c'`" then echo shar: "error transmitting 'inp.c'" '(should have been 8134 characters)' fi fi echo shar: "extracting 'inp.h'" '(473 characters)' if test -f 'inp.h' then echo shar: "will not over-write existing file 'inp.h'" else sed 's/^X//' << \SHAR_EOF > 'inp.h' X/* $Header: inp.h,v 2.0 86/09/17 15:37:25 lwall Exp $ X * X * $Log: inp.h,v $ X * Revision 2.0 86/09/17 15:37:25 lwall X * Baseline for netwide release. X * X */ X XEXT LINENUM input_lines INIT(0); /* how long is input file in lines */ XEXT LINENUM last_frozen_line INIT(0); /* how many input lines have been */ X /* irretractibly output */ X Xbool rev_in_string(); Xvoid scan_input(); Xbool plan_a(); /* returns false if insufficient memory */ Xvoid plan_b(); Xchar *ifetch(); X SHAR_EOF if test 473 -ne "`wc -c < 'inp.h'`" then echo shar: "error transmitting 'inp.h'" '(should have been 473 characters)' fi fi echo shar: "extracting 'malloc.c'" '(12262 characters)' if test -f 'malloc.c' then echo shar: "will not over-write existing file 'malloc.c'" else sed 's/^X//' << \SHAR_EOF > 'malloc.c' X/* X * @(#)nmalloc.c 1 (Caltech) 2/21/82 X * X * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs X * X * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD. X * X * This is a very fast storage allocator. It allocates blocks of a small X * number of different sizes, and keeps free lists of each size. Blocks X * that don't exactly fit are passed up to the next larger size. In this X * implementation, the available sizes are (2^n)-4 (or -16) bytes long. X * This is designed for use in a program that uses vast quantities of X * memory, but bombs when it runs out. To make it a little better, it X * warns the user when he starts to get near the end. X * X * June 84, ACT: modified rcheck code to check the range given to malloc, X * rather than the range determined by the 2-power used. X * X * Jan 85, RMS: calls malloc_warning to issue warning on nearly full. X * No longer Emacs-specific; can serve as all-purpose malloc for GNU. X * You should call malloc_init to reinitialize after loading dumped Emacs. X * Call malloc_stats to get info on memory stats if MSTATS turned on. X * realloc knows how to return same block given, just changing its size, X * if the power of 2 is correct. X */ X X/* X * nextf[i] is the pointer to the next free block of size 2^(i+3). The X * smallest allocatable block is 8 bytes. The overhead information will X * go in the first int of the block, and the returned pointer will point X * to the second. X * X#ifdef MSTATS X * nmalloc[i] is the difference between the number of mallocs and frees X * for a given block size. X#endif /* MSTATS */ X */ X X#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ X#define ISFREE ((char) 0x54) /* magic byte that implies free block */ X /* this is for error checking only */ X Xextern char etext; X X/* end of the program; can be changed by calling init_malloc */ Xstatic char *endofpure = &etext; X X#ifdef MSTATS Xstatic int nmalloc[30]; Xstatic int nmal, nfre; X#endif /* MSTATS */ X X/* If range checking is not turned on, all we have is a flag indicating X whether memory is allocated, an index in nextf[], and a size field; to X realloc() memory we copy either size bytes or 1<<(index+3) bytes depending X on whether the former can hold the exact size (given the value of X 'index'). If range checking is on, we always need to know how much space X is allocated, so the 'size' field is never used. */ X Xstruct mhead { X char mh_alloc; /* ISALLOC or ISFREE */ X char mh_index; /* index in nextf[] */ X/* Remainder are valid only when block is allocated */ X unsigned short mh_size; /* size, if < 0x10000 */ X#ifdef rcheck X unsigned mh_nbytes; /* number of bytes allocated */ X int mh_magic4; /* should be == MAGIC4 */ X#endif /* rcheck */ X }; X X/* Access free-list pointer of a block. X It is stored at block + 4. X This is not a field in the mhead structure X because we want sizeof (struct mhead) X to describe the overhead for when the block is in use, X and we do not want the free-list pointer to count in that. */ X X#define CHAIN(a) \ X (*(struct mhead **) (sizeof (char *) + (char *) (a))) X X#ifdef rcheck X X/* To implement range checking, we write magic values in at the beginning and X end of each allocated block, and make sure they are undisturbed whenever a X free or a realloc occurs. */ X/* Written in each of the 4 bytes following the block's real space */ X#define MAGIC1 0x55 X/* Written in the 4 bytes before the block's real space */ X#define MAGIC4 0x55555555 X#define ASSERT(p) if (!(p)) botch("p"); else Xstatic Xbotch(s) X char *s; X{ X X printf("assertion botched: %s\n", s); X abort(); X} X#define EXTRA 4 /* 4 bytes extra for MAGIC1s */ X#else X#define ASSERT(p) X#define EXTRA 0 X#endif /* rcheck */ X X/* nextf[i] is free list of blocks of size 2**(i + 3) */ X Xstatic struct mhead *nextf[30]; X X#ifdef M_WARN X/* Number of bytes of writable memory we can expect to be able to get */ Xstatic int lim_data; X/* Level number of warnings already issued. X 0 -- no warnings issued. X 1 -- 75% warning already issued. X 2 -- 85% warning already issued. X*/ Xstatic int warnlevel; X#endif /* M_WARN */ X X/* nonzero once initial bunch of free blocks made */ Xstatic int gotpool; X X/* Cause reinitialization based on job parameters; X also declare where the end of pure storage is. */ Xmalloc_init (end) X char *end; { X endofpure = end; X#ifdef M_WARN X lim_data = 0; X warnlevel = 0; X#endif /* M_WARN */ X } X Xstatic Xmorecore (nu) /* ask system for more memory */ X register int nu; { /* size index to get more of */ X char *sbrk (); X register char *cp; X register int nblks; X register int siz; X X#ifdef M_WARN X#ifndef BSD42 X#ifdef USG X extern long ulimit (); X if (lim_data == 0) /* find out how much we can get */ X lim_data = ulimit (3, 0) - TEXT_START; X#else /*HMS: was endif */ X if (lim_data == 0) /* find out how much we can get */ X lim_data = vlimit (LIM_DATA, -1); X#endif /* USG */ /HMS:* was not here */ X#else X if (lim_data == 0) { X struct rlimit XXrlimit; X X getrlimit (RLIMIT_DATA, &XXrlimit); X lim_data = XXrlimit.rlim_cur;} /* soft limit */ X#endif /* BSD42 */ X#endif /* M_WARN */ X X /* On initial startup, get two blocks of each size up to 1k bytes */ X if (!gotpool) X getpool (), getpool (), gotpool = 1; X X /* Find current end of memory and issue warning if getting near max */ X X cp = sbrk (0); X siz = cp - endofpure; X#ifdef M_WARN X switch (warnlevel) { X case 0: X if (siz > (lim_data / 4) * 3) { X warnlevel++; X malloc_warning ("Warning: past 75% of memory limit");} X break; X case 1: X if (siz > (lim_data / 20) * 17) { X warnlevel++; X malloc_warning ("Warning: past 85% of memory limit");} X break; X case 2: X if (siz > (lim_data / 20) * 19) { X warnlevel++; X malloc_warning ("Warning: past 95% of memory limit");} X break;} X#endif /* M_WARN */ X X if ((int) cp & 0x3ff) /* land on 1K boundaries */ X sbrk (1024 - ((int) cp & 0x3ff)); X X /* Take at least 2k, and figure out how many blocks of the desired size we're about to get */ X nblks = 1; X if ((siz = nu) < 8) X nblks = 1 << ((siz = 8) - nu); X X if ((cp = sbrk (1 << (siz + 3))) == (char *) -1) X return; /* no more room! */ X if ((int) cp & 7) { /* shouldn't happen, but just in case */ X cp = (char *) (((int) cp + 8) & ~7); X nblks--;} X X /* save new header and link the nblks blocks together */ X nextf[nu] = (struct mhead *) cp; X siz = 1 << (nu + 3); X while (1) { X ((struct mhead *) cp) -> mh_alloc = ISFREE; X ((struct mhead *) cp) -> mh_index = nu; X if (--nblks <= 0) break; X CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz); X cp += siz;} X/* CHAIN ((struct mhead *) cp) = 0; /* since sbrk() returns cleared core, this is already set */ X } X Xstatic Xgetpool () { X register int nu; X register char *cp = sbrk (0); X X if ((int) cp & 0x3ff) /* land on 1K boundaries */ X sbrk (1024 - ((int) cp & 0x3ff)); X X /* Get 2k of storage */ X X cp = sbrk (04000); X if (cp == (char *) -1) X return; X X /* Divide it into an initial 8-word block X plus one block of size 2**nu for nu = 3 ... 10. */ X X CHAIN (cp) = nextf[0]; X nextf[0] = (struct mhead *) cp; X ((struct mhead *) cp) -> mh_alloc = ISFREE; X ((struct mhead *) cp) -> mh_index = 0; X cp += 8; X X for (nu = 0; nu < 7; nu++) { X CHAIN (cp) = nextf[nu]; X nextf[nu] = (struct mhead *) cp; X ((struct mhead *) cp) -> mh_alloc = ISFREE; X ((struct mhead *) cp) -> mh_index = nu; X cp += 8 << nu;}} X Xchar * Xmalloc (n) /* get a block */ X unsigned n; { X register struct mhead *p; X register unsigned int nbytes; X register int nunits = 0; X X /* Figure out how many bytes are required, rounding up to the nearest X multiple of 4, then figure out which nextf[] area to use */ X nbytes = (n + sizeof *p + EXTRA + 3) & ~3; X { X register unsigned int shiftr = (nbytes - 1) >> 2; X X while (shiftr >>= 1) X nunits++; X } X X /* If there are no blocks of the appropriate size, go get some */ X /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */ X if (nextf[nunits] == 0) X morecore (nunits); X X /* Get one block off the list, and set the new list head */ X if ((p = nextf[nunits]) == 0) X return 0; X nextf[nunits] = CHAIN (p); X X /* Check for free block clobbered */ X /* If not for this check, we would gobble a clobbered free chain ptr */ X /* and bomb out on the NEXT allocate of this size block */ X if (p -> mh_alloc != ISFREE || p -> mh_index != nunits) X#ifdef rcheck X botch ("block on free list clobbered"); X#else X abort (); X#endif /* rcheck */ X X /* Fill in the info, and if range checking, set up the magic numbers */ X p -> mh_alloc = ISALLOC; X#ifdef rcheck X p -> mh_nbytes = n; X p -> mh_magic4 = MAGIC4; X { X register char *m = (char *) (p + 1) + n; X X *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1; X } X#else X p -> mh_size = n; X#endif /* rcheck */ X#ifdef MSTATS X nmalloc[nunits]++; X nmal++; X#endif /* MSTATS */ X return (char *) (p + 1);} X Xfree (mem) X char *mem; { X register struct mhead *p; X { X register char *ap = mem; X X ASSERT (ap != 0); X p = (struct mhead *) ap - 1; X ASSERT (p -> mh_alloc == ISALLOC); X#ifdef rcheck X ASSERT (p -> mh_magic4 == MAGIC4); X ap += p -> mh_nbytes; X ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1); X ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1); X#endif /* rcheck */ X } X { X register int nunits = p -> mh_index; X X ASSERT (nunits <= 29); X p -> mh_alloc = ISFREE; X CHAIN (p) = nextf[nunits]; X nextf[nunits] = p; X#ifdef MSTATS X nmalloc[nunits]--; X nfre++; X#endif /* MSTATS */ X } X } X Xchar * Xrealloc (mem, n) X char *mem; X register unsigned n; { X register struct mhead *p; X register unsigned int tocopy; X register int nbytes; X register int nunits; X X if ((p = (struct mhead *) mem) == 0) X return malloc (n); X p--; X nunits = p -> mh_index; X ASSERT (p -> mh_alloc == ISALLOC); X#ifdef rcheck X ASSERT (p -> mh_magic4 == MAGIC4); X { X register char *m = mem + (tocopy = p -> mh_nbytes); X ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1); X ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1); X } X#else X if (p -> mh_index >= 13) X tocopy = (1 << (p -> mh_index + 3)) - sizeof *p; X else X tocopy = p -> mh_size; X#endif /* rcheck */ X X /* See if desired size rounds to same power of 2 as actual size. */ X nbytes = (n + sizeof *p + EXTRA + 7) & ~7; X X /* If ok, use the same block, just marking its size as changed. */ X if (nbytes > (4 << nunits) && nbytes <= (8 << nunits)) { X#ifdef rcheck X register char *m = mem + tocopy; X *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0; X p-> mh_nbytes = n; X m = mem + n; X *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; X#else X p -> mh_size = n; X#endif /* rcheck */ X return mem;} X X if (n < tocopy) X tocopy = n; X { X register char *new; X void bcopy(); /*HMS: here? */ X X if ((new = malloc (n)) == 0) X return 0; X bcopy (mem, new, tocopy); X free (mem); X return new; X } X } X X#ifdef MSTATS X/* Return statistics describing allocation of blocks of size 2**n. */ X Xstruct mstats_value { X int blocksize; X int nfree; X int nused; X }; X Xstruct mstats_value Xmalloc_stats (size) X int size; { X struct mstats_value v; X register int i; X register struct mhead *p; X X v.nfree = 0; X X if (size < 0 || size >= 30) { X v.blocksize = 0; X v.nused = 0; X return v;} X X v.blocksize = 1 << (size + 3); X v.nused = nmalloc[size]; X X for (p = nextf[size]; p; p = CHAIN (p)) X v.nfree++; X X return v;} X#endif X X/* how much space is available? */ X Xunsigned freespace() { X register int i, j; X register struct mhead *p; X register unsigned space = 0; X int local; /* address only is used */ X X space = (char *)&local - sbrk(0); /* stack space */ X X for (i = 0; i < 30; i++) { X for (j = 0, p = nextf[i]; p; p = CHAIN (p), j++) ; X space += j * (1 << (i + 3));} X X return(space);} X X/* How big is this cell? */ X Xunsigned mc_size(cp) X char *cp;{ X register struct mhead *p; X X if ((p = (struct mhead *) cp) == 0) { X /*HMS? */ X } X p--; X#ifdef rcheck X return p -> mh_nbytes; X#else X return (1 << (p -> mh_index + 3)) - sizeof *p; X/**/ X/* if (p -> mh_index >= 13) X/* return (1 << (p -> mh_index + 3)) - sizeof *p; X/* else X/* return p -> mh_size; X/**/ X#endif /* rcheck */ X } X X/*HMS: Really should use memcpy, if available... */ X Xvoid bcopy(source, dest, len) X register char *source, *dest; X register len; { X register i; X X for (i = 0; i < len; i++) X *dest++ = *source++;} SHAR_EOF if test 12262 -ne "`wc -c < 'malloc.c'`" then echo shar: "error transmitting 'malloc.c'" '(should have been 12262 characters)' fi fi echo shar: "extracting 'patch.c'" '(18908 characters)' if test -f 'patch.c' then echo shar: "will not over-write existing file 'patch.c'" else sed 's/^X//' << \SHAR_EOF > 'patch.c' Xchar rcsid[] = X "$Header: patch.c,v 2.0.1.5 88/06/03 15:09:37 lwall Locked $"; X X/* patch - a program to apply diffs to original files X * X * Copyright 1986, Larry Wall X * X * This program may be copied as long as you don't try to make any X * money off of it, or pretend that you wrote it. X * X * $Log: patch.c,v $ X * Revision 2.0.1.5 88/06/03 15:09:37 lwall X * patch10: exit code improved. X * patch10: better support for non-flexfilenames. X * X * Revision 2.0.1.4 87/02/16 14:00:04 lwall X * Short replacement caused spurious "Out of sync" message. X * X * Revision 2.0.1.3 87/01/30 22:45:50 lwall X * Improved diagnostic on sync error. X * Moved do_ed_script() to pch.c. X * X * Revision 2.0.1.2 86/11/21 09:39:15 lwall X * Fuzz factor caused offset of installed lines. X * X * Revision 2.0.1.1 86/10/29 13:10:22 lwall X * Backwards search could terminate prematurely. X * X * Revision 2.0 86/09/17 15:37:32 lwall X * Baseline for netwide release. X * X * Revision 1.5 86/08/01 20:53:24 lwall X * Changed some %d's to %ld's. X * Linted. X * X * Revision 1.4 86/08/01 19:17:29 lwall X * Fixes for machines that can't vararg. X * Added fuzz factor. X * Generalized -p. X * General cleanup. X * X * 85/08/15 van%ucbmonet@berkeley X * Changes for 4.3bsd diff -c. X * X * Revision 1.3 85/03/26 15:07:43 lwall X * Frozen. X * X * Revision 1.2.1.9 85/03/12 17:03:35 lwall X * Changed pfp->_file to fileno(pfp). X * X * Revision 1.2.1.8 85/03/12 16:30:43 lwall X * Check i_ptr and i_womp to make sure they aren't null before freeing. X * Also allow ed output to be suppressed. X * X * Revision 1.2.1.7 85/03/12 15:56:13 lwall X * Added -p option from jromine@uci-750a. X * X * Revision 1.2.1.6 85/03/12 12:12:51 lwall X * Now checks for normalness of file to patch. X * X * Revision 1.2.1.5 85/03/12 11:52:12 lwall X * Added -D (#ifdef) option from joe@fluke. X * X * Revision 1.2.1.4 84/12/06 11:14:15 lwall X * Made smarter about SCCS subdirectories. X * X * Revision 1.2.1.3 84/12/05 11:18:43 lwall X * Added -l switch to do loose string comparison. X * X * Revision 1.2.1.2 84/12/04 09:47:13 lwall X * Failed hunk count not reset on multiple patch file. X * X * Revision 1.2.1.1 84/12/04 09:42:37 lwall X * Branch for sdcrdcf changes. X * X * Revision 1.2 84/11/29 13:29:51 lwall X * Linted. Identifiers uniqified. Fixed i_ptr malloc() bug. Fixed X * multiple calls to mktemp(). Will now work on machines that can only X * read 32767 chars. Added -R option for diffs with new and old swapped. X * Various cosmetic changes. X * X * Revision 1.1 84/11/09 17:03:58 lwall X * Initial revision X * X */ X X#include "INTERN.h" X#include "common.h" X#include "EXTERN.h" X#include "version.h" X#include "util.h" X#include "pch.h" X#include "inp.h" X X/* procedures */ X Xvoid reinitialize_almost_everything(); Xvoid get_some_switches(); XLINENUM locate_hunk(); Xvoid abort_hunk(); Xvoid apply_hunk(); Xvoid init_output(); Xvoid init_reject(); Xvoid copy_till(); Xvoid spew_output(); Xvoid dump_line(); Xbool patch_match(); Xbool similar(); Xvoid re_input(); Xvoid my_exit(); X X/* Apply a set of diffs as appropriate. */ X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X LINENUM where; X LINENUM newwhere; X LINENUM fuzz; X LINENUM mymaxfuzz; X int hunk = 0; X int failed = 0; X int failtotal = 0; X int i; X X setbuf(stderr, serrbuf); X for (i = 0; i 13) X if (s[12] == '.') /* try to preserve difference */ X s[12] = s[13]; /* between .h, .c, .y, etc. */ X s[13] = '\0'; X } X#endif X Strcat(rejname, REJEXT); X } X if (skip_rest_of_patch) { X say4("%d out of %d hunks ignored--saving rejects to %s\n", X failed, hunk, rejname); X } X else { X say4("%d out of %d hunks failed--saving rejects to %s\n", X failed, hunk, rejname); X } X if (move_file(TMPREJNAME, rejname) < 0) X trejkeep = TRUE; X } X set_signals(1); X } X my_exit(failtotal); X} X X/* Prepare to find the next patch to do in the patch file. */ X Xvoid Xreinitialize_almost_everything() X{ X re_patch(); X re_input(); X X input_lines = 0; X last_frozen_line = 0; X X filec = 0; X if (filearg[0] != Nullch && !out_of_mem) { X free(filearg[0]); X filearg[0] = Nullch; X } X X if (outname != Nullch) { X free(outname); X outname = Nullch; X } X X last_offset = 0; X X diff_type = 0; X X if (revision != Nullch) { X free(revision); X revision = Nullch; X } X X reverse = FALSE; X skip_rest_of_patch = FALSE; X X get_some_switches(); X X if (filec >= 2) X fatal1("You may not change to a different patch file.\n"); X} X X/* Process switches and filenames up to next '+' or end of list. */ X Xvoid Xget_some_switches() X{ X Reg1 char *s; X X rejname[0] = '\0'; X Argc_last = Argc; X Argv_last = Argv; X if (!Argc) X return; X for (Argc--,Argv++; Argc; Argc--,Argv++) { X s = Argv[0]; X if (strEQ(s, "+")) { X return; /* + will be skipped by for loop */ X } X if (*s != '-' || !s[1]) { X if (filec == MAXFILEC) X fatal1("Too many file arguments.\n"); X filearg[filec++] = savestr(s); X } X else { X switch (*++s) { X case 'b': X origext = savestr(Argv[1]); X Argc--,Argv++; X break; X case 'B': X origprae = savestr(Argv[1]); X Argc--,Argv++; X break; X case 'c': X diff_type = CONTEXT_DIFF; X break; X case 'd': X if (!*++s) { X Argc--,Argv++; X s = Argv[0]; X } X if (chdir(s) < 0) X fatal2("Can't cd to %s.\n", s); X break; X case 'D': X do_defines = TRUE; X if (!*++s) { X Argc--,Argv++; X s = Argv[0]; X } X if (!isalpha(*s)) X fatal1("Argument to -D not an identifier.\n"); X Sprintf(if_defined, "#ifdef %s\n", s); X Sprintf(not_defined, "#ifndef %s\n", s); X Sprintf(end_defined, "#endif /* %s */\n", s); X break; X case 'e': X diff_type = ED_DIFF; X break; X case 'f': X force = TRUE; X break; X case 'F': X if (*++s == '=') X s++; X maxfuzz = atoi(s); X break; X case 'l': X canonicalize = TRUE; X break; X case 'n': X diff_type = NORMAL_DIFF; X break; X case 'N': X noreverse = TRUE; X break; X case 'o': X outname = savestr(Argv[1]); X Argc--,Argv++; X break; X case 'p': X if (*++s == '=') X s++; X strippath = atoi(s); X break; X case 'r': X Strcpy(rejname, Argv[1]); X Argc--,Argv++; X break; X case 'R': X reverse = TRUE; X break; X case 's': X verbose = FALSE; X break; X case 'S': X skip_rest_of_patch = TRUE; X break; X case 'v': X version(); X break; X#ifdef DEBUGGING X case 'x': X debug = atoi(s+1); X break; X#endif X default: X fatal2("Unrecognized switch: %s\n", Argv[0]); X } X } X } X} X X/* Attempt to find the right place to apply this hunk of patch. */ X XLINENUM Xlocate_hunk(fuzz) XLINENUM fuzz; X{ X Reg1 LINENUM first_guess = pch_first() + last_offset; X Reg2 LINENUM offset; X LINENUM pat_lines = pch_ptrn_lines(); X Reg3 LINENUM max_pos_offset = input_lines - first_guess X - pat_lines + 1; X Reg4 LINENUM max_neg_offset = first_guess - last_frozen_line - 1 X + pch_context(); X X if (!pat_lines) /* null range matches always */ X return first_guess; X if (max_neg_offset >= first_guess) /* do not try lines < 0 */ X max_neg_offset = first_guess - 1; X if (first_guess <= input_lines && patch_match(first_guess, Nulline, fuzz)) X return first_guess; X for (offset = 1; ; offset++) { X Reg5 bool check_after = (offset <= max_pos_offset); X Reg6 bool check_before = (offset <= max_neg_offset); X X if (check_after && patch_match(first_guess, offset, fuzz)) { X#ifdef DEBUGGING X if (debug & 1) X say3("Offset changing from %ld to %ld\n", last_offset, offset); X#endif X last_offset = offset; X return first_guess+offset; X } X else if (check_before && patch_match(first_guess, -offset, fuzz)) { X#ifdef DEBUGGING X if (debug & 1) X say3("Offset changing from %ld to %ld\n", last_offset, -offset); X#endif X last_offset = -offset; X return first_guess-offset; X } X else if (!check_before && !check_after) X return Nulline; X } X} X X/* We did not find the pattern, dump out the hunk so they can handle it. */ X Xvoid Xabort_hunk() X{ X Reg1 LINENUM i; X Reg2 LINENUM pat_end = pch_end(); X /* add in last_offset to guess the same as the previous successful hunk */ X LINENUM oldfirst = pch_first() + last_offset; X LINENUM newfirst = pch_newfirst() + last_offset; X LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1; X LINENUM newlast = newfirst + pch_repl_lines() - 1; X char *stars = (diff_type == NEW_CONTEXT_DIFF ? " ****" : ""); X char *minuses = (diff_type == NEW_CONTEXT_DIFF ? " ----" : " -----"); X X fprintf(rejfp, "***************\n"); X for (i=0; i<=pat_end; i++) { X switch (pch_char(i)) { X case '*': X if (oldlast < oldfirst) X fprintf(rejfp, "*** 0%s\n", stars); X else if (oldlast == oldfirst) X fprintf(rejfp, "*** %ld%s\n", oldfirst, stars); X else X fprintf(rejfp, "*** %ld,%ld%s\n", oldfirst, oldlast, stars); X break; X case '=': X if (newlast < newfirst) X fprintf(rejfp, "--- 0%s\n", minuses); X else if (newlast == newfirst) X fprintf(rejfp, "--- %ld%s\n", newfirst, minuses); X else X fprintf(rejfp, "--- %ld,%ld%s\n", newfirst, newlast, minuses); X break; X case '\n': X fprintf(rejfp, "%s", pfetch(i)); X break; X case ' ': case '-': case '+': case '!': X fprintf(rejfp, "%c %s", pch_char(i), pfetch(i)); X break; X default: X say1("Fatal internal error in abort_hunk().\n"); X abort(); X } X } X} X X/* We found where to apply it (we hope), so do it. */ X Xvoid Xapply_hunk(where) XLINENUM where; X{ X Reg1 LINENUM old = 1; X Reg2 LINENUM lastline = pch_ptrn_lines(); X Reg3 LINENUM new = lastline+1; X#define OUTSIDE 0 X#define IN_IFNDEF 1 X#define IN_IFDEF 2 X#define IN_ELSE 3 X Reg4 int def_state = OUTSIDE; X Reg5 bool R_do_defines = do_defines; X Reg6 LINENUM pat_end = pch_end(); X X where--; X while (pch_char(new) == '=' || pch_char(new) == '\n') X new++; X X while (old <= lastline) { X if (pch_char(old) == '-') { X copy_till(where + old - 1); X if (R_do_defines) { X if (def_state == OUTSIDE) { X fputs(not_defined, ofp); X def_state = IN_IFNDEF; X } X else if (def_state == IN_IFDEF) { X fputs(else_defined, ofp); X def_state = IN_ELSE; X } X fputs(pfetch(old), ofp); X } X last_frozen_line++; X old++; X } X else if (new > pat_end) X break; X else if (pch_char(new) == '+') { X copy_till(where + old - 1); X if (R_do_defines) { X if (def_state == IN_IFNDEF) { X fputs(else_defined, ofp); X def_state = IN_ELSE; X } X else if (def_state == OUTSIDE) { X fputs(if_defined, ofp); X def_state = IN_IFDEF; X } X } X fputs(pfetch(new), ofp); X new++; X } X else { X if (pch_char(new) != pch_char(old)) { X say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n", X pch_hunk_beg() + old, X pch_hunk_beg() + new); X#ifdef DEBUGGING X say3("oldchar = '%c', newchar = '%c'\n", X pch_char(old), pch_char(new)); X#endif X my_exit(1); X } X if (pch_char(new) == '!') { X copy_till(where + old - 1); X if (R_do_defines) { X fputs(not_defined, ofp); X def_state = IN_IFNDEF; X } X while (pch_char(old) == '!') { X if (R_do_defines) { X fputs(pfetch(old), ofp); X } X last_frozen_line++; X old++; X } X if (R_do_defines) { X fputs(else_defined, ofp); X def_state = IN_ELSE; X } X while (pch_char(new) == '!') { X fputs(pfetch(new), ofp); X new++; X } X if (R_do_defines) { X fputs(end_defined, ofp); X def_state = OUTSIDE; X } X } X else { X assert(pch_char(new) == ' '); X old++; X new++; X } X } X } X if (new <= pat_end && pch_char(new) == '+') { X copy_till(where + old - 1); X if (R_do_defines) { X if (def_state == OUTSIDE) { X fputs(if_defined, ofp); X def_state = IN_IFDEF; X } X else if (def_state == IN_IFNDEF) { X fputs(else_defined, ofp); X def_state = IN_ELSE; X } X } X while (new <= pat_end && pch_char(new) == '+') { X fputs(pfetch(new), ofp); X new++; X } X } X if (R_do_defines && def_state != OUTSIDE) { X fputs(end_defined, ofp); X } X} X X/* Open the new file. */ X Xvoid Xinit_output(name) Xchar *name; X{ X ofp = fopen(name, "w"); X if (ofp == Nullfp) X fatal2("patch: can't create %s.\n", name); X} X X/* Open a file to put hunks we can't locate. */ X Xvoid Xinit_reject(name) Xchar *name; X{ X rejfp = fopen(name, "w"); X if (rejfp == Nullfp) X fatal2("patch: can't create %s.\n", name); X} X X/* Copy input file to output, up to wherever hunk is to be applied. */ X Xvoid Xcopy_till(lastline) XReg1 LINENUM lastline; X{ X Reg2 LINENUM R_last_frozen_line = last_frozen_line; X X if (R_last_frozen_line > lastline) X say1("patch: misordered hunks! output will be garbled.\n"); X while (R_last_frozen_line < lastline) { X dump_line(++R_last_frozen_line); X } X last_frozen_line = R_last_frozen_line; X} X X/* Finish copying the input file to the output file. */ X Xvoid Xspew_output() X{ X#ifdef DEBUGGING X if (debug & 256) X say3("il=%ld lfl=%ld\n",input_lines,last_frozen_line); X#endif X if (input_lines) X copy_till(input_lines); /* dump remainder of file */ X Fclose(ofp); X ofp = Nullfp; X} X X/* Copy one line from input to output. */ X Xvoid Xdump_line(line) XLINENUM line; X{ X Reg1 char *s; X Reg2 char R_newline = '\n'; X X /* Note: string is not null terminated. */ X for (s=ifetch(line, 0); putc(*s, ofp) != R_newline; s++) ; X} X X/* Does the patch pattern match at line base+offset? */ X Xbool Xpatch_match(base, offset, fuzz) XLINENUM base; XLINENUM offset; XLINENUM fuzz; X{ X Reg1 LINENUM pline = 1 + fuzz; X Reg2 LINENUM iline; X Reg3 LINENUM pat_lines = pch_ptrn_lines() - fuzz; X X for (iline=base+offset+fuzz; pline <= pat_lines; pline++,iline++) { X if (canonicalize) { X if (!similar(ifetch(iline, (offset >= 0)), X pfetch(pline), X pch_line_len(pline) )) X return FALSE; X } X else if (strnNE(ifetch(iline, (offset >= 0)), X pfetch(pline), X pch_line_len(pline) )) X return FALSE; X } X return TRUE; X} X X/* Do two lines match with canonicalized white space? */ X Xbool Xsimilar(a,b,len) XReg1 char *a; XReg2 char *b; XReg3 int len; X{ X while (len) { X if (isspace(*b)) { /* whitespace (or \n) to match? */ X if (!isspace(*a)) /* no corresponding whitespace? */ X return FALSE; X while (len && isspace(*b) && *b != '\n') X b++,len--; /* skip pattern whitespace */ X while (isspace(*a) && *a != '\n') X a++; /* skip target whitespace */ X if (*a == '\n' || *b == '\n') X return (*a == *b); /* should end in sync */ X } X else if (*a++ != *b++) /* match non-whitespace chars */ X return FALSE; X else X len--; /* probably not necessary */ X } X return TRUE; /* actually, this is not reached */ X /* since there is always a \n */ X} X X/* Exit with cleanup. */ X Xvoid Xmy_exit(status) Xint status; X{ X Unlink(TMPINNAME); X if (!toutkeep) { X Unlink(TMPOUTNAME); X } X if (!trejkeep) { X Unlink(TMPREJNAME); X } X Unlink(TMPPATNAME); X exit(status); X} SHAR_EOF if test 18908 -ne "`wc -c < 'patch.c'`" then echo shar: "error transmitting 'patch.c'" '(should have been 18908 characters)' fi fi echo shar: "extracting 'util.h'" '(1972 characters)' if test -f 'util.h' then echo shar: "will not over-write existing file 'util.h'" else sed 's/^X//' << \SHAR_EOF > 'util.h' X/* $Header: util.h,v 2.0 86/09/17 15:40:06 lwall Exp $ X * X * $Log: util.h,v $ X * Revision 2.0 86/09/17 15:40:06 lwall X * Baseline for netwide release. X * X */ X X/* and for those machine that can't handle a variable argument list */ X X#ifdef CANVARARG X X#define say1 say X#define say2 say X#define say3 say X#define say4 say X#define ask1 ask X#define ask2 ask X#define ask3 ask X#define ask4 ask X#define fatal1 fatal X#define fatal2 fatal X#define fatal3 fatal X#define fatal4 fatal X X#else /* hope they allow multi-line macro actual arguments */ X X#ifdef lint X X#define say1(a) say(a, 0, 0, 0) X#define say2(a,b) say(a, (b)==(b), 0, 0) X#define say3(a,b,c) say(a, (b)==(b), (c)==(c), 0) X#define say4(a,b,c,d) say(a, (b)==(b), (c)==(c), (d)==(d)) X#define ask1(a) ask(a, 0, 0, 0) X#define ask2(a,b) ask(a, (b)==(b), 0, 0) X#define ask3(a,b,c) ask(a, (b)==(b), (c)==(c), 0) X#define ask4(a,b,c,d) ask(a, (b)==(b), (c)==(c), (d)==(d)) X#define fatal1(a) fatal(a, 0, 0, 0) X#define fatal2(a,b) fatal(a, (b)==(b), 0, 0) X#define fatal3(a,b,c) fatal(a, (b)==(b), (c)==(c), 0) X#define fatal4(a,b,c,d) fatal(a, (b)==(b), (c)==(c), (d)==(d)) X X#else /* lint */ X /* if this doesn't work, try defining CANVARARG above */ X#define say1(a) say(a, Nullch, Nullch, Nullch) X#define say2(a,b) say(a, b, Nullch, Nullch) X#define say3(a,b,c) say(a, b, c, Nullch) X#define say4 say X#define ask1(a) ask(a, Nullch, Nullch, Nullch) X#define ask2(a,b) ask(a, b, Nullch, Nullch) X#define ask3(a,b,c) ask(a, b, c, Nullch) X#define ask4 ask X#define fatal1(a) fatal(a, Nullch, Nullch, Nullch) X#define fatal2(a,b) fatal(a, b, Nullch, Nullch) X#define fatal3(a,b,c) fatal(a, b, c, Nullch) X#define fatal4 fatal X X#endif /* lint */ X X/* if neither of the above work, join all multi-line macro calls. */ X#endif X XEXT char serrbuf[BUFSIZ]; /* buffer for stderr */ X Xchar *fetchname(); Xint move_file(); Xvoid copy_file(); Xvoid say(); Xvoid fatal(); Xvoid ask(); Xchar *savestr(); Xvoid set_signals(); Xvoid ignore_signals(); Xvoid makedirs(); SHAR_EOF if test 1972 -ne "`wc -c < 'util.h'`" then echo shar: "error transmitting 'util.h'" '(should have been 1972 characters)' fi fi echo shar: "extracting 'version.c'" '(489 characters)' if test -f 'version.c' then echo shar: "will not over-write existing file 'version.c'" else sed 's/^X//' << \SHAR_EOF > 'version.c' X/* $Header: version.c,v 2.0 86/09/17 15:40:11 lwall Exp $ X * X * $Log: version.c,v $ X * Revision 2.0 86/09/17 15:40:11 lwall X * Baseline for netwide release. X * X */ X X#include "EXTERN.h" X#include "common.h" X#include "util.h" X#include "INTERN.h" X#include "patchlevel.h" X#include "version.h" X X/* Print out the version number and die. */ X Xvoid Xversion() X{ X extern char rcsid[]; X X#ifdef lint X rcsid[0] = rcsid[0]; X#else X fatal3("%s\nPatch level: %d\n", rcsid, PATCHLEVEL); X#endif X} SHAR_EOF if test 489 -ne "`wc -c < 'version.c'`" then echo shar: "error transmitting 'version.c'" '(should have been 489 characters)' fi fi echo shar: "extracting 'version.h'" '(185 characters)' if test -f 'version.h' then echo shar: "will not over-write existing file 'version.h'" else sed 's/^X//' << \SHAR_EOF > 'version.h' X/* $Header: version.h,v 2.0 86/09/17 15:40:14 lwall Exp $ X * X * $Log: version.h,v $ X * Revision 2.0 86/09/17 15:40:14 lwall X * Baseline for netwide release. X * X */ X Xvoid version(); SHAR_EOF if test 185 -ne "`wc -c < 'version.h'`" then echo shar: "error transmitting 'version.h'" '(should have been 185 characters)' fi fi exit 0 # End of shell archive