📄 pch.c
字号:
{ Reg1 char *s; Reg8 char *ret; Reg2 int context = 0; while (p_end >= 0) { if (p_end == p_efake) p_end = p_bfake; /* don't free twice */ else free(p_line[p_end]); p_end--; } assert(p_end == -1); p_efake = -1; p_max = hunkmax; /* gets reduced when --- found */ if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) { long line_beginning = ftell(pfp); /* file pos of the current line */ LINENUM repl_beginning = 0; /* index of --- line */ Reg4 LINENUM fillcnt = 0; /* #lines of missing ptrn or repl */ Reg5 LINENUM fillsrc; /* index of first line to copy */ Reg6 LINENUM filldst; /* index of first missing line */ bool ptrn_spaces_eaten = FALSE; /* ptrn was slightly misformed */ Reg9 bool repl_could_be_missing = TRUE; /* no + or ! lines in this hunk */ bool repl_missing = FALSE; /* we are now backtracking */ long repl_backtrack_position = 0; /* file pos of first repl line */ LINENUM repl_patch_line; /* input line number for same */ Reg7 LINENUM ptrn_copiable = 0; /* # of copiable lines in ptrn */ ret = pgets(buf, sizeof buf, pfp); p_input_line++; if (ret == Nullch || strnNE(buf, "********", 8)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } p_context = 100; p_hunk_beg = p_input_line + 1; while (p_end < p_max) { line_beginning = ftell(pfp); ret = pgets(buf, sizeof buf, pfp); p_input_line++; if (ret == Nullch) { if (p_max - p_end < 4) Strcpy(buf, " \n"); /* assume blank lines got chopped */ else { if (repl_beginning && repl_could_be_missing) { repl_missing = TRUE; goto hunk_done; } fatal1("unexpected end of file in patch\n"); } } p_end++; assert(p_end < hunkmax); p_char[p_end] = *buf;#ifdef zilog p_line[(short)p_end] = Nullch;#else p_line[p_end] = Nullch;#endif switch (*buf) { case '*': if (strnEQ(buf, "********", 8)) { if (repl_beginning && repl_could_be_missing) { repl_missing = TRUE; goto hunk_done; } else fatal2("unexpected end of hunk at line %ld\n", p_input_line); } if (p_end != 0) { if (repl_beginning && repl_could_be_missing) { repl_missing = TRUE; goto hunk_done; } fatal3("unexpected *** at line %ld: %s", p_input_line, buf); } context = 0; p_line[p_end] = savestr(buf); if (out_of_mem) { p_end--; return FALSE; } for (s=buf; *s && !isdigit(*s); s++) ; if (!*s) malformed (); if (strnEQ(s,"0,0",3)) strcpy(s,s+2); p_first = (LINENUM) atol(s); while (isdigit(*s)) s++; if (*s == ',') { for (; *s && !isdigit(*s); s++) ; if (!*s) malformed (); p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1; } else if (p_first) p_ptrn_lines = 1; else { p_ptrn_lines = 0; p_first = 1; } p_max = p_ptrn_lines + 6; /* we need this much at least */ while (p_max >= hunkmax) grow_hunkmax(); p_max = hunkmax; break; case '-': if (buf[1] == '-') { if (repl_beginning || (p_end != p_ptrn_lines + 1 + (p_char[p_end-1] == '\n'))) { if (p_end == 1) { /* `old' lines were omitted - set up to fill */ /* them in from 'new' context lines. */ p_end = p_ptrn_lines + 1; fillsrc = p_end + 1; filldst = 1; fillcnt = p_ptrn_lines; } else { if (repl_beginning) { if (repl_could_be_missing){ repl_missing = TRUE; goto hunk_done; } fatal3("duplicate \"---\" at line %ld--check line numbers at line %ld\n", p_input_line, p_hunk_beg + repl_beginning); } else { fatal4("%s \"---\" at line %ld--check line numbers at line %ld\n", (p_end <= p_ptrn_lines ? "Premature" : "Overdue" ), p_input_line, p_hunk_beg); } } } repl_beginning = p_end; repl_backtrack_position = ftell(pfp); repl_patch_line = p_input_line; p_line[p_end] = savestr(buf); if (out_of_mem) { p_end--; return FALSE; } p_char[p_end] = '='; for (s=buf; *s && !isdigit(*s); s++) ; if (!*s) malformed (); p_newfirst = (LINENUM) atol(s); while (isdigit(*s)) s++; if (*s == ',') { for (; *s && !isdigit(*s); s++) ; if (!*s) malformed (); p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1; } else if (p_newfirst) p_repl_lines = 1; else { p_repl_lines = 0; p_newfirst = 1; } p_max = p_repl_lines + p_end; if (p_max > MAXHUNKSIZE) fatal4("hunk too large (%ld lines) at line %ld: %s", p_max, p_input_line, buf); while (p_max >= hunkmax) grow_hunkmax(); if (p_repl_lines != ptrn_copiable && (p_context != 0 || p_repl_lines != 1)) repl_could_be_missing = FALSE; break; } goto change_line; case '+': case '!': repl_could_be_missing = FALSE; change_line: if (buf[1] == '\n' && canonicalize) strcpy(buf+1," \n"); if (!isspace(buf[1]) && buf[1] != '>' && buf[1] != '<' && repl_beginning && repl_could_be_missing) { repl_missing = TRUE; goto hunk_done; } if (context >= 0) { if (context < p_context) p_context = context; context = -1000; } p_line[p_end] = savestr(buf+2); if (out_of_mem) { p_end--; return FALSE; } break; case '\t': case '\n': /* assume the 2 spaces got eaten */ if (repl_beginning && repl_could_be_missing && (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF) ) { repl_missing = TRUE; goto hunk_done; } p_line[p_end] = savestr(buf); if (out_of_mem) { p_end--; return FALSE; } if (p_end != p_ptrn_lines + 1) { ptrn_spaces_eaten |= (repl_beginning != 0); context++; if (!repl_beginning) ptrn_copiable++; p_char[p_end] = ' '; } break; case ' ': if (!isspace(buf[1]) && repl_beginning && repl_could_be_missing) { repl_missing = TRUE; goto hunk_done; } context++; if (!repl_beginning) ptrn_copiable++; p_line[p_end] = savestr(buf+2); if (out_of_mem) { p_end--; return FALSE; } break; default: if (repl_beginning && repl_could_be_missing) { repl_missing = TRUE; goto hunk_done; } malformed (); } /* set up p_len for strncmp() so we don't have to */ /* assume null termination */ if (p_line[p_end]) p_len[p_end] = strlen(p_line[p_end]); else p_len[p_end] = 0; } hunk_done: if (p_end >=0 && !repl_beginning) fatal2("no --- found in patch at line %ld\n", pch_hunk_beg()); if (repl_missing) { /* reset state back to just after --- */ p_input_line = repl_patch_line; for (p_end--; p_end > repl_beginning; p_end--) free(p_line[p_end]); Fseek(pfp, repl_backtrack_position, 0); /* redundant 'new' context lines were omitted - set */ /* up to fill them in from the old file context */ if (!p_context && p_repl_lines == 1) { p_repl_lines = 0; p_max--; } fillsrc = 1; filldst = repl_beginning+1; fillcnt = p_repl_lines; p_end = p_max; } else if (!p_context && fillcnt == 1) { /* the first hunk was a null hunk with no context */ /* and we were expecting one line -- fix it up. */ while (filldst < p_end) { p_line[filldst] = p_line[filldst+1]; p_char[filldst] = p_char[filldst+1]; p_len[filldst] = p_len[filldst+1]; filldst++; }#if 0 repl_beginning--; /* this doesn't need to be fixed */#endif p_end--; p_first++; /* do append rather than insert */ fillcnt = 0; p_ptrn_lines = 0; } if (diff_type == CONTEXT_DIFF && (fillcnt || (p_first > 1 && ptrn_copiable > 2*p_context)) ) { if (verbose) say4("%s\n%s\n%s\n","(Fascinating--this is really a new-style context diff but without","the telltale extra asterisks on the *** line that usually indicate","the new style...)"); diff_type = NEW_CONTEXT_DIFF; } /* if there were omitted context lines, fill them in now */ if (fillcnt) { p_bfake = filldst; /* remember where not to free() */ p_efake = filldst + fillcnt - 1; while (fillcnt-- > 0) { while (fillsrc <= p_end && p_char[fillsrc] != ' ') fillsrc++; if (fillsrc > p_end) fatal2("replacement text or line numbers mangled in hunk at line %ld\n", p_hunk_beg); p_line[filldst] = p_line[fillsrc]; p_char[filldst] = p_char[fillsrc]; p_len[filldst] = p_len[fillsrc]; fillsrc++; filldst++; } while (fillsrc <= p_end && fillsrc != repl_beginning && p_char[fillsrc] != ' ') fillsrc++;#ifdef DEBUGGING if (debug & 64) printf("fillsrc %ld, filldst %ld, rb %ld, e+1 %ld\n", fillsrc,filldst,repl_beginning,p_end+1);#endif assert(fillsrc==p_end+1 || fillsrc==repl_beginning); assert(filldst==p_end+1 || filldst==repl_beginning); } } else if (diff_type == UNI_DIFF) { long line_beginning = ftell(pfp); /* file pos of the current line */ Reg4 LINENUM fillsrc; /* index of old lines */ Reg5 LINENUM filldst; /* index of new lines */ char ch; ret = pgets(buf, sizeof buf, pfp); p_input_line++; if (ret == Nullch || strnNE(buf, "@@ -", 4)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } s = buf+4; if (!*s) malformed (); p_first = (LINENUM) atol(s); while (isdigit(*s)) s++; if (*s == ',') { p_ptrn_lines = (LINENUM) atol(++s); while (isdigit(*s)) s++; } else p_ptrn_lines = 1; if (*s == ' ') s++; if (*s != '+' || !*++s) malformed (); p_newfirst = (LINENUM) atol(s); while (isdigit(*s)) s++; if (*s == ',') { p_repl_lines = (LINENUM) atol(++s); while (isdigit(*s)) s++; } else p_repl_lines = 1; if (*s == ' ') s++; if (*s != '@') malformed (); if (!p_ptrn_lines) p_first++; /* do append rather than insert */ p_max = p_ptrn_lines + p_repl_lines + 1; while (p_max >= hunkmax) grow_hunkmax(); fillsrc = 1; filldst = fillsrc + p_ptrn_lines; p_end = filldst + p_repl_lines; Sprintf(buf,"*** %ld,%ld ****\n",p_first,p_first + p_ptrn_lines - 1); p_line[0] = savestr(buf); if (out_of_mem) { p_end = -1; return FALSE; } p_char[0] = '*'; Sprintf(buf,"--- %ld,%ld ----\n",p_newfirst,p_newfirst+p_repl_lines-1); p_line[filldst] = savestr(buf); if (out_of_mem) { p_end = 0; return FALSE; } p_char[filldst++] = '='; p_context = 100; context = 0; p_hunk_beg = p_input_line + 1; while (fillsrc <= p_ptrn_lines || filldst <= p_end) { line_beginning = ftell(pfp); ret = pgets(buf, sizeof buf, pfp); p_input_line++; if (ret == Nullch) { if (p_max - filldst < 3) Strcpy(buf, " \n"); /* assume blank lines got chopped */ else { fatal1("unexpected end of file in patch\n"); } } if (*buf == '\t' || *buf == '\n') { ch = ' '; /* assume the space got eaten */ s = savestr(buf); } else { ch = *buf; s = savestr(buf+1); } if (out_of_mem) { while (--filldst > p_ptrn_lines) free(p_line[filldst]); p_end = fillsrc-1; return FALSE; } switch (ch) { case '-': if (fillsrc > p_ptrn_lines) { free(s); p_end = filldst-1; malformed (); } p_char[fillsrc] = ch; p_line[fillsrc] = s; p_len[fillsrc++] = strlen(s); break; case '=': ch = ' '; /* FALL THROUGH */ case ' ': if (fillsrc > p_ptrn_lines) { free(s); while (--filldst > p_ptrn_lines) free(p_line[filldst]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -