=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/patch/patch.c,v retrieving revision 1.28 retrieving revision 1.29 diff -c -r1.28 -r1.29 *** src/usr.bin/patch/patch.c 2003/07/28 16:13:53 1.28 --- src/usr.bin/patch/patch.c 2003/07/28 18:28:52 1.29 *************** *** 1,4 **** ! /* $OpenBSD: patch.c,v 1.28 2003/07/28 16:13:53 millert Exp $ */ /* * patch - a program to apply diffs to original files --- 1,4 ---- ! /* $OpenBSD: patch.c,v 1.29 2003/07/28 18:28:52 otto Exp $ */ /* * patch - a program to apply diffs to original files *************** *** 27,33 **** */ #ifndef lint ! static const char rcsid[] = "$OpenBSD: patch.c,v 1.28 2003/07/28 16:13:53 millert Exp $"; #endif /* not lint */ #include --- 27,33 ---- */ #ifndef lint ! static const char rcsid[] = "$OpenBSD: patch.c,v 1.29 2003/07/28 18:28:52 otto Exp $"; #endif /* not lint */ #include *************** *** 38,67 **** #include #include #include #include #include - #include "INTERN.h" #include "common.h" - #include "EXTERN.h" #include "util.h" #include "pch.h" #include "inp.h" #include "backupfile.h" static void reinitialize_almost_everything(void); static void get_some_switches(void); static LINENUM locate_hunk(LINENUM); static void abort_hunk(void); static void apply_hunk(LINENUM); ! static void init_output(char *); ! static void init_reject(char *); static void copy_till(LINENUM); static void spew_output(void); static void dump_line(LINENUM); static bool patch_match(LINENUM, LINENUM, LINENUM); ! static bool similar(char *, char *, int); static __dead void usage(void); /* TRUE if -E was specified on command line. */ --- 38,102 ---- #include #include #include + #include #include #include #include "common.h" #include "util.h" #include "pch.h" #include "inp.h" #include "backupfile.h" + int filemode = 0644; + char buf[MAXLINELEN]; /* general purpose buffer */ + + bool using_plan_a = TRUE; /* try to keep everything in memory */ + bool out_of_mem = FALSE; /* ran out of memory in plan a */ + + #define MAXFILEC 2 + + char *filearg[MAXFILEC]; + bool ok_to_create_file = FALSE; + char *outname = NULL; + char *origprae = NULL; + char *TMPOUTNAME; + char *TMPINNAME; + char *TMPREJNAME; + char *TMPPATNAME; + bool toutkeep = FALSE; + bool trejkeep = FALSE; + + #ifdef DEBUGGING + int debug = 0; + #endif + + bool force = FALSE; + bool batch = FALSE; + bool verbose = TRUE; + bool reverse = FALSE; + bool noreverse = FALSE; + bool skip_rest_of_patch = FALSE; + int strippath = 957; + bool canonicalize = FALSE; + bool check_only = FALSE; + int diff_type = 0; + char *revision = NULL; /* prerequisite revision, if any */ + LINENUM input_lines = 0; /* how long is input file in lines */ + static void reinitialize_almost_everything(void); static void get_some_switches(void); static LINENUM locate_hunk(LINENUM); static void abort_hunk(void); static void apply_hunk(LINENUM); ! static void init_output(const char *); ! static void init_reject(const char *); static void copy_till(LINENUM); static void spew_output(void); static void dump_line(LINENUM); static bool patch_match(LINENUM, LINENUM, LINENUM); ! static bool similar(const char *, const char *, int); static __dead void usage(void); /* TRUE if -E was specified on command line. */ *************** *** 76,82 **** --- 111,143 ---- /* buffer for stderr */ static char serrbuf[BUFSIZ]; + /* how many input lines have been irretractibly output */ + static LINENUM last_frozen_line = 0; + static int Argc; /* guess */ + static char **Argv; + static int Argc_last; /* for restarting plan_b */ + static char **Argv_last; + + static FILE *ofp = NULL; /* output file pointer */ + static FILE *rejfp = NULL; /* reject file pointer */ + + static int filec = 0; /* how many file arguments? */ + static LINENUM last_offset = 0; + static LINENUM maxfuzz = 2; + + /* patch using ifdef, ifndef, etc. */ + static bool do_defines = FALSE; + /* #ifdef xyzzy */ + static char if_defined[128]; + /* #ifndef xyzzy */ + static char not_defined[128]; + /* #else */ + static const char else_defined[] = "#else\n"; + /* #endif xyzzy */ + static char end_defined[128]; + + /* Apply a set of diffs as appropriate. */ int *************** *** 90,97 **** for (i = 0; i < MAXFILEC; i++) filearg[i] = NULL; - myuid = getuid(); - /* Cons up the names of the temporary files. */ tmpdir = getenv("TMPDIR"); if (tmpdir == NULL) { --- 151,156 ---- *************** *** 177,200 **** out_of_mem = FALSE; while (another_hunk()) { hunk++; ! fuzz = NULL; mymaxfuzz = pch_context(); if (maxfuzz < mymaxfuzz) mymaxfuzz = maxfuzz; if (!skip_rest_of_patch) { do { where = locate_hunk(fuzz); ! if (hunk == 1 && where == NULL && !force) { /* dwim for reversed patch? */ if (!pch_swap()) { ! if (fuzz == NULL) say("Not enough memory to try swapped hunk! Assuming unswapped.\n"); continue; } reverse = !reverse; /* try again */ where = locate_hunk(fuzz); ! if (where == NULL) { /* didn't find it swapped */ if (!pch_swap()) /* put it back to normal */ --- 236,259 ---- out_of_mem = FALSE; while (another_hunk()) { hunk++; ! fuzz = 0; mymaxfuzz = pch_context(); if (maxfuzz < mymaxfuzz) mymaxfuzz = maxfuzz; if (!skip_rest_of_patch) { do { where = locate_hunk(fuzz); ! if (hunk == 1 && where == 0 && !force) { /* dwim for reversed patch? */ if (!pch_swap()) { ! if (fuzz == 0) say("Not enough memory to try swapped hunk! Assuming unswapped.\n"); continue; } reverse = !reverse; /* try again */ where = locate_hunk(fuzz); ! if (where == 0) { /* didn't find it swapped */ if (!pch_swap()) /* put it back to normal */ *************** *** 220,226 **** ask("Apply anyway? [n] "); if (*buf != 'y') skip_rest_of_patch = TRUE; ! where = NULL; reverse = !reverse; if (!pch_swap()) /* put it back to normal */ --- 279,285 ---- ask("Apply anyway? [n] "); if (*buf != 'y') skip_rest_of_patch = TRUE; ! where = 0; reverse = !reverse; if (!pch_swap()) /* put it back to normal */ *************** *** 228,234 **** } } } ! } while (!skip_rest_of_patch && where == NULL && ++fuzz <= mymaxfuzz); if (skip_rest_of_patch) { /* just got decided */ --- 287,293 ---- } } } ! } while (!skip_rest_of_patch && where == 0 && ++fuzz <= mymaxfuzz); if (skip_rest_of_patch) { /* just got decided */ *************** *** 243,249 **** if (verbose) say("Hunk #%d ignored at %ld.\n", hunk, newwhere); ! } else if (where == NULL) { abort_hunk(); failed++; if (verbose) --- 302,308 ---- if (verbose) say("Hunk #%d ignored at %ld.\n", hunk, newwhere); ! } else if (where == 0) { abort_hunk(); failed++; if (verbose) *************** *** 254,260 **** if (verbose) { say("Hunk #%d succeeded at %ld", hunk, newwhere); ! if (fuzz) say(" with fuzz %ld", fuzz); if (last_offset) say(" (offset %ld line%s)", --- 313,319 ---- if (verbose) { say("Hunk #%d succeeded at %ld", hunk, newwhere); ! if (fuzz != 0) say(" with fuzz %ld", fuzz); if (last_offset) say(" (offset %ld line%s)", *************** *** 311,317 **** rejfp = NULL; if (failed) { error = 1; ! if (!*rejname) { if (strlcpy(rejname, outname, sizeof(rejname)) >= sizeof(rejname)) fatal("filename %s is too long\n", outname); --- 370,376 ---- rejfp = NULL; if (failed) { error = 1; ! if (*rejname == '\0') { if (strlcpy(rejname, outname, sizeof(rejname)) >= sizeof(rejname)) fatal("filename %s is too long\n", outname); *************** *** 547,557 **** LINENUM max_pos_offset = input_lines - first_guess - pat_lines + 1; LINENUM max_neg_offset = first_guess - last_frozen_line - 1 + pch_context(); ! if (!pat_lines) /* null range matches always */ return first_guess; if (max_neg_offset >= first_guess) /* do not try lines < 0 */ max_neg_offset = first_guess - 1; ! if (first_guess <= input_lines && patch_match(first_guess, NULL, fuzz)) return first_guess; for (offset = 1; ; offset++) { bool check_after = (offset <= max_pos_offset); --- 606,616 ---- LINENUM max_pos_offset = input_lines - first_guess - pat_lines + 1; LINENUM max_neg_offset = first_guess - last_frozen_line - 1 + pch_context(); ! if (pat_lines == 0) /* null range matches always */ return first_guess; if (max_neg_offset >= first_guess) /* do not try lines < 0 */ max_neg_offset = first_guess - 1; ! if (first_guess <= input_lines && patch_match(first_guess, 0, fuzz)) return first_guess; for (offset = 1; ; offset++) { bool check_after = (offset <= max_pos_offset); *************** *** 574,580 **** last_offset = -offset; return first_guess - offset; } else if (!check_before && !check_after) ! return NULL; } } --- 633,639 ---- last_offset = -offset; return first_guess - offset; } else if (!check_before && !check_after) ! return 0; } } *************** *** 584,600 **** abort_hunk(void) { LINENUM i; ! LINENUM pat_end = pch_end(); /* * add in last_offset to guess the same as the previous successful * hunk */ ! LINENUM oldfirst = pch_first() + last_offset; ! LINENUM newfirst = pch_newfirst() + last_offset; ! LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1; ! LINENUM newlast = newfirst + pch_repl_lines() - 1; ! char *stars = (diff_type >= NEW_CONTEXT_DIFF ? " ****" : ""); ! char *minuses = (diff_type >= NEW_CONTEXT_DIFF ? " ----" : " -----"); fprintf(rejfp, "***************\n"); for (i = 0; i <= pat_end; i++) { --- 643,659 ---- abort_hunk(void) { LINENUM i; ! const LINENUM pat_end = pch_end(); /* * add in last_offset to guess the same as the previous successful * hunk */ ! const LINENUM oldfirst = pch_first() + last_offset; ! const LINENUM newfirst = pch_newfirst() + last_offset; ! const LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1; ! const LINENUM newlast = newfirst + pch_repl_lines() - 1; ! const char *stars = (diff_type >= NEW_CONTEXT_DIFF ? " ****" : ""); ! const char *minuses = (diff_type >= NEW_CONTEXT_DIFF ? " ----" : " -----"); fprintf(rejfp, "***************\n"); for (i = 0; i <= pat_end; i++) { *************** *** 637,652 **** static void apply_hunk(LINENUM where) { ! LINENUM old = 1; ! LINENUM lastline = pch_ptrn_lines(); ! LINENUM new = lastline + 1; #define OUTSIDE 0 #define IN_IFNDEF 1 #define IN_IFDEF 2 #define IN_ELSE 3 ! int def_state = OUTSIDE; ! bool R_do_defines = do_defines; ! LINENUM pat_end = pch_end(); where--; while (pch_char(new) == '=' || pch_char(new) == '\n') --- 696,710 ---- static void apply_hunk(LINENUM where) { ! LINENUM old = 1; ! const LINENUM lastline = pch_ptrn_lines(); ! LINENUM new = lastline + 1; #define OUTSIDE 0 #define IN_IFNDEF 1 #define IN_IFDEF 2 #define IN_ELSE 3 ! int def_state = OUTSIDE; ! const LINENUM pat_end = pch_end(); where--; while (pch_char(new) == '=' || pch_char(new) == '\n') *************** *** 655,661 **** while (old <= lastline) { if (pch_char(old) == '-') { copy_till(where + old - 1); ! if (R_do_defines) { if (def_state == OUTSIDE) { fputs(not_defined, ofp); def_state = IN_IFNDEF; --- 713,719 ---- while (old <= lastline) { if (pch_char(old) == '-') { copy_till(where + old - 1); ! if (do_defines) { if (def_state == OUTSIDE) { fputs(not_defined, ofp); def_state = IN_IFNDEF; *************** *** 671,677 **** break; } else if (pch_char(new) == '+') { copy_till(where + old - 1); ! if (R_do_defines) { if (def_state == IN_IFNDEF) { fputs(else_defined, ofp); def_state = IN_ELSE; --- 729,735 ---- break; } else if (pch_char(new) == '+') { copy_till(where + old - 1); ! if (do_defines) { if (def_state == IN_IFNDEF) { fputs(else_defined, ofp); def_state = IN_ELSE; *************** *** 693,710 **** my_exit(2); } else if (pch_char(new) == '!') { copy_till(where + old - 1); ! if (R_do_defines) { fputs(not_defined, ofp); def_state = IN_IFNDEF; } while (pch_char(old) == '!') { ! if (R_do_defines) { fputs(pfetch(old), ofp); } last_frozen_line++; old++; } ! if (R_do_defines) { fputs(else_defined, ofp); def_state = IN_ELSE; } --- 751,768 ---- my_exit(2); } else if (pch_char(new) == '!') { copy_till(where + old - 1); ! if (do_defines) { fputs(not_defined, ofp); def_state = IN_IFNDEF; } while (pch_char(old) == '!') { ! if (do_defines) { fputs(pfetch(old), ofp); } last_frozen_line++; old++; } ! if (do_defines) { fputs(else_defined, ofp); def_state = IN_ELSE; } *************** *** 716,722 **** assert(pch_char(new) == ' '); old++; new++; ! if (R_do_defines && def_state != OUTSIDE) { fputs(end_defined, ofp); def_state = OUTSIDE; } --- 774,780 ---- assert(pch_char(new) == ' '); old++; new++; ! if (do_defines && def_state != OUTSIDE) { fputs(end_defined, ofp); def_state = OUTSIDE; } *************** *** 724,730 **** } if (new <= pat_end && pch_char(new) == '+') { copy_till(where + old - 1); ! if (R_do_defines) { if (def_state == OUTSIDE) { fputs(if_defined, ofp); def_state = IN_IFDEF; --- 782,788 ---- } if (new <= pat_end && pch_char(new) == '+') { copy_till(where + old - 1); ! if (do_defines) { if (def_state == OUTSIDE) { fputs(if_defined, ofp); def_state = IN_IFDEF; *************** *** 738,744 **** new++; } } ! if (R_do_defines && def_state != OUTSIDE) { fputs(end_defined, ofp); } } --- 796,802 ---- new++; } } ! if (do_defines && def_state != OUTSIDE) { fputs(end_defined, ofp); } } *************** *** 747,753 **** * Open the new file. */ static void ! init_output(char *name) { ofp = fopen(name, "w"); if (ofp == NULL) --- 805,811 ---- * Open the new file. */ static void ! init_output(const char *name) { ofp = fopen(name, "w"); if (ofp == NULL) *************** *** 758,764 **** * Open a file to put hunks we can't locate. */ static void ! init_reject(char *name) { rejfp = fopen(name, "w"); if (rejfp == NULL) --- 816,822 ---- * Open a file to put hunks we can't locate. */ static void ! init_reject(const char *name) { rejfp = fopen(name, "w"); if (rejfp == NULL) *************** *** 771,783 **** static void copy_till(LINENUM lastline) { ! LINENUM R_last_frozen_line = last_frozen_line; ! ! if (R_last_frozen_line > lastline) fatal("misordered hunks! output would be garbled\n"); ! while (R_last_frozen_line < lastline) ! dump_line(++R_last_frozen_line); ! last_frozen_line = R_last_frozen_line; } /* --- 829,838 ---- static void copy_till(LINENUM lastline) { ! if (last_frozen_line > lastline) fatal("misordered hunks! output would be garbled\n"); ! while (last_frozen_line < lastline) ! dump_line(++last_frozen_line); } /* *************** *** 802,814 **** static void dump_line(LINENUM line) { ! char *s, R_newline = '\n'; s = ifetch(line, 0); if (s == NULL) return; /* Note: string is not null terminated. */ ! for (; putc(*s, ofp) != R_newline; s++) ; } --- 857,869 ---- static void dump_line(LINENUM line) { ! char *s; s = ifetch(line, 0); if (s == NULL) return; /* Note: string is not null terminated. */ ! for (; putc(*s, ofp) != '\n'; s++) ; } *************** *** 818,829 **** static bool patch_match(LINENUM base, LINENUM offset, LINENUM fuzz) { ! LINENUM pline = 1 + fuzz; ! LINENUM iline; ! LINENUM pat_lines = pch_ptrn_lines() - fuzz; ! char *ilineptr; ! char *plineptr; ! short plinelen; for (iline = base + offset + fuzz; pline <= pat_lines; pline++, iline++) { ilineptr = ifetch(iline, offset >= 0); --- 873,884 ---- static bool patch_match(LINENUM base, LINENUM offset, LINENUM fuzz) { ! LINENUM pline = 1 + fuzz; ! LINENUM iline; ! LINENUM pat_lines = pch_ptrn_lines() - fuzz; ! const char *ilineptr; ! const char *plineptr; ! short plinelen; for (iline = base + offset + fuzz; pline <= pat_lines; pline++, iline++) { ilineptr = ifetch(iline, offset >= 0); *************** *** 844,850 **** * Do two lines match with canonicalized white space? */ static bool ! similar(char *a, char *b, int len) { while (len) { if (isspace(*b)) { /* whitespace (or \n) to match? */ --- 899,905 ---- * Do two lines match with canonicalized white space? */ static bool ! similar(const char *a, const char *b, int len) { while (len) { if (isspace(*b)) { /* whitespace (or \n) to match? */