00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "EXTERN.h"
00019 #include "common.h"
00020 #include "util.h"
00021 #include "pch.h"
00022 #include "INTERN.h"
00023 #include "inp.h"
00024
00025
00026
00027 static long i_size;
00028 static char *i_womp;
00029 static char **i_ptr;
00030
00031 static int tifd = -1;
00032 static char *tibuf[2];
00033 static LINENUM tiline[2] = {-1, -1};
00034 static LINENUM lines_per_buf;
00035 static int tireclen;
00036
00037
00038
00039 void
00040 re_input()
00041 {
00042 if (using_plan_a) {
00043 i_size = 0;
00044 #ifndef lint
00045 if (i_ptr != Null(char**))
00046 free((char *)i_ptr);
00047 #endif
00048 if (i_womp != Nullch)
00049 free(i_womp);
00050 i_womp = Nullch;
00051 i_ptr = Null(char **);
00052 }
00053 else {
00054 #ifndef SMALL
00055 using_plan_a = TRUE;
00056 #endif
00057 Close(tifd);
00058 tifd = -1;
00059 free(tibuf[0]);
00060 free(tibuf[1]);
00061 tibuf[0] = tibuf[1] = Nullch;
00062 tiline[0] = tiline[1] = -1;
00063 tireclen = 0;
00064 }
00065 }
00066
00067
00068
00069 void
00070 scan_input(filename)
00071 char *filename;
00072 {
00073 #ifndef SMALL
00074 if (!plan_a(filename))
00075 #endif
00076 plan_b(filename);
00077 if (verbose) {
00078 say3("Patching file %s using Plan %s...\n", filename,
00079 (using_plan_a ? "A" : "B") );
00080 }
00081 }
00082
00083 #ifndef SMALL
00084
00085
00086 bool
00087 plan_a(filename)
00088 char *filename;
00089 {
00090 int ifd;
00091 Reg1 char *s;
00092 Reg2 LINENUM iline;
00093
00094 if (ok_to_create_file && stat(filename, &filestat) < 0) {
00095 if (verbose)
00096 say2("(Creating file %s...)\n",filename);
00097 makedirs(filename, TRUE);
00098 close(creat(filename, 0666));
00099 }
00100 if (stat(filename, &filestat) < 0) {
00101 Sprintf(buf, "RCS/%s%s", filename, RCSSUFFIX);
00102 if (stat(buf, &filestat) >= 0 || stat(buf+4, &filestat) >= 0) {
00103 Sprintf(buf, CHECKOUT, filename);
00104 if (verbose)
00105 say2("Can't find %s--attempting to check it out from RCS.\n",
00106 filename);
00107 if (system(buf) || stat(filename, &filestat))
00108 fatal2("Can't check out %s.\n", filename);
00109 }
00110 else {
00111 Sprintf(buf+20, "SCCS/%s%s", SCCSPREFIX, filename);
00112 if (stat(s=buf+20, &filestat) >= 0 ||
00113 stat(s=buf+25, &filestat) >= 0) {
00114 Sprintf(buf, GET, s);
00115 if (verbose)
00116 say2("Can't find %s--attempting to get it from SCCS.\n",
00117 filename);
00118 if (system(buf) || stat(filename, &filestat))
00119 fatal2("Can't get %s.\n", filename);
00120 }
00121 else
00122 fatal2("Can't find %s.\n", filename);
00123 }
00124 }
00125 filemode = filestat.st_mode;
00126 if ((filemode & S_IFMT) & ~S_IFREG)
00127 fatal2("%s is not a normal file--can't patch.\n", filename);
00128 i_size = filestat.st_size;
00129 if (out_of_mem) {
00130 set_hunkmax();
00131 out_of_mem = FALSE;
00132 return FALSE;
00133 }
00134 #ifdef lint
00135 i_womp = Nullch;
00136 #else
00137 i_womp = malloc((MEM)(i_size+2));
00138
00139 #endif
00140 if (i_womp == Nullch)
00141 return FALSE;
00142 if ((ifd = open(filename, 0)) < 0)
00143 fatal2("Can't open file %s\n", filename);
00144 #ifndef lint
00145 if (read(ifd, i_womp, (int)i_size) != i_size) {
00146 Close(ifd);
00147 free(i_womp);
00148 return FALSE;
00149 }
00150 #endif
00151 Close(ifd);
00152 if (i_size && i_womp[i_size-1] != '\n')
00153 i_womp[i_size++] = '\n';
00154 i_womp[i_size] = '\0';
00155
00156
00157
00158 iline = 0;
00159 for (s=i_womp; *s; s++) {
00160 if (*s == '\n')
00161 iline++;
00162 }
00163 #ifdef lint
00164 i_ptr = Null(char**);
00165 #else
00166 i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
00167 #endif
00168 if (i_ptr == Null(char **)) {
00169 free((char *)i_womp);
00170 return FALSE;
00171 }
00172
00173
00174
00175 iline = 1;
00176 i_ptr[iline] = i_womp;
00177 for (s=i_womp; *s; s++) {
00178 if (*s == '\n')
00179 i_ptr[++iline] = s+1;
00180 }
00181 input_lines = iline - 1;
00182
00183
00184
00185 if (revision != Nullch) {
00186 if (!rev_in_string(i_womp)) {
00187 if (force) {
00188 if (verbose)
00189 say2(
00190 "Warning: this file doesn't appear to be the %s version--patching anyway.\n",
00191 revision);
00192 }
00193 else {
00194 ask2(
00195 "This file doesn't appear to be the %s version--patch anyway? [n] ",
00196 revision);
00197 if (*buf != 'y')
00198 fatal1("Aborted.\n");
00199 }
00200 }
00201 else if (verbose)
00202 say2("Good. This file appears to be the %s version.\n",
00203 revision);
00204 }
00205 return TRUE;
00206 }
00207 #endif
00208
00209
00210
00211 void
00212 plan_b(filename)
00213 char *filename;
00214 {
00215 Reg3 FILE *ifp;
00216 Reg1 int i = 0;
00217 Reg2 int maxlen = 1;
00218 Reg4 bool found_revision = (revision == Nullch);
00219
00220 using_plan_a = FALSE;
00221 if ((ifp = fopen(filename, "r")) == Nullfp)
00222 fatal2("Can't open file %s\n", filename);
00223 if ((tifd = creat(TMPINNAME, 0666)) < 0)
00224 fatal2("Can't open file %s\n", TMPINNAME);
00225 while (fgets(buf, sizeof buf, ifp) != Nullch) {
00226 if (revision != Nullch && !found_revision && rev_in_string(buf))
00227 found_revision = TRUE;
00228 if ((i = strlen(buf)) > maxlen)
00229 maxlen = i;
00230 }
00231 if (revision != Nullch) {
00232 if (!found_revision) {
00233 if (force) {
00234 if (verbose)
00235 say2(
00236 "Warning: this file doesn't appear to be the %s version--patching anyway.\n",
00237 revision);
00238 }
00239 else {
00240 ask2(
00241 "This file doesn't appear to be the %s version--patch anyway? [n] ",
00242 revision);
00243 if (*buf != 'y')
00244 fatal1("Aborted.\n");
00245 }
00246 }
00247 else if (verbose)
00248 say2("Good. This file appears to be the %s version.\n",
00249 revision);
00250 }
00251 Fseek(ifp, 0L, 0);
00252 lines_per_buf = BUFFERSIZE / maxlen;
00253 tireclen = maxlen;
00254 tibuf[0] = (char *)malloc((MEM)(BUFFERSIZE + 1));
00255 tibuf[1] = (char *)malloc((MEM)(BUFFERSIZE + 1));
00256 if (tibuf[1] == Nullch)
00257 fatal1("Can't seem to get enough memory.\n");
00258 for (i=1; ; i++) {
00259 if (! (i % lines_per_buf))
00260 if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
00261 fatal1("patch: can't write temp file.\n");
00262 if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
00263 == Nullch) {
00264 input_lines = i - 1;
00265 if (i % lines_per_buf)
00266 if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
00267 fatal1("patch: can't write temp file.\n");
00268 break;
00269 }
00270 }
00271 Fclose(ifp);
00272 Close(tifd);
00273 if ((tifd = open(TMPINNAME, 0)) < 0) {
00274 fatal2("Can't reopen file %s\n", TMPINNAME);
00275 }
00276 }
00277
00278
00279
00280 char *
00281 ifetch(line,whichbuf)
00282 Reg1 LINENUM line;
00283 int whichbuf;
00284 {
00285 if (line < 1 || line > input_lines)
00286 return "";
00287 if (using_plan_a)
00288 return i_ptr[line];
00289 else {
00290 LINENUM offline = line % lines_per_buf;
00291 LINENUM baseline = line - offline;
00292
00293 if (tiline[0] == baseline)
00294 whichbuf = 0;
00295 else if (tiline[1] == baseline)
00296 whichbuf = 1;
00297 else {
00298 tiline[whichbuf] = baseline;
00299 #ifndef lint
00300 Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
00301 #endif
00302 if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
00303 fatal2("Error reading tmp file %s.\n", TMPINNAME);
00304 }
00305 return tibuf[whichbuf] + (tireclen*offline);
00306 }
00307 }
00308
00309
00310
00311 bool
00312 rev_in_string(string)
00313 char *string;
00314 {
00315 Reg1 char *s;
00316 Reg2 int patlen;
00317
00318 if (revision == Nullch)
00319 return TRUE;
00320 patlen = strlen(revision);
00321 if (strnEQ(string,revision,patlen) && isspace(s[patlen]))
00322 return TRUE;
00323 for (s = string; *s; s++) {
00324 if (isspace(*s) && strnEQ(s+1, revision, patlen) &&
00325 isspace(s[patlen+1] )) {
00326 return TRUE;
00327 }
00328 }
00329 return FALSE;
00330 }
00331