diff -c old/common.h new/common.h
*** old/common.h	Wed Dec 27 14:03:26 1989
--- new/common.h	Mon Feb 18 19:46:34 1991
***************
*** 28,36 ****
  #define Fclose (void)fclose
  #define Fflush (void)fflush
  #define Sprintf (void)sprintf
- #ifndef MSDOS
  #define Mktemp (void)mktemp
- #endif
  #define Strcpy (void)strcpy
  #define Strcat (void)strcat
  
--- 28,34 ----
***************
*** 58,70 ****
  #define CHECKOUT "co -l %s"
  
  #ifdef FLEXFILENAMES
- #ifdef MSDOS
- #define ORIGEXT ".org"
- #define REJEXT ".rej"
- #else
  #define ORIGEXT ".orig"
  #define REJEXT ".rej"
- #endif
  #else
  #define ORIGEXT "~"
  #define REJEXT "#"
--- 56,63 ----
***************
*** 119,135 ****
  EXT char *origext INIT(Nullch);
  EXT char *origprae INIT(Nullch);
  
! #ifdef MSDOS
! EXT char TMPOUTNAME[80] INIT("poXXXXXX");
! EXT char TMPINNAME[80] INIT("piXXXXXX"); /* might want /usr/tmp here */
! EXT char TMPREJNAME[80] INIT("prXXXXXX");
! EXT char TMPPATNAME[80] INIT("ppXXXXXX");
! #else
! EXT char TMPOUTNAME[] INIT("/tmp/patchoXXXXXX");
! EXT char TMPINNAME[] INIT("/tmp/patchiXXXXXX");	/* might want /usr/tmp here */
! EXT char TMPREJNAME[] INIT("/tmp/patchrXXXXXX");
! EXT char TMPPATNAME[] INIT("/tmp/patchpXXXXXX");
! #endif
  
  EXT bool toutkeep INIT(FALSE);
  EXT bool trejkeep INIT(FALSE);
--- 112,121 ----
  EXT char *origext INIT(Nullch);
  EXT char *origprae INIT(Nullch);
  
! EXT char *TMPOUTNAME;
! EXT char *TMPINNAME;
! EXT char *TMPREJNAME;
! EXT char *TMPPATNAME;
  
  EXT bool toutkeep INIT(FALSE);
  EXT bool trejkeep INIT(FALSE);
***************
*** 151,156 ****
--- 137,143 ----
  #define NORMAL_DIFF 2
  #define ED_DIFF 3
  #define NEW_CONTEXT_DIFF 4
+ #define UNI_DIFF 5
  EXT int diff_type INIT(0);
  
  EXT bool do_defines INIT(FALSE);	/* patch using ifdef, ifndef, etc. */
***************
*** 178,180 ****
--- 165,168 ----
  #else
  int sprintf();
  #endif
+ char *getenv();
diff -c old/inp.c new/inp.c
*** old/inp.c	Sat Mar 10 20:19:38 1990
--- new/inp.c	Mon Feb 18 19:00:46 1991
***************
*** 135,144 ****
  #endif
      if (i_womp == Nullch)
  	return FALSE;
!     if ((ifd = open(filename, 0)) < 0)
  	fatal2("Can't open file %s\n", filename);
  #ifndef lint
