Annotation of 43BSDTahoe/new/patch/inp.c, revision 1.1.1.1

1.1       root        1: /* $Header: inp.c,v 2.0 86/09/17 15:37:02 lwall Exp $
                      2:  *
                      3:  * $Log:       inp.c,v $
                      4:  * Revision 2.0  86/09/17  15:37:02  lwall
                      5:  * Baseline for netwide release.
                      6:  * 
                      7:  */
                      8: 
                      9: #include "EXTERN.h"
                     10: #include "common.h"
                     11: #include "util.h"
                     12: #include "pch.h"
                     13: #include "INTERN.h"
                     14: #include "inp.h"
                     15: 
                     16: /* Input-file-with-indexable-lines abstract type */
                     17: 
                     18: static long i_size;                    /* size of the input file */
                     19: static char *i_womp;                   /* plan a buffer for entire file */
                     20: static char **i_ptr;                   /* pointers to lines in i_womp */
                     21: 
                     22: static int tifd = -1;                  /* plan b virtual string array */
                     23: static char *tibuf[2];                 /* plan b buffers */
                     24: static LINENUM tiline[2] = {-1, -1};   /* 1st line in each buffer */
                     25: static LINENUM lines_per_buf;          /* how many lines per buffer */
                     26: static int tireclen;                   /* length of records in tmp file */
                     27: 
                     28: /* New patch--prepare to edit another file. */
                     29: 
                     30: void
                     31: re_input()
                     32: {
                     33:     if (using_plan_a) {
                     34:        i_size = 0;
                     35: #ifndef lint
                     36:        if (i_ptr != Null(char**))
                     37:            free((char *)i_ptr);
                     38: #endif
                     39:        if (i_womp != Nullch)
                     40:            free(i_womp);
                     41:        i_womp = Nullch;
                     42:        i_ptr = Null(char **);
                     43:     }
                     44:     else {
                     45:        using_plan_a = TRUE;            /* maybe the next one is smaller */
                     46:        Close(tifd);
                     47:        tifd = -1;
                     48:        free(tibuf[0]);
                     49:        free(tibuf[1]);
                     50:        tibuf[0] = tibuf[1] = Nullch;
                     51:        tiline[0] = tiline[1] = -1;
                     52:        tireclen = 0;
                     53:     }
                     54: }
                     55: 
                     56: /* Constuct the line index, somehow or other. */
                     57: 
                     58: void
                     59: scan_input(filename)
                     60: char *filename;
                     61: {
                     62:     if (!plan_a(filename))
                     63:        plan_b(filename);
                     64:     if (verbose) {
                     65:        say3("Patching file %s using Plan %s...\n", filename,
                     66:          (using_plan_a ? "A" : "B") );
                     67:     }
                     68: }
                     69: 
                     70: /* Try keeping everything in memory. */
                     71: 
                     72: bool
                     73: plan_a(filename)
                     74: char *filename;
                     75: {
                     76:     int ifd;
                     77:     Reg1 char *s;
                     78:     Reg2 LINENUM iline;
                     79: 
                     80:     if (ok_to_create_file && stat(filename, &filestat) < 0) {
                     81:        if (verbose)
                     82:            say2("(Creating file %s...)\n",filename);
                     83:        makedirs(filename, TRUE);
                     84:        close(creat(filename, 0666));
                     85:     }
                     86:     if (stat(filename, &filestat) < 0) {
                     87:        Sprintf(buf, "RCS/%s%s", filename, RCSSUFFIX);
                     88:        if (stat(buf, &filestat) >= 0 || stat(buf+4, &filestat) >= 0) {
                     89:            Sprintf(buf, CHECKOUT, filename);
                     90:            if (verbose)
                     91:                say2("Can't find %s--attempting to check it out from RCS.\n",
                     92:                    filename);
                     93:            if (system(buf) || stat(filename, &filestat))
                     94:                fatal2("Can't check out %s.\n", filename);
                     95:        }
                     96:        else {
                     97:            Sprintf(buf, "SCCS/%s%s", SCCSPREFIX, filename);
                     98:            if (stat(buf, &filestat) >= 0 || stat(buf+5, &filestat) >= 0) {
                     99:                Sprintf(buf, GET, filename);
                    100:                if (verbose)
                    101:                    say2("Can't find %s--attempting to get it from SCCS.\n",
                    102:                        filename);
                    103:                if (system(buf) || stat(filename, &filestat))
                    104:                    fatal2("Can't get %s.\n", filename);
                    105:            }
                    106:            else
                    107:                fatal2("Can't find %s.\n", filename);
                    108:        }
                    109:     }
                    110:     filemode = filestat.st_mode;
                    111:     if ((filemode & S_IFMT) & ~S_IFREG)
                    112:        fatal2("%s is not a normal file--can't patch.\n", filename);
                    113:     i_size = filestat.st_size;
                    114:     if (out_of_mem) {
                    115:        set_hunkmax();          /* make sure dynamic arrays are allocated */
                    116:        out_of_mem = FALSE;
                    117:        return FALSE;                   /* force plan b because plan a bombed */
                    118:     }
                    119: #ifdef lint
                    120:     i_womp = Nullch;
                    121: #else
                    122:     i_womp = malloc((MEM)(i_size+2));  /* lint says this may alloc less than */
                    123:                                        /* i_size, but that's okay, I think. */
                    124: #endif
                    125:     if (i_womp == Nullch)
                    126:        return FALSE;
                    127:     if ((ifd = open(filename, 0)) < 0)
                    128:        fatal2("Can't open file %s\n", filename);
                    129: #ifndef lint
                    130:     if (read(ifd, i_womp, (int)i_size) != i_size) {
                    131:        Close(ifd);     /* probably means i_size > 15 or 16 bits worth */
                    132:        free(i_womp);   /* at this point it doesn't matter if i_womp was */
                    133:        return FALSE;   /*   undersized. */
                    134:     }
                    135: #endif
                    136:     Close(ifd);
                    137:     if (i_size && i_womp[i_size-1] != '\n')
                    138:        i_womp[i_size++] = '\n';
                    139:     i_womp[i_size] = '\0';
                    140: 
                    141:     /* count the lines in the buffer so we know how many pointers we need */
                    142: 
                    143:     iline = 0;
                    144:     for (s=i_womp; *s; s++) {
                    145:        if (*s == '\n')
                    146:            iline++;
                    147:     }
                    148: #ifdef lint
                    149:     i_ptr = Null(char**);
                    150: #else
                    151:     i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
                    152: #endif
                    153:     if (i_ptr == Null(char **)) {      /* shucks, it was a near thing */
                    154:        free((char *)i_womp);
                    155:        return FALSE;
                    156:     }
                    157:     
                    158:     /* now scan the buffer and build pointer array */
                    159: 
                    160:     iline = 1;
                    161:     i_ptr[iline] = i_womp;
                    162:     for (s=i_womp; *s; s++) {
                    163:        if (*s == '\n')
                    164:            i_ptr[++iline] = s+1;       /* these are NOT null terminated */
                    165:     }
                    166:     input_lines = iline - 1;
                    167: 
                    168:     /* now check for revision, if any */
                    169: 
                    170:     if (revision != Nullch) { 
                    171:        if (!rev_in_string(i_womp)) {
                    172:            if (force) {
                    173:                if (verbose)
                    174:                    say2("\
                    175: Warning: this file doesn't appear to be the %s version--patching anyway.\n",
                    176:                        revision);
                    177:            }
                    178:            else {
                    179:                ask2("\
                    180: This file doesn't appear to be the %s version--patch anyway? [n] ",
                    181:                    revision);
                    182:            if (*buf != 'y')
                    183:                fatal1("Aborted.\n");
                    184:            }
                    185:        }
                    186:        else if (verbose)
                    187:            say2("Good.  This file appears to be the %s version.\n",
                    188:                revision);
                    189:     }
                    190:     return TRUE;                       /* plan a will work */
                    191: }
                    192: 
                    193: /* Keep (virtually) nothing in memory. */
                    194: 
                    195: void
                    196: plan_b(filename)
                    197: char *filename;
                    198: {
                    199:     Reg3 FILE *ifp;
                    200:     Reg1 int i = 0;
                    201:     Reg2 int maxlen = 1;
                    202:     Reg4 bool found_revision = (revision == Nullch);
                    203: 
                    204:     using_plan_a = FALSE;
                    205:     if ((ifp = fopen(filename, "r")) == Nullfp)
                    206:        fatal2("Can't open file %s\n", filename);
                    207:     if ((tifd = creat(TMPINNAME, 0666)) < 0)
                    208:        fatal2("Can't open file %s\n", TMPINNAME);
                    209:     while (fgets(buf, sizeof buf, ifp) != Nullch) {
                    210:        if (revision != Nullch && !found_revision && rev_in_string(buf))
                    211:            found_revision = TRUE;
                    212:        if ((i = strlen(buf)) > maxlen)
                    213:            maxlen = i;                 /* find longest line */
                    214:     }
                    215:     if (revision != Nullch) {
                    216:        if (!found_revision) {
                    217:            if (force) {
                    218:                if (verbose)
                    219:                    say2("\
                    220: Warning: this file doesn't appear to be the %s version--patching anyway.\n",
                    221:                        revision);
                    222:            }
                    223:            else {
                    224:                ask2("\
                    225: This file doesn't appear to be the %s version--patch anyway? [n] ",
                    226:                    revision);
                    227:                if (*buf != 'y')
                    228:                    fatal1("Aborted.\n");
                    229:            }
                    230:        }
                    231:        else if (verbose)
                    232:            say2("Good.  This file appears to be the %s version.\n",
                    233:                revision);
                    234:     }
                    235:     Fseek(ifp, 0L, 0);         /* rewind file */
                    236:     lines_per_buf = BUFFERSIZE / maxlen;
                    237:     tireclen = maxlen;
                    238:     tibuf[0] = malloc((MEM)(BUFFERSIZE + 1));
                    239:     tibuf[1] = malloc((MEM)(BUFFERSIZE + 1));
                    240:     if (tibuf[1] == Nullch)
                    241:        fatal1("Can't seem to get enough memory.\n");
                    242:     for (i=1; ; i++) {
                    243:        if (! (i % lines_per_buf))      /* new block */
                    244:            if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
                    245:                fatal1("patch: can't write temp file.\n");
                    246:        if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
                    247:          == Nullch) {
                    248:            input_lines = i - 1;
                    249:            if (i % lines_per_buf)
                    250:                if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
                    251:                    fatal1("patch: can't write temp file.\n");
                    252:            break;
                    253:        }
                    254:     }
                    255:     Fclose(ifp);
                    256:     Close(tifd);
                    257:     if ((tifd = open(TMPINNAME, 0)) < 0) {
                    258:        fatal2("Can't reopen file %s\n", TMPINNAME);
                    259:     }
                    260: }
                    261: 
                    262: /* Fetch a line from the input file, \n terminated, not necessarily \0. */
                    263: 
                    264: char *
                    265: ifetch(line,whichbuf)
                    266: Reg1 LINENUM line;
                    267: int whichbuf;                          /* ignored when file in memory */
                    268: {
                    269:     if (line < 1 || line > input_lines)
                    270:        return "";
                    271:     if (using_plan_a)
                    272:        return i_ptr[line];
                    273:     else {
                    274:        LINENUM offline = line % lines_per_buf;
                    275:        LINENUM baseline = line - offline;
                    276: 
                    277:        if (tiline[0] == baseline)
                    278:            whichbuf = 0;
                    279:        else if (tiline[1] == baseline)
                    280:            whichbuf = 1;
                    281:        else {
                    282:            tiline[whichbuf] = baseline;
                    283: #ifndef lint           /* complains of long accuracy */
                    284:            Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
                    285: #endif
                    286:            if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
                    287:                fatal2("Error reading tmp file %s.\n", TMPINNAME);
                    288:        }
                    289:        return tibuf[whichbuf] + (tireclen*offline);
                    290:     }
                    291: }
                    292: 
                    293: /* True if the string argument contains the revision number we want. */
                    294: 
                    295: bool
                    296: rev_in_string(string)
                    297: char *string;
                    298: {
                    299:     Reg1 char *s;
                    300:     Reg2 int patlen;
                    301: 
                    302:     if (revision == Nullch)
                    303:        return TRUE;
                    304:     patlen = strlen(revision);
                    305:     for (s = string; *s; s++) {
                    306:        if (isspace(*s) && strnEQ(s+1, revision, patlen) && 
                    307:                isspace(s[patlen+1] )) {
                    308:            return TRUE;
                    309:        }
                    310:     }
                    311:     return FALSE;
                    312: }
                    313: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.