⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pch.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
{    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 + -