! #ifdef MSDOS
      if ((i_res = read(ifd, i_womp, (int)i_size)) == -1) {
  	Close(ifd);	/* probably means i_size > 15 or 16 bits worth */
  	free(i_womp);	/* at this point it doesn't matter if i_womp was */
--- 135,145 ----
  #endif
      if (i_womp == Nullch)
  	return FALSE;
!     if ((ifd = open(filename, O_BINARY)) < 0)
  	fatal2("Can't open file %s\n", filename);
  #ifndef lint
! #ifdef DUMMY_MSDOS
!     /* this hack is now obsolete in binary mode */
      if ((i_res = read(ifd, i_womp, (int)i_size)) == -1) {
  	Close(ifd);	/* probably means i_size > 15 or 16 bits worth */
  	free(i_womp);	/* at this point it doesn't matter if i_womp was */
***************
*** 224,230 ****
      Reg4 bool found_revision = (revision == Nullch);
  
      using_plan_a = FALSE;
!     if ((ifp = fopen(filename, "r")) == Nullfp)
  	fatal2("Can't open file %s\n", filename);
      if ((tifd = open(TMPINNAME, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
                       S_IWRITE|S_IREAD)) < 0)
--- 225,231 ----
      Reg4 bool found_revision = (revision == Nullch);
  
      using_plan_a = FALSE;
!     if ((ifp = fopen(filename, "rb")) == Nullfp)
  	fatal2("Can't open file %s\n", filename);
      if ((tifd = open(TMPINNAME, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
                       S_IWRITE|S_IREAD)) < 0)
***************
*** 326,332 ****
      if (revision == Nullch)
  	return TRUE;
      patlen = strlen(revision);
!     if (strnEQ(string,revision,patlen) && isspace(s[patlen]))
  	return TRUE;
      for (s = string; *s; s++) {
  	if (isspace(*s) && strnEQ(s+1, revision, patlen) &&
--- 327,333 ----
      if (revision == Nullch)
  	return TRUE;
      patlen = strlen(revision);
!     if (strnEQ(string,revision,patlen) && isspace(string[patlen]))
  	return TRUE;
      for (s = string; *s; s++) {
  	if (isspace(*s) && strnEQ(s+1, revision, patlen) &&
Only in new: isvalid.c
Only in old: makefile
Only in old: malloc.c
diff -c old/patch.c new/patch.c
*** old/patch.c	Wed Dec 27 14:03:26 1989
--- new/patch.c	Mon Feb 18 19:15:32 1991
***************
*** 1,5 ****
  char rcsid[] =
! 	"$Header: patch.c,v 2.0.1.6 88/06/22 20:46:39 lwall Locked $";
  
  /* patch - a program to apply diffs to original files
   *
--- 1,5 ----
  char rcsid[] =
! 	"$Header: patch.c,v 2.0.2.0 90/05/01 22:17:50 davison Locked $";
  
  /* patch - a program to apply diffs to original files
   *
***************
*** 9,14 ****
--- 9,17 ----
   * money off of it, or pretend that you wrote it.
   *
   * $Log:	patch.c,v $
+  * Revision 2.0.2.0  90/05/01  22:17:50  davison
+  * patch12u: unidiff support added
+  *
   * Revision 2.0.1.6  88/06/22  20:46:39  lwall
   * patch12: rindex() wasn't declared
   *
***************
*** 94,99 ****
--- 97,103 ----
  #include "util.h"
  #include "pch.h"
  #include "inp.h"
+ #include "patchlev.h"
  
  /* procedures */
  
***************
*** 112,118 ****
--- 116,127 ----
  void re_input();
  void my_exit();
  char *strchr();
+ char *strrchr();
+ 
+ /* Nonzero if -R was specified on command line.  */
+ static int reverse_flag_specified = FALSE;
  
+ /* Program name */
  static char *myname;
  
  /* Apply a set of diffs as appropriate. */
***************
*** 138,147 ****
  
      for (i = 0; i<MAXFILEC; i++)
  	filearg[i] = Nullch;
!     Mktemp(TMPOUTNAME);
!     Mktemp(TMPINNAME);
!     Mktemp(TMPREJNAME);
!     Mktemp(TMPPATNAME);
  
      /* parse switches */
      Argc = argc;
--- 147,189 ----
  
      for (i = 0; i<MAXFILEC; i++)
  	filearg[i] = Nullch;
! 
!     /* Cons up the names of the temporary files.  */
!     {
!       /* Directory for temporary files.  */
!       char *tmpdir;
!       int tmpname_len;
! 
! #ifdef MSDOS
!       tmpdir = getenv ("TMP");
! #else
!       tmpdir = getenv ("TMPDIR");
! #endif
!       if (tmpdir == NULL) {
! 	tmpdir = "/tmp";
!       }
!       tmpname_len = strlen (tmpdir) + 20;
! 
!       TMPOUTNAME = (char *) malloc (tmpname_len);
!       strcpy (TMPOUTNAME, tmpdir);
!       strcat (TMPOUTNAME, "/poXXXXXX");
!       Mktemp(TMPOUTNAME);
! 
!       TMPINNAME = (char *) malloc (tmpname_len);
!       strcpy (TMPINNAME, tmpdir);
!       strcat (TMPINNAME, "/piXXXXXX");
!       Mktemp(TMPINNAME);
! 
!       TMPREJNAME = (char *) malloc (tmpname_len);
!       strcpy (TMPREJNAME, tmpdir);
!       strcat (TMPREJNAME, "/prXXXXXX");
!       Mktemp(TMPREJNAME);
! 
!       TMPPATNAME = (char *) malloc (tmpname_len);
!       strcpy (TMPPATNAME, tmpdir);
!       strcat (TMPPATNAME, "/ppXXXXXX");
!       Mktemp(TMPPATNAME);
!     }
  
      /* parse switches */
      Argc = argc;
***************
*** 310,322 ****
  			    s[12] = s[13];	/* between .h, .c, .y, etc. */
  			s[13] = '\0';
                  }
- #else
- #ifdef MSDOS
-                 if ((s=strchr(rejname,'.'))!=NULL)
-                   *s=0;
  #endif
  #endif
  		Strcat(rejname, REJEXT);
  	    }
  	    if (skip_rest_of_patch) {
  		say4("%d out of %d hunks ignored--saving rejects to %s\n",
--- 352,373 ----
  			    s[12] = s[13];	/* between .h, .c, .y, etc. */
  			s[13] = '\0';
                  }
  #endif
+ #ifdef MSDOS
+                 s = strchr(rejname, 0);
  #endif
  		Strcat(rejname, REJEXT);
+ #ifdef MSDOS
+                 if ( !IsFileNameValid(rejname) )
+                 {
+                   *s=0;
+ 
+                   if ((s=strrchr(rejname,'.'))!=NULL)
+                     *s=0;
+ 
+                   strcat(rejname, ".rej");
+                 }
+ #endif
  	    }
  	    if (skip_rest_of_patch) {
  		say4("%d out of %d hunks ignored--saving rejects to %s\n",
***************
*** 365,371 ****
  	revision = Nullch;
      }
  
!     reverse = FALSE;
      skip_rest_of_patch = FALSE;
  
      get_some_switches();
--- 416,422 ----
  	revision = Nullch;
      }
  
!     reverse = reverse_flag_specified;
      skip_rest_of_patch = FALSE;
  
      get_some_switches();
***************
*** 374,379 ****
--- 425,438 ----
  	fatal1("You may not change to a different patch file.\n");
  }
  
+ static char *
+ nextarg()
+ {
+     if (!--Argc)
+ 	fatal2("patch: missing argument after `%s'\n", *Argv);
+     return *++Argv;
+ }
+ 
  /* Process switches and filenames up to next '+' or end of list. */
  
  void
***************
*** 393,429 ****
  	}
  	if (*s != '-' || !s[1]) {
  	    if (filec == MAXFILEC)
! 		fatal1("Too many file arguments.\n");
  	    filearg[filec++] = savestr(s);
  	}
  	else {
  	    switch (*++s) {
  	    case 'b':
! 		origext = savestr(Argv[1]);
! 		Argc--,Argv++;
  		break;
  	    case 'B':
! 		origprae = savestr(Argv[1]);
! 		Argc--,Argv++;
  		break;
  	    case 'c':
  		diff_type = CONTEXT_DIFF;
  		break;
  	    case 'd':
! 		if (!*++s) {
! 		    Argc--,Argv++;
! 		    s = Argv[0];
! 		}
  		if (chdir(s) < 0)
  		    fatal2("Can't cd to %s.\n", s);
  		break;
  	    case 'D':
  	    	do_defines = TRUE;
! 		if (!*++s) {
! 		    Argc--,Argv++;
! 		    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);
--- 452,482 ----
  	}
  	if (*s != '-' || !s[1]) {
  	    if (filec == MAXFILEC)
!  		fatal1("patch: Too many file arguments.\n");
  	    filearg[filec++] = savestr(s);
  	}
  	else {
  	    switch (*++s) {
  	    case 'b':
! 		origext = savestr(nextarg());
  		break;
  	    case 'B':
! 		origprae = savestr(nextarg());
  		break;
  	    case 'c':
  		diff_type = CONTEXT_DIFF;
  		break;
  	    case 'd':
! 		if (!*++s)
! 		    s = nextarg();
  		if (chdir(s) < 0)
  		    fatal2("Can't cd to %s.\n", s);
  		break;
  	    case 'D':
  	    	do_defines = TRUE;
! 		if (!*++s)
! 		    s = nextarg();
! 		if (!isalpha(*s) && '_' != *s)
  		    fatal1("Argument to -D not an identifier.\n");
  		Sprintf(if_defined, "#ifdef %s\n", s);
  		Sprintf(not_defined, "#ifndef %s\n", s);
***************
*** 450,457 ****
  		noreverse = TRUE;
  		break;
  	    case 'o':
! 		outname = savestr(Argv[1]);
! 		Argc--,Argv++;
  		break;
  	    case 'p':
  		if (*++s == '=')
--- 503,509 ----
  		noreverse = TRUE;
  		break;
  	    case 'o':
! 		outname = savestr(nextarg());
  		break;
  	    case 'p':
  		if (*++s == '=')
***************
*** 459,469 ****
  		strippath = atoi(s);
  		break;
  	    case 'r':
! 		Strcpy(rejname, Argv[1]);
! 		Argc--,Argv++;
  		break;
  	    case 'R':
  		reverse = TRUE;
  		break;
  	    case 's':
  		verbose = FALSE;
--- 511,521 ----
  		strippath = atoi(s);
  		break;
  	    case 'r':
! 		Strcpy(rejname, nextarg());
  		break;
  	    case 'R':
  		reverse = TRUE;
+ 		reverse_flag_specified = TRUE;
  		break;
  	    case 's':
  		verbose = FALSE;
***************
*** 471,476 ****
--- 523,531 ----
  	    case 'S':
  		skip_rest_of_patch = TRUE;
  		break;
+ 	    case 'u':
+ 		diff_type = UNI_DIFF;
+ 		break;
  	    case 'v':
  		version();
  		break;
***************
*** 497,521 ****
  
  Usage()
  {
    printf("\nUsage: %s [options] orig patchfile [+ [options] orig]\n\n", myname);
!   printf("-b   next argument is the extension to be used in place of '.orig'\n");
!   printf("-c   forces patch to interpret the patch file as a context diff\n");
!   printf("-d   next argument is a directory, cd to it before doing anything else\n");
!   printf("-D   next argument is the symbol for '#ifdef...#endif' to mark changes\n");
!   printf("-e   forces patch to interpret the patch file as an ed script\n");
!   printf("-f   do not ask any questions\n");
!   printf("-l   more loosely whitespace matching\n");
!   printf("-n   forces patch to interpret the patch file as a normal diff\n");
!   printf("-N   ignore patches that are reversed or already applied, see -R\n");
!   printf("-o   next argument is the output file name\n");
!   printf("-r   next argument is the reject file name\n");
!   printf("-R   patch was created with the old and new files swapped\n");
!   printf("-s   makes patch do its work silently, unless an error occurs\n");
!   printf("-S   ignore this patch from the patch file\n");
!   printf("-v   print out revision header and patch level\n\n");
!   printf("-F<number>    maximum fuzz factor for context diffs (default 2)\n");
!   printf("-p<number>    sets the pathname strip count\n");
!   printf("-x<number>    set internal debugging flags\n");
  }
  
  
--- 552,579 ----
  
  Usage()
  {
+   printf("\npatch 2.0, patchlevel %d\n", PATCHLEVEL);
+ 
    printf("\nUsage: %s [options] orig patchfile [+ [options] orig]\n\n", myname);
!   printf("  -b   next argument is the extension to be used in place of '.orig'\n");
!   printf("  -c   forces patch to interpret the patch file as a context diff\n");
!   printf("  -d   next argument is a directory, cd to it before doing anything else\n");
!   printf("  -D   next argument is the symbol for '#ifdef...#endif' to mark changes\n");
!   printf("  -e   forces patch to interpret the patch file as an ed script\n");
!   printf("  -f   do not ask any questions\n");
!   printf("  -l   more loosely whitespace matching\n");
!   printf("  -n   forces patch to interpret the patch file as a normal diff\n");
!   printf("  -N   ignore patches that are reversed or already applied, see -R\n");
!   printf("  -o   next argument is the output file name\n");
!   printf("  -r   next argument is the reject file name\n");
!   printf("  -R   patch was created with the old and new files swapped\n");
!   printf("  -s   makes patch do its work silently, unless an error occurs\n");
!   printf("  -S   ignore this patch from the patch file\n");
!   printf("  -u   forces patch to interpret the patch file as a unified context diff\n");
!   printf("  -v   print out revision header and patch level\n\n");
!   printf("  -F<number>    maximum fuzz factor for context diffs (default 2)\n");
!   printf("  -p<number>    sets the pathname strip count\n");
!   printf("  -x<number>    set internal debugging flags\n");
  }
  
  
***************
*** 576,583 ****
      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++) {
--- 634,641 ----
      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++) {
***************
*** 613,618 ****
--- 671,699 ----
  
  /* We found where to apply it (we hope), so do it. */
  
+ #ifdef MSDOS
+ static int fputs(const char *buffer, FILE *file)
+ {
+   const char *ptr;
+ 
+   for ( ptr = buffer; *ptr; ptr++ )
+     if ( *ptr == '\r' )
+     {
+       putc(*ptr, file);
+ 
+       if ( *(ptr + 1) == '\n' )
+         putc(*++ptr, file);
+     }
+     else if ( *ptr == '\n' )
+     {
+       putc('\r', file);
+       putc(*ptr, file);
+     }
+     else
+       putc(*ptr, file);
+ }
+ #endif
+ 
  void
  apply_hunk(where)
  LINENUM where;
***************
*** 649,656 ****
  	    last_frozen_line++;
  	    old++;
  	}
! 	else if (new > pat_end)
  	    break;
  	else if (pch_char(new) == '+') {
  	    copy_till(where + old - 1);
  	    if (R_do_defines) {
--- 730,738 ----
  	    last_frozen_line++;
  	    old++;
  	}
! 	else if (new > pat_end) {
  	    break;
+ 	}
  	else if (pch_char(new) == '+') {
  	    copy_till(where + old - 1);
  	    if (R_do_defines) {
***************
*** 666,714 ****
  	    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);
--- 748,794 ----
  	    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);
! 	}
! 	else 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++;
  	    }
  	}
+ 	else {
+ 	    assert(pch_char(new) == ' ');
+ 	    old++;
+ 	    new++;
+ 	    if (R_do_defines && def_state != OUTSIDE) {
+ 		fputs(end_defined, ofp);
+ 		def_state = OUTSIDE;
+ 	    }
+ 	}
      }
      if (new <= pat_end && pch_char(new) == '+') {
  	copy_till(where + old - 1);
***************
*** 738,744 ****
  init_output(name)
  char *name;
  {
!     ofp = fopen(name, "w");
      if (ofp == Nullfp)
  	fatal2("patch: can't create %s.\n", name);
  }
--- 818,824 ----
  init_output(name)
  char *name;
  {
!     ofp = fopen(name, "wb");
      if (ofp == Nullfp)
  	fatal2("patch: can't create %s.\n", name);
  }
***************
*** 817,826 ****
--- 897,925 ----
  			 pch_line_len(pline) ))
  		return FALSE;
  	}
+ #ifdef MSDOS
+ 	else
+         {
+           char *s1, *s2;
+           int len;
+ 
+           s1 = ifetch(iline, (offset >= 0));
+           s2 = pfetch(pline);
+           len = pch_line_len(pline);
+ 
+           /* special CR/LF case */
+           if ( s1[len - 1] == '\r' && s1[len] == '\n' && s2[len - 1] == '\n' )
+             len--;
+ 
+           if (strnNE(s1, s2, len))
+ 	    return FALSE;
+         }
+ #else
  	else if (strnNE(ifetch(iline, (offset >= 0)),
  		   pfetch(pline),
  		   pch_line_len(pline) ))
  	    return FALSE;
+ #endif
      }
      return TRUE;
  }
diff -c old/patch.cs new/patch.cs
*** old/patch.cs	Sat Mar 10 20:04:48 1990
--- new/patch.cs	Thu Nov 15 22:45:56 1990
***************
*** 1,4 ****
! (-W1 -Oxn -DCANVARARG PATCH.C PCH.C INP.C VERSION.C)
  (-W1 -Od -DCANVARARG UTIL.C)
  PATCH.DEF
  PATCH.EXE
--- 1,4 ----
! (-W1 -DCANVARARG PATCH.C PCH.C INP.C VERSION.C ISVALID.C)
  (-W1 -Od -DCANVARARG UTIL.C)
  PATCH.DEF
  PATCH.EXE
