]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* libiberty/configure.ac: Add cygpath for mingw hosts.
authorMark Mitchell <mark@codesourcery.com>
Fri, 31 Mar 2006 00:32:32 +0000 (00:32 +0000)
committerMark Mitchell <mark@codesourcery.com>
Fri, 31 Mar 2006 00:32:32 +0000 (00:32 +0000)
* libiberty.configure: Rebuilt.
* libiberty/Makefile.in: Add cygpath.
* libiberty/cygpath.c: New.

libiberty/Makefile.in
libiberty/configure
libiberty/configure.ac
libiberty/cygpath.c [new file with mode: 0644]

index dcd5ebd86d1674168243f148e5e54497422e56b4..77848ad5928f19fc1125d17cd38f8f6cdaded72e 100644 (file)
@@ -129,7 +129,7 @@ COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS) -I. -I$(INCDIR) $(HDEFINES) @ac_libiber
 CFILES = alloca.c argv.c asprintf.c atexit.c                           \
        basename.c bcmp.c bcopy.c bsearch.c bzero.c                     \
        calloc.c choose-temp.c clock.c concat.c cp-demangle.c           \
-        cp-demint.c cplus-dem.c                                        \
+        cp-demint.c cplus-dem.c cygpath.c                              \
        dyn-string.c                                                    \
        fdmatch.c ffs.c fibheap.c floatformat.c fnmatch.c               \
         fopen_unlocked.c                                               \
@@ -186,7 +186,7 @@ REQUIRED_OFILES = ./regex.o ./cplus-dem.o ./cp-demangle.o ./md5.o   \
 # maint-missing" and "make check".
 CONFIGURED_OFILES = ./asprintf.o ./atexit.o                            \
        ./basename.o ./bcmp.o ./bcopy.o ./bsearch.o ./bzero.o           \
-       ./calloc.o ./clock.o ./copysign.o                               \
+       ./calloc.o ./clock.o ./copysign.o ./cygpath.o                   \
        ./_doprnt.o                                                     \
        ./ffs.o                                                         \
        ./getcwd.o ./getpagesize.o ./gettimeofday.o                     \
@@ -548,6 +548,12 @@ $(CONFIGURED_OFILES): stamp-picdir
        else true; fi
        $(COMPILE.c) $(srcdir)/cplus-dem.c $(OUTPUT_OPTION)
 
+./cygpath.o: $(srcdir)/cygpath.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
+       if [ x"$(PICFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(srcdir)/cygpath.c -o pic/$@; \
+       else true; fi
+       $(COMPILE.c) $(srcdir)/cygpath.c $(OUTPUT_OPTION)
+
 ./dyn-string.o: $(srcdir)/dyn-string.c config.h $(INCDIR)/ansidecl.h \
        $(INCDIR)/dyn-string.h $(INCDIR)/libiberty.h
        if [ x"$(PICFLAG)" != x ]; then \
index 59633d520fc05347f786ac45434307326669cb78..8a866d89f89d03706080f76e230b4c91d3c6ca31 100755 (executable)
@@ -8205,6 +8205,20 @@ case "${host}" in
 esac
 
 
+# On MinGW, add support for Cygwin paths.
+case "${host}" in
+     *-*-mingw*)
+       case $LIBOBJS in
+    "cygpath.$ac_objext"   | \
+  *" cygpath.$ac_objext"   | \
+    "cygpath.$ac_objext "* | \
+  *" cygpath.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS cygpath.$ac_objext" ;;
+esac
+
+       ;;
+esac
+
 if test x$gcc_no_link = xyes; then
   if test "x${ac_cv_func_mmap_fixed_mapped+set}" != xset; then
     ac_cv_func_mmap_fixed_mapped=no
index a57685a14ec40f2252b29af93105d81b0bbd0f1b..9c1eed9bbed1214f601f428172d12dd24aaab85e 100644 (file)
@@ -618,6 +618,13 @@ case "${host}" in
 esac
 AC_SUBST(pexecute)
 
+# On MinGW, add support for Cygwin paths.
+case "${host}" in
+     *-*-mingw*)
+       AC_LIBOBJ([cygpath])
+       ;;
+esac
+
 libiberty_AC_FUNC_STRNCMP
 
 # Install a library built with a cross compiler in $(tooldir) rather
diff --git a/libiberty/cygpath.c b/libiberty/cygpath.c
new file mode 100644 (file)
index 0000000..2e7b4c9
--- /dev/null
@@ -0,0 +1,270 @@
+/* Support Cygwin paths under MinGW.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   Written by CodeSourcery.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or modify it
+under the terms of the GNU Library General Public License as published
+by the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.  If not, write
+to the Free Software Foundation, Inc., 51 Franklin Street - Fifth
+Floor, Boston, MA 02110-1301, USA.  */
+
+#include <windows.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <io.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "libiberty.h"
+
+/* If non-zero, we have attempted to use cygpath.  CYGPATH_PEX may
+   still be NULL, if cygpath is unavailable.  */
+static int cygpath_initialized;
+
+/* If non-NULL, an instance of cygpath connected via a pipe.  */
+static struct pex_obj *cygpath_pex;
+
+/* The input to cygpath.  */
+static FILE *cygpath_in;
+
+/* The output from cygpath.  */
+static FILE *cygpath_out;
+
+/* CYG_PATH is a pointer to a Cygwin path.  This function converts the
+   Cygwin path to a Windows path, storing the result in
+   WIN32_PATH.  Returns true if the conversion was successful; false
+   otherwise.  */
+static bool
+cygpath (const char *cyg_path, char win32_path[MAX_PATH + 1])
+{
+  bool ok;
+
+  if (!cygpath_initialized) 
+    {
+      const char *argv[] = { "cygpath", "-w", "-f", "-", NULL };
+      const char *cygpath_path;
+      int err;
+
+      /* If we are unable to invoke cygpath, we do not want to try
+        again.  So, we set the initialized flag at this point; if
+        errors occur during the invocation, it will remain set.  */
+      cygpath_initialized = 1;
+      /* Check to see if the user wants cygpath support.  */
+      cygpath_path = getenv ("CYGPATH");
+      if (!cygpath_path)
+       /* The user doesn't need to support Cygwin paths.  */
+       goto error;
+      /* If the environment variable is set to a non-empty string, use
+        that string as the path to cygpath.  */ 
+      if (cygpath_path[0] != '\0')
+       argv[0] = cygpath_path;
+      /* Create the pex object.  */
+      cygpath_pex = pex_init (PEX_SEARCH | PEX_USE_PIPES, 
+                             "cygpath", NULL);
+      if (!cygpath_pex)
+       goto error;
+      /* Get the FILE we will use to write to the child.  */
+      cygpath_in = pex_write_input (cygpath_pex, /*binary=*/0);
+      if (!cygpath_in)
+       goto error;
+      /* Start the child process.  */
+      if (pex_run (cygpath_pex, PEX_SEARCH | PEX_USE_PIPES, 
+                  argv[0], (char**) argv, 
+                  NULL, NULL,
+                  &err) != NULL)
+       goto error;
+      /* Get the FILE we will use to read from the child.  */
+      cygpath_out = pex_read_output (cygpath_pex, /*binary=*/1);
+      if (!cygpath_out)
+       goto error;
+    }
+  else if (!cygpath_pex) 
+    /* We previously tried to use cygpath, but something went wrong.  */
+    return false;
+
+  /* Write CYG_PATH to the child, on a line by itself.  */
+  if (fprintf (cygpath_in, "%s\n", cyg_path) < 0)
+    goto error;
+  /* Flush the output.  (We cannot set the stream into line-buffered
+     mode with setvbuf because Windows treats _IOLBF as a synonym for
+     _IOFBF.)  */
+  fflush (cygpath_in);
+  /* Read the output.  */
+  ok = true;
+  while (1)
+    {
+      size_t pathlen;
+      if (!fgets (win32_path, MAX_PATH, cygpath_out))
+       goto error;
+      pathlen = strlen (win32_path);
+      if (pathlen == 0 && ok)
+       /* This isn't a well-formed response from cygpath.  */
+       goto error;
+      if (win32_path[pathlen - 1] == '\n')
+       {
+         win32_path[pathlen - 1] = '\0';
+         break;
+       }
+      /* We didn't reach the end of the line.  There's no point in
+        trying to use this output, since we know the length of
+        paths are limited to MAX_PATH characters, but we read the
+        entire line so that we are still in sync with
+        cygpath.  */
+      ok = false;
+    }
+
+  return ok;
+
+ error:
+
+  /* Free resources.  */
+  if (cygpath_out)
+    {
+      fclose (cygpath_out);
+      cygpath_out = NULL;
+    }
+  if (cygpath_in)
+    {
+      fclose (cygpath_in);
+      cygpath_in = NULL;
+    }
+  if (cygpath_pex)
+    {
+      pex_free (cygpath_pex);
+      cygpath_pex = NULL;
+    }
+
+  return false;
+}
+
+/* Returns the handle for the MVCRT DLL, or NULL if it is not
+   available.  */
+static HANDLE
+msvcrt_dll (void)
+{
+  static HANDLE dll = INVALID_HANDLE_VALUE;
+
+  /* After we call LoadLibrary, DLL will be either a valid handle or
+     NULL, so this check ensures that we only try to load the library
+     once.  */
+  if (dll == INVALID_HANDLE_VALUE)
+    dll = LoadLibrary ("msvcrt.dll");
+
+  return dll;
+}
+
+/* Call the underlying MSVCRT fopen with PATH and MODE, and return
+   what it returns.  */
+static FILE *
+msvcrt_fopen (const char *path, const char *mode)
+{
+  typedef FILE *(fopen_type)(const char *path, 
+                            const char *mode);
+
+  static fopen_type *f = NULL;
+
+  /* Get the address of "fopen".  */
+  if (!f) 
+    {
+      HANDLE dll = msvcrt_dll ();
+      if (!dll)
+       {
+         errno = ENOSYS;
+         return NULL;
+       }
+      f = (fopen_type *) GetProcAddress (dll, "fopen");
+      if (!f)
+       {
+         errno = ENOSYS;
+         return NULL;
+       }
+    }
+
+  /* Call fopen.  */
+  return (*f)(path, mode);
+}
+
+FILE *
+fopen (const char *path, const char *mode)
+{
+  FILE *f;
+  char win32_path[MAX_PATH + 1];
+
+  /* Assume PATH is a Windows path.  */
+  f = msvcrt_fopen (path, mode);
+  if (f || errno != ENOENT)
+    return f;
+  /* Perhaps it is a Cygwin path?  */
+  if (cygpath (path, win32_path))
+    f = msvcrt_fopen (win32_path, mode);
+  return f;
+}
+
+int 
+open (const char *path, int oflag, ...)
+{
+  int fd;
+  char win32_path[MAX_PATH + 1];
+  int pmode = 0;
+
+  if ((oflag & _O_CREAT))
+    {
+      va_list ap;
+      va_start (ap, oflag);
+      pmode = va_arg (ap, int); 
+      va_end (ap);
+    }
+
+  /* Assume PATH is a Windows path.  */
+  fd = _open (path, oflag, pmode);
+  if (fd != -1 || errno != ENOENT)
+    return fd;
+  /* Perhaps it is a Cygwin path?  */
+  if (cygpath (path, win32_path))
+    fd = _open (win32_path, oflag, pmode);
+  return fd;
+}
+
+int
+stat (const char *path, struct stat *buffer)
+{
+  int r;
+  char win32_path[MAX_PATH + 1];
+
+  /* Assume PATH is a Windows path.  */
+  r = _stat (path, (struct _stat *) buffer);
+  if (r != -1 || errno != ENOENT)
+    return r;
+  /* Perhaps it is a Cygwin path?  */
+  if (cygpath (path, win32_path))
+    r = _stat (win32_path, (struct _stat *) buffer);
+  return r;
+}
+
+int
+access (const char *path, int mode)
+{
+  int r;
+  char win32_path[MAX_PATH + 1];
+
+  /* Assume PATH is a Windows path.  */
+  r = _access (path, mode);
+  if (r != -1 || errno != ENOENT)
+    return r;
+  /* Perhaps it is a Cygwin path?  */
+  if (cygpath (path, win32_path))
+    r = _access (win32_path, mode);
+  return r;
+}