+-+-+-+ Beginning of part 3 +-+-+-+
X    if (ok_to_create_file && stat(filename, &filestat) < 0) `123
X`009if (verbose)
X`009    say2("(Creating file %s...)\n",filename);
X`009makedirs(filename, TRUE);
X`009close(creat(filename, 0666));
X    `125
X    if (stat(filename, &filestat) < 0) `123
X`009Sprintf(buf, "RCS/%s%s", filename, RCSSUFFIX);
X`009if (stat(buf, &filestat) >= 0 `124`124 stat(buf+4, &filestat) >= 0) `123
X`009    Sprintf(buf, CHECKOUT, filename);
X`009    if (verbose)
X`009`009say2("Can't find %s--attempting to check it out from RCS.\n",
X`009`009    filename);
X`009    if (system(buf) `124`124 stat(filename, &filestat))
X`009`009fatal2("Can't check out %s.\n", filename);
X`009`125
X`009else `123
X`009    Sprintf(buf+20, "SCCS/%s%s", SCCSPREFIX, filename);
X`009    if (stat(s=buf+20, &filestat) >= 0 `124`124
X`009      stat(s=buf+25, &filestat) >= 0) `123
X`009`009Sprintf(buf, GET, s);
X`009`009if (verbose)
X`009`009    say2("Can't find %s--attempting to get it from SCCS.\n",
X`009`009`009filename);
X`009`009if (system(buf) `124`124 stat(filename, &filestat))
X`009`009    fatal2("Can't get %s.\n", filename);
X`009    `125
X`009    else
X`009`009fatal2("Can't find %s.\n", filename);
X`009`125
X    `125
X    filemode = filestat.st_mode;
X    if ((filemode & S_IFMT) & `126S_IFREG)
X`009fatal2("%s is not a normal file--can't patch.\n", filename);
X    i_size = filestat.st_size;
X    if (out_of_mem) `123
X`009set_hunkmax();`009`009/* make sure dynamic arrays are allocated */
X`009out_of_mem = FALSE;
X`009return FALSE;`009`009`009/* force plan b because plan a bombed */
X    `125
X#ifdef lint
X    i_womp = Nullch;
X#else
V    i_womp = malloc((MEM)(i_size+2));`009/* lint says this may alloc less tha
Xn*/
X`009`009`009`009`009/* i_size, but that's okay, I think. */
X#endif
X    if (i_womp == Nullch)
X`009return FALSE;
X    if ((ifd = open(filename, 0)) < 0)
X`009fatal2("Can't open file %s\n", filename);
X#ifndef lint
X    if (read(ifd, i_womp, (int)i_size) != i_size) `123
X`009Close(ifd);`009/* probably means i_size > 15 or 16 bits worth */
X`009free(i_womp);`009/* at this point it doesn't matter if i_womp was */
X`009return FALSE;`009/*   undersized. */
X    `125
X#endif
X    Close(ifd);
X    if (i_size && i_womp[i_size-1] != '\n')
X`009i_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++) `123
X`009if (*s == '\n')
X`009    iline++;
X    `125
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 **)) `123`009/* shucks, it was a near thing */
X`009free((char *)i_womp);
X`009return FALSE;
X    `125
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++) `123
X`009if (*s == '\n')
X`009    i_ptr[++iline] = s+1;`009/* these are NOT null terminated */
X    `125
X    input_lines = iline - 1;
X
X    /* now check for revision, if any */
X
X    if (revision != Nullch) `123
X`009if (!rev_in_string(i_womp)) `123
X`009    if (force) `123
X`009`009if (verbose)
X`009`009    say2(
X"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
X`009`009`009revision);
X`009    `125
X`009    else `123
X`009`009ask2(
X"This file doesn't appear to be the %s version--patch anyway? [n] ",
X`009`009    revision);
X`009    if (*buf != 'y')
X`009`009fatal1("Aborted.\n");
X`009    `125
X`009`125
X`009else if (verbose)
X`009    say2("Good.  This file appears to be the %s version.\n",
X`009`009revision);
X    `125
X    return TRUE;`009`009`009/* plan a will work */
X`125
X
X/* Keep (virtually) nothing in memory. */
X
Xvoid
Xplan_b(filename)
Xchar *filename;
X`123
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`009fatal2("Can't open file %s\n", filename);
X    if ((tifd = creat(TMPINNAME, 0666)) < 0)
X`009fatal2("Can't open file %s\n", TMPINNAME);
X    while (fgets(buf, sizeof buf, ifp) != Nullch) `123
X`009if (revision != Nullch && !found_revision && rev_in_string(buf))
X`009    found_revision = TRUE;
X`009if ((i = strlen(buf)) > maxlen)
X`009    maxlen = i;`009`009`009/* find longest line */
X    `125
X    if (revision != Nullch) `123
X`009if (!found_revision) `123
X`009    if (force) `123
X`009`009if (verbose)
X`009`009    say2(
X"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
X`009`009`009revision);
X`009    `125
X`009    else `123
X`009`009ask2(
X"This file doesn't appear to be the %s version--patch anyway? [n] ",
X`009`009    revision);
X`009`009if (*buf != 'y')
X`009`009    fatal1("Aborted.\n");
X`009    `125
X`009`125
X`009else if (verbose)
X`009    say2("Good.  This file appears to be the %s version.\n",
X`009`009revision);
X    `125
X    Fseek(ifp, 0L, 0);`009`009/* 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`009fatal1("Can't seem to get enough memory.\n");
X    for (i=1; ; i++) `123
X`009if (! (i % lines_per_buf))`009/* new block */
X`009    if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
X`009`009fatal1("patch: can't write temp file.\n");
X`009if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
X`009  == Nullch) `123
X`009    input_lines = i - 1;
X`009    if (i % lines_per_buf)
X`009`009if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
X`009`009    fatal1("patch: can't write temp file.\n");
X`009    break;
X`009`125
X    `125
X    Fclose(ifp);
X    Close(tifd);
X    if ((tifd = open(TMPINNAME, 0)) < 0) `123
X`009fatal2("Can't reopen file %s\n", TMPINNAME);
X    `125
X`125
X
X/* Fetch a line from the input file, \n terminated, not necessarily \0. */
X
Xchar *
Xifetch(line,whichbuf)
XReg1 LINENUM line;
Xint whichbuf;`009`009`009`009/* ignored when file in memory */
X`123
X    if (line < 1 `124`124 line > input_lines)
X`009return "";
X    if (using_plan_a)
X`009return i_ptr[line];
X    else `123
X`009LINENUM offline = line % lines_per_buf;
X`009LINENUM baseline = line - offline;
X
X`009if (tiline[0] == baseline)
X`009    whichbuf = 0;
X`009else if (tiline[1] == baseline)
X`009    whichbuf = 1;
X`009else `123
X`009    tiline[whichbuf] = baseline;
X#ifndef lint`009`009/* complains of long accuracy */
X`009    Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
X#endif
X`009    if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
X`009`009fatal2("Error reading tmp file %s.\n", TMPINNAME);
X`009`125
X`009return tibuf[whichbuf] + (tireclen*offline);
X    `125
X`125
X
X/* True if the string argument contains the revision number we want. */
X
Xbool
Xrev_in_string(string)
Xchar *string;
X`123
X    Reg1 char *s;
X    Reg2 int patlen;
X
X    if (revision == Nullch)
X`009return TRUE;
X    patlen = strlen(revision);
X    if (strnEQ(string,revision,patlen) && isspace(s[patlen]))
X`009return TRUE;
X    for (s = string; *s; s++) `123
X`009if (isspace(*s) && strnEQ(s+1, revision, patlen) &&
X`009`009isspace(s[patlen+1] )) `123
X`009    return TRUE;
X`009`125
X    `125
X    return FALSE;
X`125
X
$ GOSUB UNPACK_FILE

$ FILE_IS = "INP.H"
$ CHECKSUM_IS = 1192051176
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/* $Header: inp.h,v 2.0 86/09/17 15:37:25 lwall Exp $
X *
X * $Log:`009inp.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);`009/* how long is input file in lines */
XEXT LINENUM last_frozen_line INIT(0);`009/* how many input lines have been */
X`009`009`009`009`009/* irretractibly output */
X
Xbool rev_in_string();
Xvoid scan_input();
Xbool plan_a();`009`009`009/* returns false if insufficient memory */
Xvoid plan_b();
Xchar *ifetch();
X
$ GOSUB UNPACK_FILE

$ FILE_IS = "INTERN.H"
$ CHECKSUM_IS = 629031049
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/* $Header: INTERN.h,v 2.0 86/09/17 15:35:58 lwall Exp $
X *
X * $Log:`009INTERN.h,v $
X * Revision 2.0  86/09/17  15:35:58  lwall
X * Baseline for netwide release.
X *
X */
X
X#ifdef EXT
X#undef EXT
X#endif
X#define EXT
X
X#ifdef INIT
X#undef INIT
X#endif
X#define INIT(x) = x
X
X#define DOINIT
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAKEFILE."
$ CHECKSUM_IS = 1400456204
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X# $Header: Makefile.SH,v 2.0.1.2 88/06/22 20:43:40 lwall Locked $
X#
X# $Log: Makefile.SH,v $
X# Revision 2.0.1.2  88/06/22  20:43:40  lwall
X# patch12: config.h now depends on config.h.SH
X#
X# Revision 2.0.1.1  88/06/03  15:00:48  lwall
X# patch10: upgraded to match some new metaconfig stuff
X#
X# Revision 2.0  86/09/17  15:36:15  lwall
X# Baseline for netwide release.
X#
X# Revision 1.2  86/09/08  14:07:42  lwall
X# Split up patch.c.
X#
X# Revision 1.1  86/08/01  20:18:35  lwall
X# Initial revision
X#
X
XCC = cc
Xbin = user$utils
Xmansrc = user$hlp
Xmanext = l
XCFLAGS =
XLDFLAGS =
XSMALL =
XLARGE =
X
Xlibs=,user$com:options_file/opt
Xpublic = patch
Xprivate =
Xmanpages = patch.man
Xutil = Makefile
X
X*.obj : *.c
X        define sys sys$library
X        cc $*
X#        $(CC) $(CFLAGS) $(LARGE) $*.c
X
Xc = patch.c pch.c inp.c version.c util.c
X
Xobj = patch.obj pch.obj inp.obj util.obj version.obj
Xlobj = patch.obj,pch.obj,inp.obj,util.obj,version.obj
X
X
Xall: $(public) $(private) $(util)
X        write sys$output "touch all (patch build complete)"
X
Xpatch: $(obj)
X       link/exe=patch.exe $(LDFLAGS) $(lobj) $(libs)
X
X
X# won't work with csh
Xinstall: patch
X       write sys$output "Not ready yet"
X
Xclean:
X       del *.obj;* *_orig;*
X
Xpatch.obj: config.h common.h patch.c inp.h pch.h util.h version.h
Xpch.obj: config.h common.h pch.c pch.h util.h
Xinp.obj: config.h common.h inp.c inp.h util.h
Xutil.obj: config.h common.h util.c util.h
Xversion.obj: config.h common.h version.c version.h patchlevel.h util.h
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAKEFILE.UNIX"
$ CHECKSUM_IS = 856105322
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X# $Header: Makefile.SH,v 2.0.1.2 88/06/22 20:43:40 lwall Locked $
X#
X# $Log:`009Makefile.SH,v $
X# Revision 2.0.1.2  88/06/22  20:43:40  lwall
X# patch12: config.h now depends on config.h.SH
X#
X# Revision 2.0.1.1  88/06/03  15:00:48  lwall
X# patch10: upgraded to match some new metaconfig stuff
X#
X# Revision 2.0  86/09/17  15:36:15  lwall
X# Baseline for netwide release.
X#
X# Revision 1.2  86/09/08  14:07:42  lwall
X# Split up patch.c.
X#
X# Revision 1.1  86/08/01  20:18:35  lwall
X# Initial revision
X#
X
XCC = cc
Xbin = /usr/local/bin
Xmansrc = /usr/man/manl
Xmanext = l
XCFLAGS =  -O
XLDFLAGS =
XSMALL =
XLARGE =
X
X
Xpublic = patch
Xprivate =
Xmanpages = patch.man
Xutil = Makefile
X
Xc = patch.c pch.c inp.c version.c util.c
X
Xobj = patch.o pch.o inp.o util.o version.o
X
Xlintflags = -phbvxac
X
Xaddedbyconf = Makefile.old bsd config.h config.sh eunice loc pdp11 usg v7
X
X# grrr
XSHELL = /bin/sh
X
X.c.o:
X`009$(CC) -c $(CFLAGS) $(LARGE) $*.c
X
Xall: $(public) $(private) $(util)
X`009touch all
X
Xpatch: $(obj)
X`009$(CC) $(LDFLAGS) $(obj) $(libs) -o patch
X
Xconfig.h: config.h.SH
X`009sh config.h.SH
X
X# won't work with csh
Xinstall: patch
X`009export PATH `124`124 exit 1
X`009- mv $(bin)/patch $(bin)/patch.old
X`009- if test `096pwd`096 != $(bin); then cp $(public) $(bin); fi
X`009cd $(bin); chmod 755 $(public)
X`009- if test `096pwd`096 != $(mansrc); then \
Xfor page in $(manpages); do \
Xrm -f $(mansrc)/../cat$(manext)/`096basename $$page .man`096.$(manext); \
Xcp $$page $(mansrc)/`096basename $$page .man`096.$(manext); \
Xdone; \
Xfi
X
Xclean:
X`009rm -f *.o *.orig core
X
Xrealclean:
X`009rm -f patch *.o *.orig *`126 core $(addedbyconf)
X
X# The following lint has practically everything turned on.  Unfortunately,
X# you have to wade through a lot of mumbo jumbo that can't be suppressed.
X# If the source file has a /*NOSTRICT*/ somewhere, ignore the lint message
X# for that spot.
X
Xlint:
X`009lint $(lintflags) $(defs) $(c) > patch.fuzz
X
Xpatch.o: config.h common.h patch.c inp.h pch.h util.h version.h
Xpch.o: config.h common.h pch.c pch.h util.h
Xinp.o: config.h common.h inp.c inp.h util.h
Xutil.o: config.h common.h util.c util.h
Xversion.o: config.h common.h version.c version.h patchlevel.h util.h
X
$ GOSUB UNPACK_FILE

$ FILE_IS = "MALLOC.C"
$ CHECKSUM_IS = 726272038
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*
X * @(#)nmalloc.c 1 (Caltech) 2/21/82
X *
X *`009U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
X *
X *`009Nov 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`094n)-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`094(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)`009/* magic byte that implies allocation */
X#define ISFREE ((char) 0x54)`009/* magic byte that implies free block */
X`009`009`009`009/* 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
-+-+-+-+-+ End of part 3 +-+-+-+-+-