diff -c old/patch.def new/patch.def
*** old/patch.def	Wed Dec 27 14:03:26 1989
--- new/patch.def	Fri Jan 18 18:19:54 1991
***************
*** 1,2 ****
! NAME PATCH WINDOWCOMPAT
! DESCRIPTION 'Patches original files with diffs - for MS-DOS and OS/2'
--- 1,2 ----
! NAME PATCH WINDOWCOMPAT NEWFILES
! DESCRIPTION 'Patch 2.0 PL12u - for MS-DOS and OS/2'
Binary files old/patch.exe and new/patch.exe differ
diff -c old/patch.man new/patch.man
*** old/patch.man	Sat Mar 10 20:25:48 1990
--- new/patch.man	Fri Sep 07 21:14:00 1990
***************
*** 1,7 ****
-                                                          PATCH(1)
- 
- 
- 
  NAME
       patch - a program for applying a diff file to an original
  
--- 1,3 ----
***************
*** 13,19 ****
       patch <patchfile
  
  DESCRIPTION
!      Patch will take a patch file containing any of the three
       forms of difference listing produced by the diff program and
       apply those differences to an original file, producing a
       patched version.  By default, the patched version is put in
--- 9,15 ----
       patch <patchfile
  
  DESCRIPTION
!      Patch will take a patch file containing any of the four
       forms of difference listing produced by the diff program and
       apply those differences to an original file, producing a
       patched version.  By default, the patched version is put in
***************
*** 26,34 ****
  
       Upon startup, patch will attempt to determine the type of
       the diff listing, unless over-ruled by a -c, -e, or -n
!      switch.  Context diffs and normal diffs are applied by the
!      patch program itself, while ed diffs are simply fed to the
!      ed editor via a pipe.
  
       Patch will try to skip any leading garbage, apply the diff,
       and then skip any trailing garbage.  Thus you could feed an
--- 22,30 ----
  
       Upon startup, patch will attempt to determine the type of
       the diff listing, unless over-ruled by a -c, -e, or -n
!      switch.  Context diffs (old-style, new-style, and unified) and
!      normal diffs are applied by the patch program itself, while ed
!      diffs are simply fed to the ed editor via a pipe.
  
       Patch will try to skip any leading garbage, apply the diff,
       and then skip any trailing garbage.  Thus you could feed an
***************
*** 233,238 ****
--- 229,237 ----
                 patch -S + -S + <patchfile
  
            will ignore the first and second of three patches.
+ 
+      -u   forces patch to interpret the patch file as a unified
+           context diff (a unidiff).
  
       -v   causes patch to print out it's revision header and
            patch level.
Only in old: patches.dos
Only in new: patches.os2
diff -c old/pch.c new/pch.c
*** old/pch.c	Wed Dec 27 14:03:26 1989
--- new/pch.c	Mon Feb 18 19:46:32 1991
***************
*** 1,6 ****
--- 1,9 ----
  /* $Header: pch.c,v 2.0.1.7 88/06/03 15:13:28 lwall Locked $
   *
   * $Log:	pch.c,v $
+  * Revision 2.0.2.0  90/05/01  22:17:51  davison
+  * patch12u: unidiff support added
+  *
   * Revision 2.0.1.7  88/06/03  15:13:28  lwall
   * patch10: Can now find patches in shar scripts.
   * patch10: Hunks that swapped and then swapped back could core dump.
***************
*** 34,39 ****
--- 37,43 ----
  #include "util.h"
  #include "INTERN.h"
  #include "pch.h"
+ #include "version.h"
  
  /* Patch (diff listing) abstract type. */
  
