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

📄 patch.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		    s = Argv[0];		}		if (!isalpha(*s))		    fatal1("Argument to -D not an identifier.\n");		Sprintf(if_defined, "#ifdef %s\n", s);		Sprintf(not_defined, "#ifndef %s\n", s);		Sprintf(end_defined, "#endif /* %s */\n", s);		break;	    case 'e':		diff_type = ED_DIFF;		break;	    case 'f':		force = TRUE;		break;	    case 'F':		if (*++s == '=')		    s++;		maxfuzz = atoi(s);		break;	    case 'l':		canonicalize = TRUE;		break;	    case 'n':		diff_type = NORMAL_DIFF;		break;	    case 'N':		noreverse = TRUE;		break;	    case 'o':		outname = savestr(Argv[1]);		Argc--,Argv++;		break;	    case 'p':		if (*++s == '=')		    s++;		strippath = atoi(s);		break;	    case 'r':		Strcpy(rejname, Argv[1]);		Argc--,Argv++;		break;	    case 'R':		reverse = TRUE;		break;	    case 's':		verbose = FALSE;		break;	    case 'S':		skip_rest_of_patch = TRUE;		break;	    case 'v':		version();		break;#ifdef DEBUGGING	    case 'x':		debug = atoi(s+1);		break;#endif	    default:		fatal2("Unrecognized switch: %s\n", Argv[0]);	    }	}    }}/* Attempt to find the right place to apply this hunk of patch. */LINENUMlocate_hunk(fuzz)LINENUM fuzz;{    Reg1 LINENUM first_guess = pch_first() + last_offset;    Reg2 LINENUM offset;    LINENUM pat_lines = pch_ptrn_lines();    Reg3 LINENUM max_pos_offset = input_lines - first_guess				- pat_lines + 1;     Reg4 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, Nulline, fuzz))	return first_guess;    for (offset = 1; ; offset++) {	Reg5 bool check_after = (offset <= max_pos_offset);	Reg6 bool check_before = (offset <= max_neg_offset);	if (check_after && patch_match(first_guess, offset, fuzz)) {#ifdef DEBUGGING	    if (debug & 1)		say3("Offset changing from %ld to %ld\n", last_offset, offset);#endif	    last_offset = offset;	    return first_guess+offset;	}	else if (check_before && patch_match(first_guess, -offset, fuzz)) {#ifdef DEBUGGING	    if (debug & 1)		say3("Offset changing from %ld to %ld\n", last_offset, -offset);#endif	    last_offset = -offset;	    return first_guess-offset;	}	else if (!check_before && !check_after)	    return Nulline;    }}/* We did not find the pattern, dump out the hunk so they can handle it. */voidabort_hunk(){    Reg1 LINENUM i;    Reg2 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++) {	switch (pch_char(i)) {	case '*':	    if (oldlast < oldfirst)		fprintf(rejfp, "*** 0%s\n", stars);	    else if (oldlast == oldfirst)		fprintf(rejfp, "*** %ld%s\n", oldfirst, stars);	    else		fprintf(rejfp, "*** %ld,%ld%s\n", oldfirst, oldlast, stars);	    break;	case '=':	    if (newlast < newfirst)		fprintf(rejfp, "--- 0%s\n", minuses);	    else if (newlast == newfirst)		fprintf(rejfp, "--- %ld%s\n", newfirst, minuses);	    else		fprintf(rejfp, "--- %ld,%ld%s\n", newfirst, newlast, minuses);	    break;	case '\n':	    fprintf(rejfp, "%s", pfetch(i));	    break;	case ' ': case '-': case '+': case '!':	    fprintf(rejfp, "%c %s", pch_char(i), pfetch(i));	    break;	default:	    say1("Fatal internal error in abort_hunk().\n"); 	    abort();	}    }}/* We found where to apply it (we hope), so do it. */voidapply_hunk(where)LINENUM where;{    Reg1 LINENUM old = 1;    Reg2 LINENUM lastline = pch_ptrn_lines();    Reg3 LINENUM new = lastline+1;#define OUTSIDE 0#define IN_IFNDEF 1#define IN_IFDEF 2#define IN_ELSE 3    Reg4 int def_state = OUTSIDE;    Reg5 bool R_do_defines = do_defines;    Reg6 LINENUM pat_end = pch_end();    where--;    while (pch_char(new) == '=' || pch_char(new) == '\n')	new++;        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;		}		else if (def_state == IN_IFDEF) {		    fputs(else_defined, ofp);		    def_state = IN_ELSE;		}		fputs(pfetch(old), ofp);	    }	    last_frozen_line++;	    old++;	}	else if (new > pat_end)	    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;		}		else if (def_state == OUTSIDE) {		    fputs(if_defined, ofp);		    def_state = IN_IFDEF;		}	    }	    fputs(pfetch(new), ofp);	    new++;	}	else {	    if (pch_char(new) != pch_char(old)) {		say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",		    pch_hunk_beg() + old,		    pch_hunk_beg() + new);#ifdef DEBUGGING		say3("oldchar = '%c', newchar = '%c'\n",		    pch_char(old), pch_char(new));#endif		my_exit(1);	    }	    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;		}		while (pch_char(new) == '!') {		    fputs(pfetch(new), ofp);		    new++;		}		if (R_do_defines) {		    fputs(end_defined, ofp);		    def_state = OUTSIDE;		}	    }	    else {		assert(pch_char(new) == ' ');		old++;		new++;	    }	}    }    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;	    }	    else if (def_state == IN_IFNDEF) {		fputs(else_defined, ofp);		def_state = IN_ELSE;	    }	}	while (new <= pat_end && pch_char(new) == '+') {	    fputs(pfetch(new), ofp);	    new++;	}    }    if (R_do_defines && def_state != OUTSIDE) {	fputs(end_defined, ofp);    }}/* Open the new file. */voidinit_output(name)char *name;{    ofp = fopen(name, "w");    if (ofp == Nullfp)	fatal2("patch: can't create %s.\n", name);}/* Open a file to put hunks we can't locate. */voidinit_reject(name)char *name;{    rejfp = fopen(name, "w");    if (rejfp == Nullfp)	fatal2("patch: can't create %s.\n", name);}/* Copy input file to output, up to wherever hunk is to be applied. */voidcopy_till(lastline)Reg1 LINENUM lastline;{    Reg2 LINENUM R_last_frozen_line = last_frozen_line;    if (R_last_frozen_line > lastline)	say1("patch: misordered hunks! output will be garbled.\n");    while (R_last_frozen_line < lastline) {	dump_line(++R_last_frozen_line);    }    last_frozen_line = R_last_frozen_line;}/* Finish copying the input file to the output file. */voidspew_output(){#ifdef DEBUGGING    if (debug & 256)	say3("il=%ld lfl=%ld\n",input_lines,last_frozen_line);#endif    if (input_lines)	copy_till(input_lines);		/* dump remainder of file */    Fclose(ofp);    ofp = Nullfp;}/* Copy one line from input to output. */voiddump_line(line)LINENUM line;{    Reg1 char *s;    Reg2 char R_newline = '\n';    /* Note: string is not null terminated. */    for (s=ifetch(line, 0); putc(*s, ofp) != R_newline; s++) ;}/* Does the patch pattern match at line base+offset? */boolpatch_match(base, offset, fuzz)LINENUM base;LINENUM offset;LINENUM fuzz;{    Reg1 LINENUM pline = 1 + fuzz;    Reg2 LINENUM iline;    Reg3 LINENUM pat_lines = pch_ptrn_lines() - fuzz;    for (iline=base+offset+fuzz; pline <= pat_lines; pline++,iline++) {	if (canonicalize) {	    if (!similar(ifetch(iline, (offset >= 0)),			 pfetch(pline),			 pch_line_len(pline) ))		return FALSE;	}	else if (strnNE(ifetch(iline, (offset >= 0)),		   pfetch(pline),		   pch_line_len(pline) ))	    return FALSE;    }    return TRUE;}/* Do two lines match with canonicalized white space? */boolsimilar(a,b,len)Reg1 char *a;Reg2 char *b;Reg3 int len;{    while (len) {	if (isspace(*b)) {		/* whitespace (or \n) to match? */	    if (!isspace(*a))		/* no corresponding whitespace? */		return FALSE;	    while (len && isspace(*b) && *b != '\n')		b++,len--;		/* skip pattern whitespace */	    while (isspace(*a) && *a != '\n')		a++;			/* skip target whitespace */	    if (*a == '\n' || *b == '\n')		return (*a == *b);	/* should end in sync */	}	else if (*a++ != *b++)		/* match non-whitespace chars */	    return FALSE;	else	    len--;			/* probably not necessary */    }    return TRUE;			/* actually, this is not reached */					/* since there is always a \n */}/* Exit with cleanup. */voidmy_exit(status)int status;{    Unlink(TMPINNAME);    if (!toutkeep) {	Unlink(TMPOUTNAME);    }    if (!trejkeep) {	Unlink(TMPREJNAME);    }    Unlink(TMPPATNAME);#ifdef SMALL    Unlink(TMPSTRNAME);#endif    exit(status);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -