2013-05-09  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* src/system.h [DJGPP]: New macro CANONICALIZE_PATH defined.
	For all other systems this is a no-ops.
	New macros HAVE_LFN_SUPPORT and STRIP_FULL_PATH_AND_EXTENSION
	defined.  For all other systems these are no-ops.

	* src/sdiff.c (main): Use CANONICALIZE_PATH to canonicalize
	the passed file names.
	Use STRIP_EXTENSION to strip path and extension from argv[0].
	(temporary_file) [HAVE_LFN_SUPPORT]: Use HAVE_LFN_SUPPORT to
	determinate at run time the temp file pattern to be used.

	* src/diff3.c (main): Use CANONICALIZE_PATH to canonicalize
	the passed file names.
	Use STRIP_EXTENSION to strip path and extension from argv[0].

	* src/diff.c (main): Use CANONICALIZE_PATH to canonicalize
	the passed file names.
	Use STRIP_EXTENSION to strip path and extension from argv[0].
	Use SET_BINARY instead of set_binary_mode to change file mode
	to O_BINARY.

	* src/cmp.c (main): Use CANONICALIZE_PATH to canonicalize the
	passed file names.
	Use STRIP_EXTENSION to strip path and extension from argv[0].
	Use SET_BINARY instead of set_binary_mode to change file mode
	to O_BINARY.

	* lib/tempname.c: New macro HAVE_DIFFERENT_TMPDIR.  Value depends
	on if the OS is posix or not.
	(direxists): Use ISSLASH to check for the OS dependent directory
	separator character.  Use HAVE_DIFFERENT_TMPDIR to check for TMP
	and TEMP too, if none of them are defined or do not point to an
	existing directory default to the current directory.

	* lib/progname.c [MSDOS]: Define new macro GET_LAST_SLASH to find
	the last directory separator character.  On DOS-like systems these
	are slash, backslash or colon.  For POSIX this is simple a slash.
	(set_program_name): Use GET_LAST_SLASH to check for slash and/or
	backslash in the path.

	* lib/open.c [__DJGPP__]: Include "dosname.h" for ISSLASH definition.
	(open): Use ISSLASH to check for slash and/or backslash as directory
	separator.





diff -aprNU5 diffutils-3.3.orig/lib/open.c diffutils-3.3/lib/open.c
--- diffutils-3.3.orig/lib/open.c	2013-03-22 04:20:48 +0000
+++ diffutils-3.3/lib/open.c	2013-05-11 18:25:08 +0000
@@ -31,10 +31,14 @@ static int
 orig_open (const char *filename, int flags, mode_t mode)
 {
   return open (filename, flags, mode);
 }
 
+#ifndef ISSLASH
+# include "dosname.h"
+#endif
+
 /* Specification.  */
 /* Write "fcntl.h" here, not <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates
    this include because of the preliminary #include <fcntl.h> above.  */
 #include "fcntl.h"
 