***************
*** 87,93 ****
            exit(1);
          }
  
! 	pfp = fopen(TMPPATNAME, "wb");
  	if (pfp == Nullfp)
  	    fatal2("patch: can't create %s.\n", TMPPATNAME);
  	while (fgets(buf, sizeof buf, stdin) != Nullch)
--- 91,97 ----
            exit(1);
          }
  
! 	pfp = fopen(TMPPATNAME, "w");
  	if (pfp == Nullfp)
  	    fatal2("patch: can't create %s.\n", TMPPATNAME);
  	while (fgets(buf, sizeof buf, stdin) != Nullch)
***************
*** 169,174 ****
--- 173,179 ----
      if (verbose)
  	say3("  %sooks like %s to me...\n",
  	    (p_base == 0L ? "L" : "The next patch l"),
+ 	    diff_type == UNI_DIFF ? "a unidiff" :
  	    diff_type == CONTEXT_DIFF ? "a context diff" :
  	    diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
  	    diff_type == NORMAL_DIFF ? "a normal diff" :
***************
*** 272,277 ****
--- 277,284 ----
  	    oldtmp = savestr(s+4);
  	else if (strnEQ(s, "--- ", 4))
  	    newtmp = savestr(s+4);
+ 	else if (strnEQ(s, "+++ ", 4))
+ 	    oldtmp = savestr(s+4);	/* pretend it is the old name */
  	else if (strnEQ(s, "Index:", 6))
  	    indtmp = savestr(s+6);
  	else if (strnEQ(s, "Prereq:", 7)) {
***************
*** 293,298 ****
--- 300,314 ----
  	    retval = ED_DIFF;
  	    goto scan_exit;
  	}
+ 	if ((!diff_type || diff_type == UNI_DIFF) && strnEQ(s, "@@ -", 4)) {
+ 	    if (!atol(s+3))
+ 		ok_to_create_file = TRUE;
+ 	    p_indent = indent;
+ 	    p_start = this_line;
+ 	    p_sline = p_input_line;
+ 	    retval = UNI_DIFF;
+ 	    goto scan_exit;
+ 	}
  	stars_this_line = strnEQ(s, "********", 8);
  	if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line &&
  		 strnEQ(s, "*** ", 4)) {
***************
*** 414,419 ****
--- 430,443 ----
      p_input_line = file_line - 1;
  }
  
