[BACK]Return to pch.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / patch

Diff for /src/usr.bin/patch/pch.c between version 1.20 and 1.21

version 1.20, 2003/07/21 14:32:21 version 1.21, 2003/07/22 17:18:49
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 #ifndef lint  #ifndef lint
 static char rcsid[] = "$OpenBSD$";  static const char rcsid[] = "$OpenBSD$";
 #endif /* not lint */  #endif /* not lint */
   
   #include <sys/types.h>
   #include <sys/stat.h>
   
   #include <assert.h>
   #include <ctype.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   
 #include "EXTERN.h"  #include "EXTERN.h"
 #include "common.h"  #include "common.h"
 #include "util.h"  #include "util.h"
 #include "INTERN.h"  #include "INTERN.h"
 #include "pch.h"  #include "pch.h"
   
 extern bool     check_only;  
 /* Patch (diff listing) abstract type. */  /* Patch (diff listing) abstract type. */
   
 static long     p_filesize;     /* size of the patch file */  static long     p_filesize;     /* size of the patch file */
Line 22 
Line 30 
 static LINENUM  p_max;          /* max allowed value of p_end */  static LINENUM  p_max;          /* max allowed value of p_end */
 static LINENUM  p_context = 3;  /* # of context lines */  static LINENUM  p_context = 3;  /* # of context lines */
 static LINENUM  p_input_line = 0;       /* current line # from patch file */  static LINENUM  p_input_line = 0;       /* current line # from patch file */
 static char     **p_line = Null(char **);       /* the text of the hunk */  static char     **p_line = NULL;        /* the text of the hunk */
 static short    *p_len = Null(short *); /* length of each line */  static short    *p_len = NULL;  /* length of each line */
 static char     *p_char = Nullch;/* +, -, and ! */  static char     *p_char = NULL;/* +, -, and ! */
 static int      hunkmax = INITHUNKMAX;  /* size of above arrays to begin with */  static int      hunkmax = INITHUNKMAX;  /* size of above arrays to begin with */
 static int      p_indent;       /* indent to patch */  static int      p_indent;       /* indent to patch */
 static LINENUM  p_base;         /* where to intuit this time */  static LINENUM  p_base;         /* where to intuit this time */
Line 35 
Line 43 
 static LINENUM  p_efake = -1;   /* end of faked up lines--don't free */  static LINENUM  p_efake = -1;   /* end of faked up lines--don't free */
 static LINENUM  p_bfake = -1;   /* beg of faked up lines */  static LINENUM  p_bfake = -1;   /* beg of faked up lines */
   
   static void     grow_hunkmax(void);
   static int      intuit_diff_type(void);
   static void     next_intuit_at(long, long);
   static void     skip_to(long, long);
   static char     *pgets(char *, int, FILE *);
   
 /*  /*
  * Prepare to look for the next patch in the patch file.   * Prepare to look for the next patch in the patch file.
  */   */
 void  void
 re_patch(void)  re_patch(void)
 {  {
         p_first = Nulline;          p_first = NULL;
         p_newfirst = Nulline;          p_newfirst = NULL;
         p_ptrn_lines = Nulline;          p_ptrn_lines = NULL;
         p_repl_lines = Nulline;          p_repl_lines = NULL;
         p_end = (LINENUM) - 1;          p_end = (LINENUM) - 1;
         p_max = Nulline;          p_max = NULL;
         p_indent = 0;          p_indent = 0;
 }  }
   