@@ -105,11 +109,11 @@ open (const char *filename, int flags, .
        - if O_WRONLY or O_RDWR is specified, open() must fail because the
          file does not contain a '.' directory.  */
   if (flags & (O_CREAT | O_WRONLY | O_RDWR))
     {
       size_t len = strlen (filename);
-      if (len > 0 && filename[len - 1] == '/')
+      if (len > 0 && ISSLASH (filename[len - 1]))
         {
           errno = EISDIR;
           return -1;
         }
     }
@@ -156,11 +160,11 @@ open (const char *filename, int flags, .
      with ENOTDIR.  */
   if (fd >= 0)
     {
       /* We know len is positive, since open did not fail with ENOENT.  */
       size_t len = strlen (filename);
-      if (filename[len - 1] == '/')
+      if (ISSLASH (filename[len - 1]))
         {
           struct stat statbuf;
 
           if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
             {
diff -aprNU5 diffutils-3.3.orig/lib/progname.c diffutils-3.3/lib/progname.c
--- diffutils-3.3.orig/lib/progname.c	2013-03-22 04:20:48 +0000
+++ diffutils-3.3/lib/progname.c	2013-05-11 18:25:08 +0000
@@ -25,10 +25,33 @@
 #include <errno.h> /* get program_invocation_name declaration */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+/* MS-DOS and similar non-Posix systems have some peculiarities:
+    - they use both `/' and `\\' as directory separator in file names;
+    - they can have a drive letter X: prepended to a file name;
+   These are all parameterized here.  */
+
+#ifdef MSDOS
+# include <libc/unconst.h>
+# undef  IS_SLASH
+# define IS_SLASH(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# define GET_LAST_SLASH(filename)                  \
+  ({                                               \
+      char *_slash = unconst((filename), char *);  \
+      while (*_slash++)                            \
+        ;                                          \
+      while ((--_slash - (filename)))              \
+        if (IS_SLASH(*_slash))                     \
+          break;                                   \
+      _slash;                                      \
+  })
+#else
+# define GET_LAST_SLASH(filename)  (strrchr((filename), '/'))
+#endif
+
 
 /* String containing name the program is called with.
    To be initialized by main().  */
 const char *program_name = NULL;
 
@@ -54,13 +77,21 @@ set_program_name (const char *argv0)
       fputs ("A NULL argv[0] was passed through an exec system call.\n",
              stderr);
       abort ();
     }
 
-  slash = strrchr (argv0, '/');
+  slash = GET_LAST_SLASH (argv0);
   base = (slash != NULL ? slash + 1 : argv0);
-  if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
+  if (base - argv0 >= 7 && (strncmp (base - 7, "/.libs/", 7) == 0
+#ifdef MSDOS
+     || strncmp (base - 7, "\\.libs/", 7) == 0
+     || strncmp (base - 7, "\\.libs\\", 7) == 0
+     || strncmp (base - 7, "/_libs/", 7) == 0
+     || strncmp (base - 7, "\\_libs/", 7) == 0
+     || strncmp (base - 7, "\\_libs\\", 7) == 0
+#endif
+     ))
     {
       argv0 = base;
       if (strncmp (base, "lt-", 3) == 0)
         {
           argv0 = base + 3;
diff -aprNU5 diffutils-3.3.orig/lib/tempname.c diffutils-3.3/lib/tempname.c
--- diffutils-3.3.orig/lib/tempname.c	2013-03-22 04:20:48 +0000
+++ diffutils-3.3/lib/tempname.c	2013-05-11 18:25:10 +0000
@@ -28,10 +28,16 @@
 #include <errno.h>
 #ifndef __set_errno
 # define __set_errno(Val) errno = (Val)
 #endif
 
+#ifdef MSDOS
+# define HAVE_DIFFERENT_TMPDIR  1
+#else
+# define HAVE_DIFFERENT_TMPDIR  0
+#endif
+
 #include <stdio.h>
 #ifndef P_tmpdir
 # define P_tmpdir "/tmp"
 #endif
 #ifndef TMP_MAX
@@ -136,30 +142,41 @@ __path_search (char *tmpl, size_t tmpl_l
   if (try_tmpdir)
     {
       d = __secure_getenv ("TMPDIR");
       if (d != NULL && direxists (d))
         dir = d;
+#if HAVE_DIFFERENT_TMPDIR
+      else if ((d = __secure_getenv ("TMP")) && direxists (d))
+	dir = d;
+      else if ((d = __secure_getenv ("TEMP")) && direxists (d))
+	dir = d;
+#endif
       else if (dir != NULL && direxists (dir))
         /* nothing */ ;
       else
         dir = NULL;
     }
   if (dir == NULL)
     {
       if (direxists (P_tmpdir))
         dir = P_tmpdir;
+#if !HAVE_DIFFERENT_TMPDIR
       else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
         dir = "/tmp";
+#else
+      else if (strcmp (P_tmpdir, ".") != 0 && direxists ("."))
+	dir = "./";
+#endif
       else
         {
           __set_errno (ENOENT);
           return -1;
         }
     }
 
   dlen = strlen (dir);
-  while (dlen > 1 && dir[dlen - 1] == '/')
+  while (dlen > 1 && ISSLASH (dir[dlen - 1]))
     dlen--;                     /* remove trailing slashes */
 
   /* check we have room for "${dir}/${pfx}XXXXXX\0" */
   if (tmpl_len < dlen + 1 + plen + 6 + 1)
     {
diff -aprNU5 diffutils-3.3.orig/src/cmp.c diffutils-3.3/src/cmp.c
--- diffutils-3.3.orig/src/cmp.c	2013-02-02 04:39:04 +0000
+++ diffutils-3.3/src/cmp.c	2013-05-11 18:25:10 +0000
@@ -207,10 +207,11 @@ main (int argc, char **argv)
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (0);
+  STRIP_EXTENSION(argv[0]);
 
   /* Parse command line options.  */
 
   while ((c = getopt_long (argc, argv, "bci:ln:sv", long_options, 0))
 	 != -1)
@@ -265,10 +266,12 @@ main (int argc, char **argv)
   if (optind == argc)
     try_help ("missing operand after '%s'", argv[argc - 1]);
 
   file[0] = argv[optind++];
   file[1] = optind < argc ? argv[optind++] : "-";
+  CANONICALIZE_PATH(file[0]);
+  CANONICALIZE_PATH(file[1]);
 
   for (f = 0; f < 2 && optind < argc; f++)
     {
       char *arg = argv[optind++];
       specify_ignore_initial (f, &arg, 0);
diff -aprNU5 diffutils-3.3.orig/src/diff.c diffutils-3.3/src/diff.c
--- diffutils-3.3.orig/src/diff.c	2013-02-02 04:39:04 +0000
+++ diffutils-3.3/src/diff.c	2013-05-11 18:25:10 +0000
@@ -278,10 +278,11 @@ main (int argc, char **argv)
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (0);
+  STRIP_EXTENSION(argv[0]);
   function_regexp_list.buf = &function_regexp;
   ignore_regexp_list.buf = &ignore_regexp;
   re_set_syntax (RE_SYNTAX_GREP | RE_NO_POSIX_BACKTRACKING);
   excluded = new_exclude ();
 
@@ -733,21 +734,21 @@ main (int argc, char **argv)
       if (to_file)
 	fatal ("--from-file and --to-file both specified");
       else
 	for (; optind < argc; optind++)
 	  {
-	    int status = compare_files (NULL, from_file, argv[optind]);
+	    int status = compare_files (NULL, from_file, CANONICALIZE_PATH(argv[optind]));
 	    if (exit_status < status)
 	      exit_status = status;
 	  }
     }
   else
     {
       if (to_file)
 	for (; optind < argc; optind++)
 	  {
-	    int status = compare_files (NULL, argv[optind], to_file);
+	    int status = compare_files (NULL, CANONICALIZE_PATH(argv[optind]), to_file);
 	    if (exit_status < status)
 	      exit_status = status;
 	  }
       else
 	{
@@ -757,10 +758,12 @@ main (int argc, char **argv)
 		try_help ("missing operand after '%s'", argv[argc - 1]);
 	      else
 		try_help ("extra operand '%s'", argv[optind + 2]);
 	    }
 
+	  CANONICALIZE_PATH(argv[optind]);
+	  CANONICALIZE_PATH(argv[optind + 1]);
 	  exit_status = compare_files (NULL, argv[optind], argv[optind + 1]);
 	}
     }
 
   /* Print any messages that were saved up for last.  */
diff -aprNU5 diffutils-3.3.orig/src/sdiff.c diffutils-3.3/src/sdiff.c
--- diffutils-3.3.orig/src/sdiff.c	2013-02-02 04:39:04 +0000
+++ diffutils-3.3/src/sdiff.c	2013-05-11 18:25:10 +0000
@@ -453,10 +453,11 @@ main (int argc, char *argv[])
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (cleanup);
+  STRIP_EXTENSION(argv[0]);
 
   prog = getenv ("EDITOR");
   if (prog)
     editor_program = prog;
 
@@ -586,12 +587,12 @@ main (int argc, char *argv[])
       FILE *left, *right, *out, *diffout;
       bool interact_ok;
       struct line_filter lfilt;
       struct line_filter rfilt;
       struct line_filter diff_filt;
-      bool leftdir = diraccess (argv[optind]);
-      bool rightdir = diraccess (argv[optind + 1]);
+      bool leftdir = diraccess (CANONICALIZE_PATH(argv[optind]));
+      bool rightdir = diraccess (CANONICALIZE_PATH(argv[optind + 1]));
 
       if (leftdir & rightdir)
 	fatal ("both files to be compared are directories");
 
       lname = expand_name (argv[optind], leftdir, argv[optind + 1]);
diff -aprNU5 diffutils-3.3.orig/src/system.h diffutils-3.3/src/system.h
--- diffutils-3.3.orig/src/system.h	2013-02-02 04:39:04 +0000
+++ diffutils-3.3/src/system.h	2013-05-11 18:25:10 +0000
@@ -203,5 +203,37 @@ verify (sizeof (lin) <= sizeof (long int
     && (s)->st_mtime == (t)->st_mtime \
     && (s)->st_ctime == (t)->st_ctime)
 #endif
 
 #define STREQ(a, b) (strcmp (a, b) == 0)
+
+#ifdef __DJGPP__
+# include <libc/unconst.h>
+# define STRIP_EXTENSION(file_name)                  \
+  ({                                                 \
+      char *_begin, *_end;                           \
+      _begin = _end = unconst((file_name), char *);  \
+      while (*_end++)                                \
+        ;                                            \
+      while ((_end - _begin) && (*--_end != '.'))    \
+        ;                                            \
+      if (*_end == '.')                              \
+        *_end = '\0';                                \
+      (file_name);                                   \
+  })
+# define CANONICALIZE_PATH(path)                     \
+  ({                                                 \
+      if ((path))                                    \
+      {                                              \
+        char *_p = unconst((path), char *);          \
+        for (; *_p; _p++)                            \
+          if (*_p == '\\')                           \
+            *_p = '/';                               \
+      }                                              \
+      (path);                                        \
+  })
+# define HAVE_LFN_SUPPORT(name)      (pathconf ((name), _PC_NAME_MAX) > 12)
+#else
+# define STRIP_EXTENSION(file_name)
+# define CANONICALIZE_PATH(path)     (path)
+# define HAVE_LFN_SUPPORT(name)      (true)
+#endif