+ /* Make this a function for better debugging.  */
+ static void
+ malformed ()
+ {
+     fatal3("Malformed patch at line %ld: %s", p_input_line, buf);
+ 		/* about as informative as "Syntax error" in C */
+ }
+ 
  /* True if there is more of the current diff listing to process. */
  
  bool
***************
*** 508,514 ****
  		}
  		for (s=buf; *s && !isdigit(*s); s++) ;
  		if (!*s)
! 		    goto malformed;
  		if (strnEQ(s,"0,0",3))
  		    strcpy(s,s+2);
  		p_first = (LINENUM) atol(s);
--- 532,538 ----
  		}
  		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);
***************
*** 516,522 ****
  		if (*s == ',') {
  		    for (; *s && !isdigit(*s); s++) ;
  		    if (!*s)
! 			goto malformed;
  		    p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1;
  		}
  		else if (p_first)
--- 540,546 ----
  		if (*s == ',') {
  		    for (; *s && !isdigit(*s); s++) ;
  		    if (!*s)
! 			malformed();
  		    p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1;
  		}
  		else if (p_first)
***************
*** 574,586 ****
  		    p_char[p_end] = '=';
  		    for (s=buf; *s && !isdigit(*s); s++) ;
  		    if (!*s)
! 			goto malformed;
  		    p_newfirst = (LINENUM) atol(s);
  		    while (isdigit(*s)) s++;
  		    if (*s == ',') {
  			for (; *s && !isdigit(*s); s++) ;
  			if (!*s)
! 			    goto malformed;
  			p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1;
  		    }
  		    else if (p_newfirst)
--- 598,610 ----
  		    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)
***************
*** 660,666 ****
  		    repl_missing = TRUE;
  		    goto hunk_done;
  		}
! 		goto malformed;
  	    }
  	    /* set up p_len for strncmp() so we don't have to */
  	    /* assume null termination */
--- 684,690 ----
  		    repl_missing = TRUE;
  		    goto hunk_done;
  		}
! 		malformed();
  	    }
  	    /* set up p_len for strncmp() so we don't have to */
  	    /* assume null termination */
***************
*** 727,732 ****
--- 751,900 ----
  	    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_first && !p_ptrn_lines)
