forget difference between big and small commands - obsolete with vm.
[minix.git] / commands / patch / patch.c
blob5108d0fa9ed946c58ec0a5454650274915af3b4d
1 char rcsid[] =
2 "$Header$";
4 /* patch - a program to apply diffs to original files
6 * Copyright 1986, Larry Wall
8 * This program may be copied as long as you don't try to make any
9 * money off of it, or pretend that you wrote it.
11 * $Log$
12 * Revision 1.1 2005/04/21 14:55:10 beng
13 * Initial revision
15 * Revision 1.1.1.1 2005/04/20 13:33:19 beng
16 * Initial import of minix 2.0.4
18 * Revision 2.0.1.6 88/06/22 20:46:39 lwall
19 * patch12: rindex() wasn't declared
21 * Revision 2.0.1.5 88/06/03 15:09:37 lwall
22 * patch10: exit code improved.
23 * patch10: better support for non-flexfilenames.
25 * Revision 2.0.1.4 87/02/16 14:00:04 lwall
26 * Short replacement caused spurious "Out of sync" message.
28 * Revision 2.0.1.3 87/01/30 22:45:50 lwall
29 * Improved diagnostic on sync error.
30 * Moved do_ed_script() to pch.c.
32 * Revision 2.0.1.2 86/11/21 09:39:15 lwall
33 * Fuzz factor caused offset of installed lines.
35 * Revision 2.0.1.1 86/10/29 13:10:22 lwall
36 * Backwards search could terminate prematurely.
38 * Revision 2.0 86/09/17 15:37:32 lwall
39 * Baseline for netwide release.
41 * Revision 1.5 86/08/01 20:53:24 lwall
42 * Changed some %d's to %ld's.
43 * Linted.
45 * Revision 1.4 86/08/01 19:17:29 lwall
46 * Fixes for machines that can't vararg.
47 * Added fuzz factor.
48 * Generalized -p.
49 * General cleanup.
51 * 85/08/15 van%ucbmonet@berkeley
52 * Changes for 4.3bsd diff -c.
54 * Revision 1.3 85/03/26 15:07:43 lwall
55 * Frozen.
57 * Revision 1.2.1.9 85/03/12 17:03:35 lwall
58 * Changed pfp->_file to fileno(pfp).
60 * Revision 1.2.1.8 85/03/12 16:30:43 lwall
61 * Check i_ptr and i_womp to make sure they aren't null before freeing.
62 * Also allow ed output to be suppressed.
64 * Revision 1.2.1.7 85/03/12 15:56:13 lwall
65 * Added -p option from jromine@uci-750a.
67 * Revision 1.2.1.6 85/03/12 12:12:51 lwall
68 * Now checks for normalness of file to patch.
70 * Revision 1.2.1.5 85/03/12 11:52:12 lwall
71 * Added -D (#ifdef) option from joe@fluke.
73 * Revision 1.2.1.4 84/12/06 11:14:15 lwall
74 * Made smarter about SCCS subdirectories.
76 * Revision 1.2.1.3 84/12/05 11:18:43 lwall
77 * Added -l switch to do loose string comparison.
79 * Revision 1.2.1.2 84/12/04 09:47:13 lwall
80 * Failed hunk count not reset on multiple patch file.
82 * Revision 1.2.1.1 84/12/04 09:42:37 lwall
83 * Branch for sdcrdcf changes.
85 * Revision 1.2 84/11/29 13:29:51 lwall
86 * Linted. Identifiers uniqified. Fixed i_ptr malloc() bug. Fixed
87 * multiple calls to mktemp(). Will now work on machines that can only
88 * read 32767 chars. Added -R option for diffs with new and old swapped.
89 * Various cosmetic changes.
91 * Revision 1.1 84/11/09 17:03:58 lwall
92 * Initial revision
96 * 1992-01-15
97 * Modified by Saeko & Kouichi Hirabayashi to fit small memory (64K+64K)
98 * system by adding "#if[n]def SMALL" parts.
101 #include "INTERN.h"
102 #include "common.h"
103 #include "EXTERN.h"
104 #include "version.h"
105 #include "util.h"
106 #include "pch.h"
107 #include "inp.h"
109 /* procedures */
111 _PROTOTYPE(int main , (int argc , char **argv ));
112 _PROTOTYPE(void reinitialize_almost_everything , (void));
113 _PROTOTYPE(void get_some_switches , (void));
114 _PROTOTYPE(LINENUM locate_hunk , (LINENUM fuzz ));
115 _PROTOTYPE(void abort_hunk , (void));
116 _PROTOTYPE(void apply_hunk , (LINENUM where ));
117 _PROTOTYPE(void init_output , (char *name ));
118 _PROTOTYPE(void init_reject , (char *name ));
119 _PROTOTYPE(void copy_till , (Reg1 LINENUM lastline ));
120 _PROTOTYPE(void spew_output , (void));
121 _PROTOTYPE(void dump_line , (LINENUM line ));
122 _PROTOTYPE(bool patch_match , (LINENUM base , LINENUM offset , LINENUM fuzz ));
123 _PROTOTYPE(bool similar , (Reg1 char *a , Reg2 char *b , Reg3 int len ));
125 /* Apply a set of diffs as appropriate. */
127 int main(argc,argv)
128 int argc;
129 char **argv;
131 LINENUM where;
132 LINENUM newwhere;
133 LINENUM fuzz;
134 LINENUM mymaxfuzz;
135 int hunk = 0;
136 int failed = 0;
137 int failtotal = 0;
138 int i;
140 setbuf(stderr, serrbuf);
141 for (i = 0; i<MAXFILEC; i++)
142 filearg[i] = Nullch;
143 Mktemp(TMPOUTNAME);
144 Mktemp(TMPINNAME);
145 Mktemp(TMPREJNAME);
146 Mktemp(TMPPATNAME);
147 #ifdef SMALL
148 Mktemp(TMPSTRNAME);
149 #endif
151 /* parse switches */
152 Argc = argc;
153 Argv = argv;
154 get_some_switches();
156 /* make sure we clean up /tmp in case of disaster */
157 set_signals(0);
159 for (
160 open_patch_file(filearg[1]);
161 there_is_another_patch();
162 reinitialize_almost_everything()
163 ) { /* for each patch in patch file */
165 if (outname == Nullch)
166 outname = savestr(filearg[0]);
168 /* initialize the patched file */
169 if (!skip_rest_of_patch)
170 init_output(TMPOUTNAME);
172 /* for ed script just up and do it and exit */
173 if (diff_type == ED_DIFF) {
174 do_ed_script();
175 continue;
178 /* initialize reject file */
179 init_reject(TMPREJNAME);
181 /* find out where all the lines are */
182 if (!skip_rest_of_patch)
183 scan_input(filearg[0]);
185 /* from here on, open no standard i/o files, because malloc */
186 /* might misfire and we can't catch it easily */
188 /* apply each hunk of patch */
189 hunk = 0;
190 failed = 0;
191 out_of_mem = FALSE;
192 while (another_hunk()) {
193 hunk++;
194 fuzz = Nulline;
195 mymaxfuzz = pch_context();
196 if (maxfuzz < mymaxfuzz)
197 mymaxfuzz = maxfuzz;
198 if (!skip_rest_of_patch) {
199 do {
200 where = locate_hunk(fuzz);
201 if (hunk == 1 && where == Nulline && !force) {
202 /* dwim for reversed patch? */
203 if (!pch_swap()) {
204 if (fuzz == Nulline)
205 say1(
206 "Not enough memory to try swapped hunk! Assuming unswapped.\n");
207 continue;
209 reverse = !reverse;
210 where = locate_hunk(fuzz); /* try again */
211 if (where == Nulline) { /* didn't find it swapped */
212 if (!pch_swap()) /* put it back to normal */
213 fatal1("Lost hunk on alloc error!\n");
214 reverse = !reverse;
216 else if (noreverse) {
217 if (!pch_swap()) /* put it back to normal */
218 fatal1("Lost hunk on alloc error!\n");
219 reverse = !reverse;
220 say1(
221 "Ignoring previously applied (or reversed) patch.\n");
222 skip_rest_of_patch = TRUE;
224 else {
225 ask3(
226 "%seversed (or previously applied) patch detected! %s -R? [y] ",
227 reverse ? "R" : "Unr",
228 reverse ? "Assume" : "Ignore");
229 if (*buf == 'n') {
230 ask1("Apply anyway? [n] ");
231 if (*buf != 'y')
232 skip_rest_of_patch = TRUE;
233 where = Nulline;
234 reverse = !reverse;
235 if (!pch_swap()) /* put it back to normal */
236 fatal1("Lost hunk on alloc error!\n");
240 } while (!skip_rest_of_patch && where == Nulline &&
241 ++fuzz <= mymaxfuzz);
243 if (skip_rest_of_patch) { /* just got decided */
244 Fclose(ofp);
245 ofp = Nullfp;
249 newwhere = pch_newfirst() + last_offset;
250 if (skip_rest_of_patch) {
251 abort_hunk();
252 failed++;
253 if (verbose)
254 say3("Hunk #%d ignored at %ld.\n", hunk, newwhere);
256 else if (where == Nulline) {
257 abort_hunk();
258 failed++;
259 if (verbose)
260 say3("Hunk #%d failed at %ld.\n", hunk, newwhere);
262 else {
263 apply_hunk(where);
264 if (verbose) {
265 say3("Hunk #%d succeeded at %ld", hunk, newwhere);
266 if (fuzz)
267 say2(" with fuzz %ld", fuzz);
268 if (last_offset)
269 say3(" (offset %ld line%s)",
270 last_offset, last_offset==1L?"":"s");
271 say1(".\n");
276 if (out_of_mem && using_plan_a) {
277 Argc = Argc_last;
278 Argv = Argv_last;
279 say1("\n\nRan out of memory using Plan A--trying again...\n\n");
280 continue;
283 assert(hunk);
285 /* finish spewing out the new file */
286 if (!skip_rest_of_patch)
287 spew_output();
289 /* and put the output where desired */
290 ignore_signals();
291 if (!skip_rest_of_patch) {
292 if (move_file(TMPOUTNAME, outname) < 0) {
293 toutkeep = TRUE;
294 chmod(TMPOUTNAME, filemode);
296 else
297 chmod(outname, filemode);
299 Fclose(rejfp);
300 rejfp = Nullfp;
301 if (failed) {
302 failtotal += failed;
303 if (!*rejname) {
304 Strcpy(rejname, outname);
305 #ifndef FLEXFILENAMES
307 char *s = rindex(rejname,'/');
309 if (!s)
310 s = rejname;
311 if (strlen(s) > 13)
312 if (s[12] == '.') /* try to preserve difference */
313 s[12] = s[13]; /* between .h, .c, .y, etc. */
314 s[13] = '\0';
316 #endif
317 Strcat(rejname, REJEXT);
319 if (skip_rest_of_patch) {
320 say4("%d out of %d hunks ignored--saving rejects to %s\n",
321 failed, hunk, rejname);
323 else {
324 say4("%d out of %d hunks failed--saving rejects to %s\n",
325 failed, hunk, rejname);
327 if (move_file(TMPREJNAME, rejname) < 0)
328 trejkeep = TRUE;
330 set_signals(1);
332 #ifdef SMALL
333 if (sfp != Nullfp)
334 Fclose(sfp);
335 #endif
336 my_exit(failtotal);
339 /* Prepare to find the next patch to do in the patch file. */
341 void
342 reinitialize_almost_everything()
344 re_patch();
345 re_input();
347 input_lines = 0;
348 last_frozen_line = 0;
350 filec = 0;
351 if (filearg[0] != Nullch && !out_of_mem) {
352 free(filearg[0]);
353 filearg[0] = Nullch;
356 if (outname != Nullch) {
357 free(outname);
358 outname = Nullch;
361 last_offset = 0;
363 diff_type = 0;
365 if (revision != Nullch) {
366 free(revision);
367 revision = Nullch;
370 reverse = FALSE;
371 skip_rest_of_patch = FALSE;
373 get_some_switches();
375 if (filec >= 2)
376 fatal1("You may not change to a different patch file.\n");
379 /* Process switches and filenames up to next '+' or end of list. */
381 void
382 get_some_switches()
384 Reg1 char *s;
386 rejname[0] = '\0';
387 Argc_last = Argc;
388 Argv_last = Argv;
389 if (!Argc)
390 return;
391 for (Argc--,Argv++; Argc; Argc--,Argv++) {
392 s = Argv[0];
393 if (strEQ(s, "+")) {
394 return; /* + will be skipped by for loop */
396 if (*s != '-' || !s[1]) {
397 if (filec == MAXFILEC)
398 fatal1("Too many file arguments.\n");
399 filearg[filec++] = savestr(s);
401 else {
402 switch (*++s) {
403 case 'b':
404 origext = savestr(Argv[1]);
405 Argc--,Argv++;
406 break;
407 case 'B':
408 origprae = savestr(Argv[1]);
409 Argc--,Argv++;
410 break;
411 case 'c':
412 diff_type = CONTEXT_DIFF;
413 break;
414 case 'd':
415 if (!*++s) {
416 Argc--,Argv++;
417 s = Argv[0];
419 if (chdir(s) < 0)
420 fatal2("Can't cd to %s.\n", s);
421 break;
422 case 'D':
423 do_defines = TRUE;
424 if (!*++s) {
425 Argc--,Argv++;
426 s = Argv[0];
428 if (!isalpha(*s))
429 fatal1("Argument to -D not an identifier.\n");
430 Sprintf(if_defined, "#ifdef %s\n", s);
431 Sprintf(not_defined, "#ifndef %s\n", s);
432 Sprintf(end_defined, "#endif /* %s */\n", s);
433 break;
434 case 'e':
435 diff_type = ED_DIFF;
436 break;
437 case 'f':
438 force = TRUE;
439 break;
440 case 'F':
441 if (*++s == '=')
442 s++;
443 maxfuzz = atoi(s);
444 break;
445 case 'l':
446 canonicalize = TRUE;
447 break;
448 case 'n':
449 diff_type = NORMAL_DIFF;
450 break;
451 case 'N':
452 noreverse = TRUE;
453 break;
454 case 'o':
455 outname = savestr(Argv[1]);
456 Argc--,Argv++;
457 break;
458 case 'p':
459 if (*++s == '=')
460 s++;
461 strippath = atoi(s);
462 break;
463 case 'r':
464 Strcpy(rejname, Argv[1]);
465 Argc--,Argv++;
466 break;
467 case 'R':
468 reverse = TRUE;
469 break;
470 case 's':
471 verbose = FALSE;
472 break;
473 case 'S':
474 skip_rest_of_patch = TRUE;
475 break;
476 case 'v':
477 version();
478 break;
479 #ifdef DEBUGGING
480 case 'x':
481 debug = atoi(s+1);
482 break;
483 #endif
484 default:
485 fatal2("Unrecognized switch: %s\n", Argv[0]);
491 /* Attempt to find the right place to apply this hunk of patch. */
493 LINENUM
494 locate_hunk(fuzz)
495 LINENUM fuzz;
497 Reg1 LINENUM first_guess = pch_first() + last_offset;
498 Reg2 LINENUM offset;
499 LINENUM pat_lines = pch_ptrn_lines();
500 Reg3 LINENUM max_pos_offset = input_lines - first_guess
501 - pat_lines + 1;
502 Reg4 LINENUM max_neg_offset = first_guess - last_frozen_line - 1
503 + pch_context();
505 if (!pat_lines) /* null range matches always */
506 return first_guess;
507 if (max_neg_offset >= first_guess) /* do not try lines < 0 */
508 max_neg_offset = first_guess - 1;
509 if (first_guess <= input_lines && patch_match(first_guess, Nulline, fuzz))
510 return first_guess;
511 for (offset = 1; ; offset++) {
512 Reg5 bool check_after = (offset <= max_pos_offset);
513 Reg6 bool check_before = (offset <= max_neg_offset);
515 if (check_after && patch_match(first_guess, offset, fuzz)) {
516 #ifdef DEBUGGING
517 if (debug & 1)
518 say3("Offset changing from %ld to %ld\n", last_offset, offset);
519 #endif
520 last_offset = offset;
521 return first_guess+offset;
523 else if (check_before && patch_match(first_guess, -offset, fuzz)) {
524 #ifdef DEBUGGING
525 if (debug & 1)
526 say3("Offset changing from %ld to %ld\n", last_offset, -offset);
527 #endif
528 last_offset = -offset;
529 return first_guess-offset;
531 else if (!check_before && !check_after)
532 return Nulline;
536 /* We did not find the pattern, dump out the hunk so they can handle it. */
538 void
539 abort_hunk()
541 Reg1 LINENUM i;
542 Reg2 LINENUM pat_end = pch_end();
543 /* add in last_offset to guess the same as the previous successful hunk */
544 LINENUM oldfirst = pch_first() + last_offset;
545 LINENUM newfirst = pch_newfirst() + last_offset;
546 LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1;
547 LINENUM newlast = newfirst + pch_repl_lines() - 1;
548 char *stars = (diff_type == NEW_CONTEXT_DIFF ? " ****" : "");
549 char *minuses = (diff_type == NEW_CONTEXT_DIFF ? " ----" : " -----");
551 fprintf(rejfp, "***************\n");
552 for (i=0; i<=pat_end; i++) {
553 switch (pch_char(i)) {
554 case '*':
555 if (oldlast < oldfirst)
556 fprintf(rejfp, "*** 0%s\n", stars);
557 else if (oldlast == oldfirst)
558 fprintf(rejfp, "*** %ld%s\n", oldfirst, stars);
559 else
560 fprintf(rejfp, "*** %ld,%ld%s\n", oldfirst, oldlast, stars);
561 break;
562 case '=':
563 if (newlast < newfirst)
564 fprintf(rejfp, "--- 0%s\n", minuses);
565 else if (newlast == newfirst)
566 fprintf(rejfp, "--- %ld%s\n", newfirst, minuses);
567 else
568 fprintf(rejfp, "--- %ld,%ld%s\n", newfirst, newlast, minuses);
569 break;
570 case '\n':
571 fprintf(rejfp, "%s", pfetch(i));
572 break;
573 case ' ': case '-': case '+': case '!':
574 fprintf(rejfp, "%c %s", pch_char(i), pfetch(i));
575 break;
576 default:
577 say1("Fatal internal error in abort_hunk().\n");
578 abort();
583 /* We found where to apply it (we hope), so do it. */
585 void
586 apply_hunk(where)
587 LINENUM where;
589 Reg1 LINENUM old = 1;
590 Reg2 LINENUM lastline = pch_ptrn_lines();
591 Reg3 LINENUM new = lastline+1;
592 #define OUTSIDE 0
593 #define IN_IFNDEF 1
594 #define IN_IFDEF 2
595 #define IN_ELSE 3
596 Reg4 int def_state = OUTSIDE;
597 Reg5 bool R_do_defines = do_defines;
598 Reg6 LINENUM pat_end = pch_end();
600 where--;
601 while (pch_char(new) == '=' || pch_char(new) == '\n')
602 new++;
604 while (old <= lastline) {
605 if (pch_char(old) == '-') {
606 copy_till(where + old - 1);
607 if (R_do_defines) {
608 if (def_state == OUTSIDE) {
609 fputs(not_defined, ofp);
610 def_state = IN_IFNDEF;
612 else if (def_state == IN_IFDEF) {
613 fputs(else_defined, ofp);
614 def_state = IN_ELSE;
616 fputs(pfetch(old), ofp);
618 last_frozen_line++;
619 old++;
621 else if (new > pat_end)
622 break;
623 else if (pch_char(new) == '+') {
624 copy_till(where + old - 1);
625 if (R_do_defines) {
626 if (def_state == IN_IFNDEF) {
627 fputs(else_defined, ofp);
628 def_state = IN_ELSE;
630 else if (def_state == OUTSIDE) {
631 fputs(if_defined, ofp);
632 def_state = IN_IFDEF;
635 fputs(pfetch(new), ofp);
636 new++;
638 else {
639 if (pch_char(new) != pch_char(old)) {
640 say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
641 pch_hunk_beg() + old,
642 pch_hunk_beg() + new);
643 #ifdef DEBUGGING
644 say3("oldchar = '%c', newchar = '%c'\n",
645 pch_char(old), pch_char(new));
646 #endif
647 my_exit(1);
649 if (pch_char(new) == '!') {
650 copy_till(where + old - 1);
651 if (R_do_defines) {
652 fputs(not_defined, ofp);
653 def_state = IN_IFNDEF;
655 while (pch_char(old) == '!') {
656 if (R_do_defines) {
657 fputs(pfetch(old), ofp);
659 last_frozen_line++;
660 old++;
662 if (R_do_defines) {
663 fputs(else_defined, ofp);
664 def_state = IN_ELSE;
666 while (pch_char(new) == '!') {
667 fputs(pfetch(new), ofp);
668 new++;
670 if (R_do_defines) {
671 fputs(end_defined, ofp);
672 def_state = OUTSIDE;
675 else {
676 assert(pch_char(new) == ' ');
677 old++;
678 new++;
682 if (new <= pat_end && pch_char(new) == '+') {
683 copy_till(where + old - 1);
684 if (R_do_defines) {
685 if (def_state == OUTSIDE) {
686 fputs(if_defined, ofp);
687 def_state = IN_IFDEF;
689 else if (def_state == IN_IFNDEF) {
690 fputs(else_defined, ofp);
691 def_state = IN_ELSE;
694 while (new <= pat_end && pch_char(new) == '+') {
695 fputs(pfetch(new), ofp);
696 new++;
699 if (R_do_defines && def_state != OUTSIDE) {
700 fputs(end_defined, ofp);
704 /* Open the new file. */
706 void
707 init_output(name)
708 char *name;
710 ofp = fopen(name, "w");
711 if (ofp == Nullfp)
712 fatal2("patch: can't create %s.\n", name);
715 /* Open a file to put hunks we can't locate. */
717 void
718 init_reject(name)
719 char *name;
721 rejfp = fopen(name, "w");
722 if (rejfp == Nullfp)
723 fatal2("patch: can't create %s.\n", name);
726 /* Copy input file to output, up to wherever hunk is to be applied. */
728 void
729 copy_till(lastline)
730 Reg1 LINENUM lastline;
732 Reg2 LINENUM R_last_frozen_line = last_frozen_line;
734 if (R_last_frozen_line > lastline)
735 say1("patch: misordered hunks! output will be garbled.\n");
736 while (R_last_frozen_line < lastline) {
737 dump_line(++R_last_frozen_line);
739 last_frozen_line = R_last_frozen_line;
742 /* Finish copying the input file to the output file. */
744 void
745 spew_output()
747 #ifdef DEBUGGING
748 if (debug & 256)
749 say3("il=%ld lfl=%ld\n",input_lines,last_frozen_line);
750 #endif
751 if (input_lines)
752 copy_till(input_lines); /* dump remainder of file */
753 Fclose(ofp);
754 ofp = Nullfp;
757 /* Copy one line from input to output. */
759 void
760 dump_line(line)
761 LINENUM line;
763 Reg1 char *s;
764 Reg2 char R_newline = '\n';
766 /* Note: string is not null terminated. */
767 for (s=ifetch(line, 0); putc(*s, ofp) != R_newline; s++) ;
770 /* Does the patch pattern match at line base+offset? */
772 bool
773 patch_match(base, offset, fuzz)
774 LINENUM base;
775 LINENUM offset;
776 LINENUM fuzz;
778 Reg1 LINENUM pline = 1 + fuzz;
779 Reg2 LINENUM iline;
780 Reg3 LINENUM pat_lines = pch_ptrn_lines() - fuzz;
782 for (iline=base+offset+fuzz; pline <= pat_lines; pline++,iline++) {
783 if (canonicalize) {
784 if (!similar(ifetch(iline, (offset >= 0)),
785 pfetch(pline),
786 pch_line_len(pline) ))
787 return FALSE;
789 else if (strnNE(ifetch(iline, (offset >= 0)),
790 pfetch(pline),
791 pch_line_len(pline) ))
792 return FALSE;
794 return TRUE;
797 /* Do two lines match with canonicalized white space? */
799 bool
800 similar(a,b,len)
801 Reg1 char *a;
802 Reg2 char *b;
803 Reg3 int len;
805 while (len) {
806 if (isspace(*b)) { /* whitespace (or \n) to match? */
807 if (!isspace(*a)) /* no corresponding whitespace? */
808 return FALSE;
809 while (len && isspace(*b) && *b != '\n')
810 b++,len--; /* skip pattern whitespace */
811 while (isspace(*a) && *a != '\n')
812 a++; /* skip target whitespace */
813 if (*a == '\n' || *b == '\n')
814 return (*a == *b); /* should end in sync */
816 else if (*a++ != *b++) /* match non-whitespace chars */
817 return FALSE;
818 else
819 len--; /* probably not necessary */
821 return TRUE; /* actually, this is not reached */
822 /* since there is always a \n */
825 /* Exit with cleanup. */
827 void
828 my_exit(status)
829 int status;
831 Unlink(TMPINNAME);
832 if (!toutkeep) {
833 Unlink(TMPOUTNAME);
835 if (!trejkeep) {
836 Unlink(TMPREJNAME);
838 Unlink(TMPPATNAME);
839 #ifdef SMALL
840 Unlink(TMPSTRNAME);
841 #endif
842 exit(status);