Line 56 
Line 70 
 void  void
 open_patch_file(char *filename)  open_patch_file(char *filename)
 {  {
         if (filename == Nullch || !*filename || strEQ(filename, "-")) {          if (filename == NULL || !*filename || strEQ(filename, "-")) {
                 pfp = fopen(TMPPATNAME, "w");                  pfp = fopen(TMPPATNAME, "w");
                 if (pfp == Nullfp)                  if (pfp == NULL)
                         pfatal("can't create %s", TMPPATNAME);                          pfatal("can't create %s", TMPPATNAME);
                 while (fgets(buf, sizeof buf, stdin) != Nullch)                  while (fgets(buf, sizeof buf, stdin) != NULL)
                         fputs(buf, pfp);                          fputs(buf, pfp);
                 fclose(pfp);                  fclose(pfp);
                 filename = TMPPATNAME;                  filename = TMPPATNAME;
         }          }
         pfp = fopen(filename, "r");          pfp = fopen(filename, "r");
         if (pfp == Nullfp)          if (pfp == NULL)
                 pfatal("patch file %s not found", filename);                  pfatal("patch file %s not found", filename);
         fstat(fileno(pfp), &filestat);          fstat(fileno(pfp), &filestat);
         p_filesize = filestat.st_size;          p_filesize = filestat.st_size;
Line 80 
Line 94 
 void  void
 set_hunkmax(void)  set_hunkmax(void)
 {  {
 #ifndef lint          if (p_line == NULL)
         if (p_line == Null(char **))                  p_line = malloc((size_t) hunkmax * sizeof(char *));
                 p_line = (char **) malloc((size_t) hunkmax * sizeof(char *));          if (p_len == NULL)
         if (p_len == Null(short *))                  p_len = malloc((size_t) hunkmax * sizeof(short));
                 p_len = (short *) malloc((size_t) hunkmax * sizeof(short));          if (p_char == NULL)
 #endif                  p_char = malloc((size_t) hunkmax * sizeof(char));
         if (p_char == Nullch)  
                 p_char = (char *) malloc((size_t) hunkmax * sizeof(char));  
 }  }
   
 /*  /*
  * Enlarge the arrays containing the current hunk of patch.   * Enlarge the arrays containing the current hunk of patch.
  */   */
 void  static void
 grow_hunkmax(void)  grow_hunkmax(void)
 {  {
         hunkmax *= 2;          hunkmax *= 2;
Line 103 
Line 115 
          * since p_len can move into p_line's old space, and p_char can move into           * since p_len can move into p_line's old space, and p_char can move into
          * p_len's old space.  Not on PDP-11's however.  But it doesn't matter.           * p_len's old space.  Not on PDP-11's however.  But it doesn't matter.
          */           */
         assert(p_line != Null(char **) &&p_len != Null(short *) &&p_char != Nullch);          assert(p_line != NULL &&p_len != NULL &&p_char != NULL);
 #ifndef lint  
         p_line = (char **) realloc((char *) p_line, hunkmax * sizeof(char *));          p_line = realloc(p_line, hunkmax * sizeof(char *));
         p_len = (short *) realloc((char *) p_len, hunkmax * sizeof(short));          p_len = realloc(p_len, hunkmax * sizeof(short));
         p_char = (char *) realloc((char *) p_char, hunkmax * sizeof(char));          p_char = realloc(p_char, hunkmax * sizeof(char));
 #endif  
         if (p_line != Null(char **) &&p_len != Null(short *) &&p_char != Nullch)          if (p_line != NULL &&p_len != NULL &&p_char != NULL)
                 return;                  return;
         if (!using_plan_a)          if (!using_plan_a)
                 fatal("out of memory\n");                  fatal("out of memory\n");
Line 150 
Line 162 
                 say("(Patch is indented %d space%s.)\n", p_indent,                  say("(Patch is indented %d space%s.)\n", p_indent,
                     p_indent == 1 ? "" : "s");                      p_indent == 1 ? "" : "s");
         skip_to(p_start, p_sline);          skip_to(p_start, p_sline);
         while (filearg[0] == Nullch) {          while (filearg[0] == NULL) {
                 if (force || batch) {                  if (force || batch) {
                         say("No file to patch.  Skipping...\n");                          say("No file to patch.  Skipping...\n");
                         filearg[0] = savestr(bestguess);                          filearg[0] = savestr(bestguess);
Line 164 
Line 176 
                         bestguess = savestr(buf);                          bestguess = savestr(buf);
                         filearg[0] = fetchname(buf, 0, FALSE);                          filearg[0] = fetchname(buf, 0, FALSE);
                 }                  }
                 if (filearg[0] == Nullch) {                  if (filearg[0] == NULL) {
                         ask("No file found--skip this patch? [n] ");                          ask("No file found--skip this patch? [n] ");
                         if (*buf != 'y')                          if (*buf != 'y')
                                 continue;                                  continue;
Line 180 
Line 192 
   
 /* Determine what kind of diff is in the remaining part of the patch file. */  /* Determine what kind of diff is in the remaining part of the patch file. */
   
 int  static int
 intuit_diff_type(void)  intuit_diff_type(void)
 {  {
         long    this_line = 0, previous_line;          long    this_line = 0, previous_line;
Line 188 
Line 200 
         bool    last_line_was_command = FALSE, this_is_a_command = FALSE;          bool    last_line_was_command = FALSE, this_is_a_command = FALSE;
         bool    stars_last_line = FALSE, stars_this_line = FALSE;          bool    stars_last_line = FALSE, stars_this_line = FALSE;
         char    *s, *t;          char    *s, *t;
         char    *indtmp = Nullch;          char    *indtmp = NULL;
         char    *oldtmp = Nullch;          char    *oldtmp = NULL;
         char    *newtmp = Nullch;          char    *newtmp = NULL;
         char    *indname = Nullch;          char    *indname = NULL;
         char    *oldname = Nullch;          char    *oldname = NULL;
         char    *newname = Nullch;          char    *newname = NULL;
         int     indent, retval;          int     indent, retval;
         bool    no_filearg = (filearg[0] == Nullch);          bool    no_filearg = (filearg[0] == NULL);
   
         ok_to_create_file = FALSE;          ok_to_create_file = FALSE;
         fseek(pfp, p_base, 0);          fseek(pfp, p_base, SEEK_SET);
         p_input_line = p_bline - 1;          p_input_line = p_bline - 1;
         for (;;) {          for (;;) {
                 previous_line = this_line;                  previous_line = this_line;
Line 207 
Line 219 
                 this_line = ftell(pfp);                  this_line = ftell(pfp);
                 indent = 0;                  indent = 0;
                 p_input_line++;                  p_input_line++;
                 if (fgets(buf, sizeof buf, pfp) == Nullch) {                  if (fgets(buf, sizeof buf, pfp) == NULL) {
                         if (first_command_line >= 0L) {                          if (first_command_line >= 0L) {
                                 /* nothing but deletes!? */                                  /* nothing but deletes!? */
                                 p_start = first_command_line;                                  p_start = first_command_line;
Line 254 
Line 266 
                         *t = '\0';                          *t = '\0';
                         if (!*revision) {                          if (!*revision) {
                                 free(revision);                                  free(revision);
                                 revision = Nullch;                                  revision = NULL;
                         }                          }
                 }                  }
                 if ((!diff_type || diff_type == ED_DIFF) &&                  if ((!diff_type || diff_type == ED_DIFF) &&
Line 305 
Line 317 
         }          }
 scan_exit:  scan_exit:
         if (no_filearg) {          if (no_filearg) {
                 if (indtmp != Nullch)                  if (indtmp != NULL)
                         indname = fetchname(indtmp, strippath, ok_to_create_file);                          indname = fetchname(indtmp, strippath, ok_to_create_file);
                 if (oldtmp != Nullch)                  if (oldtmp != NULL)
                         oldname = fetchname(oldtmp, strippath, ok_to_create_file);                          oldname = fetchname(oldtmp, strippath, ok_to_create_file);
                 if (newtmp != Nullch)                  if (newtmp != NULL)
                         newname = fetchname(newtmp, strippath, ok_to_create_file);                          newname = fetchname(newtmp, strippath, ok_to_create_file);
                 if (indname)                  if (indname)
                         filearg[0] = savestr(indname);                          filearg[0] = savestr(indname);
Line 325 
Line 337 
         }          }
         if (bestguess) {          if (bestguess) {
                 free(bestguess);                  free(bestguess);
                 bestguess = Nullch;                  bestguess = NULL;
         }          }
         if (filearg[0] != Nullch)          if (filearg[0] != NULL)
                 bestguess = savestr(filearg[0]);                  bestguess = savestr(filearg[0]);
         else if (indtmp != Nullch)          else if (indtmp != NULL)
                 bestguess = fetchname(indtmp, strippath, TRUE);                  bestguess = fetchname(indtmp, strippath, TRUE);
         else {          else {
                 if (oldtmp != Nullch)                  if (oldtmp != NULL)
                         oldname = fetchname(oldtmp, strippath, TRUE);                          oldname = fetchname(oldtmp, strippath, TRUE);
                 if (newtmp != Nullch)                  if (newtmp != NULL)
                         newname = fetchname(newtmp, strippath, TRUE);                          newname = fetchname(newtmp, strippath, TRUE);
                 if (oldname && newname) {                  if (oldname && newname) {
                         if (strlen(oldname) < strlen(newname))                          if (strlen(oldname) < strlen(newname))
Line 346 
Line 358 
                 else if (newname)                  else if (newname)
                         bestguess = savestr(newname);                          bestguess = savestr(newname);
         }          }
         if (indtmp != Nullch)          free(indtmp);
                 free(indtmp);          free(oldtmp);
         if (oldtmp != Nullch)          free(newtmp);
                 free(oldtmp);          free(indname);
         if (newtmp != Nullch)          free(oldname);
                 free(newtmp);          free(newname);
         if (indname != Nullch)  
                 free(indname);  
         if (oldname != Nullch)  
                 free(oldname);  
         if (newname != Nullch)  
                 free(newname);  
         return retval;          return retval;
 }  }
   
 /*  /*
  * Remember where this patch ends so we know where to start up again.   * Remember where this patch ends so we know where to start up again.
  */   */
 void  static void
 next_intuit_at(long file_pos, long file_line)  next_intuit_at(long file_pos, long file_line)
 {  {
         p_base = file_pos;          p_base = file_pos;
Line 374 
Line 380 
 /*  /*
  * Basically a verbose fseek() to the actual diff listing.   * Basically a verbose fseek() to the actual diff listing.
  */   */
 void  static void
 skip_to(long file_pos, long file_line)  skip_to(long file_pos, long file_line)
 {  {
         char    *ret;          char    *ret;
   
         assert(p_base <= file_pos);          assert(p_base <= file_pos);
         if (verbose && p_base < file_pos) {          if (verbose && p_base < file_pos) {
                 fseek(pfp, p_base, 0);                  fseek(pfp, p_base, SEEK_SET);
                 say("The text leading up to this was:\n--------------------------\n");                  say("The text leading up to this was:\n--------------------------\n");
                 while (ftell(pfp) < file_pos) {                  while (ftell(pfp) < file_pos) {
                         ret = fgets(buf, sizeof buf, pfp);                          ret = fgets(buf, sizeof buf, pfp);
                         assert(ret != Nullch);                          assert(ret != NULL);
                         say("|%s", buf);                          say("|%s", buf);
                 }                  }
                 say("--------------------------\n");                  say("--------------------------\n");
         } else          } else
                 fseek(pfp, file_pos, 0);                  fseek(pfp, file_pos, SEEK_SET);
         p_input_line = file_line - 1;          p_input_line = file_line - 1;
 }  }
   
Line 468 
Line 474 
   
                 ret = pgets(buf, sizeof buf, pfp);                  ret = pgets(buf, sizeof buf, pfp);
                 p_input_line++;                  p_input_line++;
                 if (ret == Nullch || strnNE(buf, "********", 8)) {                  if (ret == NULL || strnNE(buf, "********", 8)) {
                         next_intuit_at(line_beginning, p_input_line);                          next_intuit_at(line_beginning, p_input_line);
                         return FALSE;                          return FALSE;
                 }                  }
Line 478 
Line 484 
                         line_beginning = ftell(pfp);                          line_beginning = ftell(pfp);
                         ret = pgets(buf, sizeof buf, pfp);                          ret = pgets(buf, sizeof buf, pfp);
                         p_input_line++;                          p_input_line++;
                         if (ret == Nullch) {                          if (ret == NULL) {
                                 if (p_max - p_end < 4) {                                  if (p_max - p_end < 4) {
                                         /* assume blank lines got chopped */                                          /* assume blank lines got chopped */
                                         strlcpy(buf, "  \n", sizeof buf);                                          strlcpy(buf, "  \n", sizeof buf);
Line 493 
Line 499 
                         p_end++;                          p_end++;
                         assert(p_end < hunkmax);                          assert(p_end < hunkmax);
                         p_char[p_end] = *buf;                          p_char[p_end] = *buf;
                         p_line[p_end] = Nullch;                          p_line[p_end] = NULL;
                         switch (*buf) {                          switch (*buf) {
                         case '*':                          case '*':
                                 if (strnEQ(buf, "********", 8)) {                                  if (strnEQ(buf, "********", 8)) {
Line 711 
Line 717 
                         p_input_line = repl_patch_line;                          p_input_line = repl_patch_line;
                         for (p_end--; p_end > repl_beginning; p_end--)                          for (p_end--; p_end > repl_beginning; p_end--)
                                 free(p_line[p_end]);                                  free(p_line[p_end]);
                         fseek(pfp, repl_backtrack_position, 0);                          fseek(pfp, repl_backtrack_position, SEEK_SET);
   
                         /* redundant 'new' context lines were omitted - set */                          /* redundant 'new' context lines were omitted - set */
                         /* up to fill them in from the old file context */                          /* up to fill them in from the old file context */
Line 792 
Line 798 
   
                 ret = pgets(buf, sizeof buf, pfp);                  ret = pgets(buf, sizeof buf, pfp);
                 p_input_line++;                  p_input_line++;
                 if (ret == Nullch || strnNE(buf, "@@ -", 4)) {                  if (ret == NULL || strnNE(buf, "@@ -", 4)) {
                         next_intuit_at(line_beginning, p_input_line);                          next_intuit_at(line_beginning, p_input_line);
                         return FALSE;                          return FALSE;
                 }                  }
Line 856 
Line 862 
                         line_beginning = ftell(pfp);                          line_beginning = ftell(pfp);
                         ret = pgets(buf, sizeof buf, pfp);                          ret = pgets(buf, sizeof buf, pfp);
                         p_input_line++;                          p_input_line++;
                         if (ret == Nullch) {                          if (ret == NULL) {
                                 if (p_max - filldst < 3) {                                  if (p_max - filldst < 3) {
                                         /* assume blank lines got chopped */                                          /* assume blank lines got chopped */
                                         strlcpy(buf, " \n", sizeof buf);                                          strlcpy(buf, " \n", sizeof buf);
Line 954 
Line 960 
                 p_context = 0;                  p_context = 0;
                 ret = pgets(buf, sizeof buf, pfp);                  ret = pgets(buf, sizeof buf, pfp);
                 p_input_line++;                  p_input_line++;
                 if (ret == Nullch || !isdigit(*buf)) {                  if (ret == NULL || !isdigit(*buf)) {
                         next_intuit_at(line_beginning, p_input_line);                          next_intuit_at(line_beginning, p_input_line);
                         return FALSE;                          return FALSE;
                 }                  }
Line 998 
Line 1004 
                 for (i = 1; i <= p_ptrn_lines; i++) {                  for (i = 1; i <= p_ptrn_lines; i++) {
                         ret = pgets(buf, sizeof buf, pfp);                          ret = pgets(buf, sizeof buf, pfp);
                         p_input_line++;                          p_input_line++;
                         if (ret == Nullch)                          if (ret == NULL)
                                 fatal("unexpected end of file in patch at line %ld\n",                                  fatal("unexpected end of file in patch at line %ld\n",
                                     p_input_line);                                      p_input_line);
                         if (*buf != '<')                          if (*buf != '<')
Line 1020 
Line 1026 
                 if (hunk_type == 'c') {                  if (hunk_type == 'c') {
                         ret = pgets(buf, sizeof buf, pfp);                          ret = pgets(buf, sizeof buf, pfp);
                         p_input_line++;                          p_input_line++;
                         if (ret == Nullch)                          if (ret == NULL)
                                 fatal("unexpected end of file in patch at line %ld\n",                                  fatal("unexpected end of file in patch at line %ld\n",
                                     p_input_line);                                      p_input_line);
                         if (*buf != '-')                          if (*buf != '-')
Line 1037 
Line 1043 
                 for (i++; i <= p_end; i++) {                  for (i++; i <= p_end; i++) {
                         ret = pgets(buf, sizeof buf, pfp);                          ret = pgets(buf, sizeof buf, pfp);
                         p_input_line++;                          p_input_line++;
                         if (ret == Nullch)                          if (ret == NULL)
                                 fatal("unexpected end of file in patch at line %ld\n",                                  fatal("unexpected end of file in patch at line %ld\n",
                                     p_input_line);                                      p_input_line);
                         if (*buf != '>')                          if (*buf != '>')
Line 1084 
Line 1090 
 /*  /*
  * Input a line from the patch file, worrying about indentation.   * Input a line from the patch file, worrying about indentation.
  */   */
 char *  static char *
 pgets(char *bf, int sz, FILE *fp)  pgets(char *bf, int sz, FILE *fp)
 {  {
         char    *s, *ret = fgets(bf, sz, fp);          char    *s, *ret = fgets(bf, sz, fp);
         int     indent = 0;          int     indent = 0;
   
         if (p_indent && ret != Nullch) {          if (p_indent && ret != NULL) {
                 for (s = buf;                  for (s = buf;
                     indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X');                      indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X');
                     s++) {                      s++) {
Line 1128 
Line 1134 
         tp_line = p_line;          tp_line = p_line;
         tp_len = p_len;          tp_len = p_len;
         tp_char = p_char;          tp_char = p_char;
         p_line = Null(char **); /* force set_hunkmax to allocate again */          p_line = NULL;  /* force set_hunkmax to allocate again */
         p_len = Null(short *);          p_len = NULL;
         p_char = Nullch;          p_char = NULL;
         set_hunkmax();          set_hunkmax();
         if (p_line == Null(char **) ||p_len == Null(short *) ||p_char == Nullch) {          if (p_line == NULL ||p_len == NULL ||p_char == NULL) {
 #ifndef lint  
                 if (p_line == Null(char **))                  if (p_line == NULL) /* XXX */
                         free((char *) p_line);                          free(p_line);
                 p_line = tp_line;                  p_line = tp_line;
                 if (p_len == Null(short *))                  if (p_len == NULL) /* XXX */
                         free((char *) p_len);                          free(p_len);
                 p_len = tp_len;                  p_len = tp_len;
 #endif                  if (p_char == NULL) /* XXX */
                 if (p_char == Nullch)                          free(p_char);
                         free((char *) p_char);  
                 p_char = tp_char;                  p_char = tp_char;
                 return FALSE;   /* not enough memory to swap hunk! */                  return FALSE;   /* not enough memory to swap hunk! */
         }          }
Line 1199 
Line 1204 
         i = p_ptrn_lines;          i = p_ptrn_lines;
         p_ptrn_lines = p_repl_lines;          p_ptrn_lines = p_repl_lines;
         p_repl_lines = i;          p_repl_lines = i;
 #ifndef lint  
         if (tp_line == Null(char **))          if (tp_line == NULL) /* XXX */
                 free((char *) tp_line);                  free(tp_line);
         if (tp_len == Null(short *))          if (tp_len == NULL) /* XXX */
                 free((char *) tp_len);                  free(tp_len);
 #endif          if (tp_char == NULL) /* XXX */
         if (tp_char == Nullch)                  free(tp_char);
                 free((char *) tp_char);  
         return TRUE;          return TRUE;
 }  }
   
Line 1322 
Line 1326 
         }          }
         for (;;) {          for (;;) {
                 beginning_of_this_line = ftell(pfp);                  beginning_of_this_line = ftell(pfp);
                 if (pgets(buf, sizeof buf, pfp) == Nullch) {                  if (pgets(buf, sizeof buf, pfp) == NULL) {
                         next_intuit_at(beginning_of_this_line, p_input_line);                          next_intuit_at(beginning_of_this_line, p_input_line);
                         break;                          break;
                 }                  }
Line 1335 
Line 1339 
                         if (!skip_rest_of_patch)                          if (!skip_rest_of_patch)
                                 fputs(buf, pipefp);                                  fputs(buf, pipefp);
                         if (*t != 'd') {                          if (*t != 'd') {
                                 while (pgets(buf, sizeof buf, pfp) != Nullch) {                                  while (pgets(buf, sizeof buf, pfp) != NULL) {
                                         p_input_line++;                                          p_input_line++;
                                         if (!skip_rest_of_patch)                                          if (!skip_rest_of_patch)
                                                 fputs(buf, pipefp);                                                  fputs(buf, pipefp);

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21