+ 	    p_first = 1;
+ 	p_max = p_ptrn_lines + p_repl_lines + 1;
+ 	while (p_max >= hunkmax)
+ 	    grow_hunkmax();
+ 	p_max = 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]);
+ 		    p_end = fillsrc-1;
+ 		    malformed ();
+ 		}
+ 		context++;
+ 		p_char[fillsrc] = ch;
+ 		p_line[fillsrc] = s;
+ 		p_len[fillsrc++] = strlen(s);
+ 		s = savestr(s);
+ 		if (out_of_mem) {
+ 		    while (--filldst > p_ptrn_lines)
+ 			free(p_line[filldst]);
+ 		    p_end = fillsrc-1;
+ 		    return FALSE;
+ 		}
+ 		/* FALL THROUGH */
+ 	    case '+':
+ 		if (filldst > p_end) {
+ 		    free(s);
+ 		    while (--filldst > p_ptrn_lines)
+ 			free(p_line[filldst]);
+ 		    p_end = fillsrc-1;
+ 		    malformed ();
+ 		}
+ 		p_char[filldst] = ch;
+ 		p_line[filldst] = s;
+ 		p_len[filldst++] = strlen(s);
+ 		break;
+ 	    default:
+ 		p_end = filldst;
+ 		malformed ();
+ 	    }
+ 	    if (ch != ' ' && context > 0) {
+ 		if (context < p_context)
+ 		    p_context = context;
+ 		context = -1000;
+ 	    }
+ 	}/* while */
+     }
      else {				/* normal diff--fake it up */
  	char hunk_type;
  	Reg3 int i;
***************
*** 844,854 ****
      if (p_end+1 < hunkmax)	/* paranoia reigns supreme... */
  	p_char[p_end+1] = '^';  /* add a stopper for apply_hunk */
      return TRUE;
- 
- malformed:
-     fatal3("Malformed patch at line %ld: %s", p_input_line, buf);
- 		/* about as informative as "Syntax error" in C */
-     return FALSE;	/* for lint */
  }
  
  /* Input a line from the patch file, worrying about indentation. */
--- 1012,1017 ----
Only in old: readme
diff -c old/util.c new/util.c
*** old/util.c	Sat Mar 24 20:02:38 1990
--- new/util.c	Mon Feb 18 19:37:12 1991
***************
*** 6,11 ****
--- 6,12 ----
  /* Rename a file, copying it if necessary. */
  
  char *strchr();
+ char *strrchr();
  
  int
  move_file(from,to)
***************
*** 39,48 ****
      } else {
          Strcpy(bakname, to);
  #ifdef MSDOS
!         if ((s=strchr(bakname,'.'))!=NULL)
!           *s=0;
  #endif
          Strcat(bakname, origext?origext:ORIGEXT);
      }
  
      if (stat(to, &filestat) >= 0) {	/* output file exists */
--- 40,59 ----
      } else {
          Strcpy(bakname, to);
  #ifdef MSDOS
!         s = strchr(bakname, 0);
  #endif
          Strcat(bakname, origext?origext:ORIGEXT);
+ #ifdef MSDOS
+         if ( !IsFileNameValid(bakname) )
+         {
+           *s=0;
+ 
+           if ((s=strrchr(bakname,'.'))!=NULL)
+             *s=0;
+ 
+           strcat(bakname, ".org");
+         }
+ #endif
      }
  
      if (stat(to, &filestat) >= 0) {	/* output file exists */
***************
*** 460,487 ****
  
  
  #ifdef MSDOS
- 
- char *getenv();
- 
- Mktemp(char *file)
- {
-   char fname[32], *tmp;
- 
-   tmp = getenv("TMP");
- 
-   if ( tmp != NULL )
-   {
-     strcpy(fname, file);
-     strcpy(file, tmp);
- 
-     if ( file[strlen(file) - 1] != '\\' )
-       strcat(file, "\\");
- 
-     strcat(file, fname);
-   }
- 
-   mktemp(file);
- }
  
  /* only one pipe can be open at a time */
  
--- 471,476 ----
diff -c old/version.c new/version.c
*** old/version.c	Wed Dec 27 14:03:26 1989
--- new/version.c	Fri Sep 07 21:03:48 1990
***************
*** 23,28 ****
  #ifdef lint
      rcsid[0] = rcsid[0];
  #else
!     fatal3("\n%s\nPatch level: %d (DOS & OS/2)\n", rcsid, PATCHLEVEL);
  #endif
  }
--- 23,28 ----
  #ifdef lint
      rcsid[0] = rcsid[0];
  #else
!     fatal3("\n%s\nPatch level: %d, with unidiff support, for DOS and OS/2\n", rcsid, PATCHLEVEL);
  #endif
  }
