|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.