pch.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 1,866 行 · 第 1/4 页

C
1,866
字号
	p_Char[i] = '=';	for (i++; i<=p_end; i++) {	    chars_read = get_line ();	    if (chars_read == (size_t) -1)	      {		p_end = i - 1;		return -1;	      }	    if (!chars_read)		fatal ("unexpected end of file in patch at line %ld",		    p_input_line);	    if (buf[0] != '>' || (buf[1] != ' ' && buf[1] != '\t'))		fatal ("`>' expected at line %ld of patch", p_input_line);	    chars_read -= 2 + (i == p_end && incomplete_line ());	    p_len[i] = chars_read;	    if (! (p_line[i] = savebuf (buf + 2, chars_read))) {		p_end = i-1;		return -1;	    }	    p_Char[i] = '+';	}    }    if (rev)				/* backwards patch? */	if (!pch_swap())	    say ("Not enough memory to swap next hunk!\n");    if (debug & 2) {	LINENUM i;	char special;	for (i=0; i <= p_end; i++) {	    if (i == p_ptrn_lines)		special = '^';	    else		special = ' ';	    fprintf (stderr, "%3ld %c %c ", i, p_Char[i], special);	    pch_write_line (i, stderr);	    fflush (stderr);	}    }    if (p_end+1 < hunkmax)	/* paranoia reigns supreme... */	p_Char[p_end+1] = '^';  /* add a stopper for apply_hunk */    return 1;}static size_tget_line (){   return pget_line (p_indent, p_rfc934_nesting);}/* Input a line from the patch file, worrying about indentation.   Strip up to INDENT characters' worth of leading indentation.   Then remove up to RFC934_NESTING instances of leading "- ".   Ignore any partial lines at end of input, but warn about them.   Succeed if a line was read; it is terminated by "\n\0" for convenience.   Return the number of characters read, including '\n' but not '\0'.   Return -1 if we ran out of memory.  */static size_tpget_line (indent, rfc934_nesting)     int indent;     int rfc934_nesting;{  register FILE *fp = pfp;  register int c;  register int i = 0;  register char *b;  register size_t s;  for (;;)    {      c = getc (fp);      if (c == EOF)	{	  if (ferror (fp))	    read_fatal ();	  return 0;	}      if (indent <= i)	break;      if (c == ' ' || c == 'X')	i++;      else if (c == '\t')	i = (i + 8) & ~7;      else	break;    }  i = 0;  b = buf;  while (c == '-' && 0 <= --rfc934_nesting)    {      c = getc (fp);      if (c == EOF)	goto patch_ends_in_middle_of_line;      if (c != ' ')	{	  i = 1;	  b[0] = '-';	  break;	}      c = getc (fp);      if (c == EOF)	goto patch_ends_in_middle_of_line;    }  s = bufsize;  for (;;)    {      if (i == s - 1)	{	  s *= 2;	  b = realloc (b, s);	  if (!b)	    {	      if (!using_plan_a)		memory_fatal ();	      return (size_t) -1;	    }	  buf = b;	  bufsize = s;	}      b[i++] = c;      if (c == '\n')	break;      c = getc (fp);      if (c == EOF)	goto patch_ends_in_middle_of_line;    }  b[i] = '\0';  p_input_line++;  return i; patch_ends_in_middle_of_line:  if (ferror (fp))    read_fatal ();  say ("patch unexpectedly ends in middle of line\n");  return 0;}static boolincomplete_line (){  register FILE *fp = pfp;  register int c;  register file_offset line_beginning = file_tell (fp);  if (getc (fp) == '\\')    {      while ((c = getc (fp)) != '\n'  &&  c != EOF)	continue;      return TRUE;    }  else    {      /* We don't trust ungetc.  */      Fseek (pfp, line_beginning, SEEK_SET);      return FALSE;    }}/* Reverse the old and new portions of the current hunk. */boolpch_swap(){    char **tp_line;		/* the text of the hunk */    size_t *tp_len;		/* length of each line */    char *tp_char;		/* +, -, and ! */    register LINENUM i;    register LINENUM n;    bool blankline = FALSE;    register char *s;    i = p_first;    p_first = p_newfirst;    p_newfirst = i;    /* make a scratch copy */    tp_line = p_line;    tp_len = p_len;    tp_char = p_Char;    p_line = 0;	/* force set_hunkmax to allocate again */    p_len = 0;    p_Char = 0;    set_hunkmax();    if (!p_line || !p_len || !p_Char) {	if (p_line)	  free (p_line);	p_line = tp_line;	if (p_len)	  free (p_len);	p_len = tp_len;	if (p_Char)	  free (p_Char);	p_Char = tp_char;	return FALSE;		/* not enough memory to swap hunk! */    }    /* now turn the new into the old */    i = p_ptrn_lines + 1;    if (tp_char[i] == '\n') {		/* account for possible blank line */	blankline = TRUE;	i++;    }    if (p_efake >= 0) {			/* fix non-freeable ptr range */	if (p_efake <= i)	    n = p_end - i + 1;	else	    n = -i;	p_efake += n;	p_bfake += n;    }    for (n=0; i <= p_end; i++,n++) {	p_line[n] = tp_line[i];	p_Char[n] = tp_char[i];	if (p_Char[n] == '+')	    p_Char[n] = '-';	p_len[n] = tp_len[i];    }    if (blankline) {	i = p_ptrn_lines + 1;	p_line[n] = tp_line[i];	p_Char[n] = tp_char[i];	p_len[n] = tp_len[i];	n++;    }    assert(p_Char[0] == '=');    p_Char[0] = '*';    for (s=p_line[0]; *s; s++)	if (*s == '-')	    *s = '*';    /* now turn the old into the new */    assert(tp_char[0] == '*');    tp_char[0] = '=';    for (s=tp_line[0]; *s; s++)	if (*s == '*')	    *s = '-';    for (i=0; n <= p_end; i++,n++) {	p_line[n] = tp_line[i];	p_Char[n] = tp_char[i];	if (p_Char[n] == '-')	    p_Char[n] = '+';	p_len[n] = tp_len[i];    }    assert(i == p_ptrn_lines + 1);    i = p_ptrn_lines;    p_ptrn_lines = p_repl_lines;    p_repl_lines = i;    if (tp_line)      free (tp_line);    if (tp_len)      free (tp_len);    if (tp_char)      free (tp_char);    return TRUE;}/* Return whether file WHICH (0 = old, 1 = new) appears to nonexistent.   Return 1 for empty, 2 for nonexistent.  */boolpch_says_nonexistent (which)     int which;{  return p_says_nonexistent[which];}/* Return timestamp of patch header for file WHICH (0 = old, 1 = new),   or -1 if there was no timestamp or an error in the timestamp.  */time_tpch_timestamp (which)     int which;{  return p_timestamp[which];}/* Return the specified line position in the old file of the old context. */LINENUMpch_first(){    return p_first;}/* Return the number of lines of old context. */LINENUMpch_ptrn_lines(){    return p_ptrn_lines;}/* Return the probable line position in the new file of the first line. */LINENUMpch_newfirst(){    return p_newfirst;}/* Return the number of lines in the replacement text including context. */LINENUMpch_repl_lines(){    return p_repl_lines;}/* Return the number of lines in the whole hunk. */LINENUMpch_end(){    return p_end;}/* Return the number of context lines before the first changed line. */LINENUMpch_prefix_context (){    return p_prefix_context;}/* Return the number of context lines after the last changed line. */LINENUMpch_suffix_context (){    return p_suffix_context;}/* Return the length of a particular patch line. */size_tpch_line_len(line)LINENUM line;{    return p_len[line];}/* Return the control character (+, -, *, !, etc) for a patch line. */charpch_char(line)LINENUM line;{    return p_Char[line];}/* Return a pointer to a particular patch line. */char *pfetch(line)LINENUM line;{    return p_line[line];}/* Output a patch line.  */boolpch_write_line (line, file)     LINENUM line;     FILE *file;{  bool after_newline = p_line[line][p_len[line] - 1] == '\n';  if (! fwrite (p_line[line], sizeof (*p_line[line]), p_len[line], file))    write_fatal ();  return after_newline;}/* Return where in the patch file this hunk began, for error messages. */LINENUMpch_hunk_beg(){    return p_hunk_beg;}/* Apply an ed script by feeding ed itself. */voiddo_ed_script (ofp)     FILE *ofp;{    static char const ed_program[] = ed_PROGRAM;    register char *t;    register file_offset beginning_of_this_line;    register bool this_line_is_command = FALSE;    register FILE *pipefp = 0;    register size_t chars_read;    if (!skip_rest_of_patch) {	assert (! inerrno);	copy_file (inname, TMPOUTNAME, instat.st_mode);	sprintf (buf, "%s %s%s", ed_program, verbosity == VERBOSE ? "" : "- ",		 TMPOUTNAME);	fflush (stdout);	pipefp = popen(buf, binary_transput ? "wb" : "w");	if (!pipefp)	  pfatal ("can't open pipe to `%s'", buf);    }    for (;;) {	beginning_of_this_line = file_tell (pfp);	chars_read = get_line ();	if (! chars_read) {	    next_intuit_at(beginning_of_this_line,p_input_line);	    break;	}	for (t = buf;  ISDIGIT (*t) || *t == ',';  t++)	  continue;	this_line_is_command = (ISDIGIT (*buf) &&	  (*t == 'd' || *t == 'c' || *t == 'a' || *t == 'i' || *t == 's') );	if (this_line_is_command) {	    if (pipefp)		if (! fwrite (buf, sizeof *buf, chars_read, pipefp))		    write_fatal ();	    if (*t != 'd' && *t != 's') {		while ((chars_read = get_line ()) != 0) {		    if (pipefp)			if (! fwrite (buf, sizeof *buf, chars_read, pipefp))			    write_fatal ();		    if (chars_read == 2  &&  strEQ (buf, ".\n"))			break;		}	    }	}	else {	    next_intuit_at(beginning_of_this_line,p_input_line);	    break;	}    }    if (!pipefp)      return;    if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0	|| fflush (pipefp) != 0)      write_fatal ();    if (pclose (pipefp) != 0)      fatal ("%s FAILED", ed_program);    if (ofp)      {	FILE *ifp = fopen (TMPOUTNAME, binary_transput ? "rb" : "r");	int c;	if (!ifp)	  pfatal ("can't open `%s'", TMPOUTNAME);	while ((c = getc (ifp)) != EOF)	  if (putc (c, ofp) == EOF)	    write_fatal ();	if (ferror (ifp) || fclose (ifp) != 0)	  read_fatal ();      }}

⌨️ 快捷键说明

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