]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygpath.cc (usage): Change usage output slightly.
authorCorinna Vinschen <corinna@vinschen.de>
Wed, 22 May 2002 10:05:41 +0000 (10:05 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Wed, 22 May 2002 10:05:41 +0000 (10:05 +0000)
* cygpath.cc (main): Add option l to support conversion to
Windows long file names.  Refactured code for capital options.
Support of options from file for capital options.
(dowin): New function.  Refactured from main.
(doit): Call long path conversion.
(get_long_name): New function.
(get_long_paths): New function.
(get_long_path_name_w32impl): New function.  Reimplementation
of Windows API function GetLongPathName (only 98/Me/2000/XP or
higher).
(get_short_name): Call GetShortPathName only once.
(get_short_paths): Fix calculating buffer size.
* utils.sgml: Update cygpath section for l option.

winsup/utils/ChangeLog
winsup/utils/cygpath.cc
winsup/utils/utils.sgml

index 46aed29a2a24a8c7030d66034619980356aa88a4..0fb9441d51e9d721f5ee60ef7c441b61c5698a81 100644 (file)
@@ -1,3 +1,23 @@
+2002-05-22  Corinna Vinschen  <corinna@vinschen.de>
+
+       * cygpath.cc (usage): Change usage output slightly.
+
+2002-05-20  Joerg Schaible <joerg.schaible@gmx.de>
+
+       * cygpath.cc (main): Add option l to support conversion to   
+       Windows long file names.  Refactured code for capital options.
+       Support of options from file for capital options.
+       (dowin): New function.  Refactured from main.
+       (doit): Call long path conversion.
+       (get_long_name): New function.
+       (get_long_paths): New function.
+       (get_long_path_name_w32impl): New function.  Reimplementation
+       of Windows API function GetLongPathName (only 98/Me/2000/XP or  
+       higher).
+       (get_short_name): Call GetShortPathName only once.
+       (get_short_paths): Fix calculating buffer size.
+       * utils.sgml: Update cygpath section for l option.
+
 2002-05-18  Christopher Faylor  <cgf@redhat.com>
 
        * strace.cc (add_child): Use calloc since new requires working
index d11eb2e48c6e646b350e939445a5f52ddc3f49ab..6a9c7acec93c450724cad5383e0c65ddbeed9ec8 100644 (file)
@@ -27,7 +27,8 @@ static char *prog_name;
 static char *file_arg;
 static char *close_arg;
 static int path_flag, unix_flag, windows_flag, absolute_flag;
-static int shortname_flag, ignore_flag, allusers_flag, output_flag;
+static int shortname_flag, longname_flag;
+static int ignore_flag, allusers_flag, output_flag;
 
 static struct option long_options[] = {
   {(char *) "help", no_argument, NULL, 'h'},
@@ -40,6 +41,7 @@ static struct option long_options[] = {
   {(char *) "version", no_argument, NULL, 'v'},
   {(char *) "windows", no_argument, NULL, 'w'},
   {(char *) "short-name", no_argument, NULL, 's'},
+  {(char *) "long-name", no_argument, NULL, 'l'},
   {(char *) "windir", no_argument, NULL, 'W'},
   {(char *) "sysdir", no_argument, NULL, 'S'},
   {(char *) "ignore", no_argument, NULL, 'i'},
@@ -55,22 +57,26 @@ usage (FILE * stream, int status)
 {
   if (!ignore_flag || !status)
     fprintf (stream, "\
-Usage: %s [-p|--path] (-u|--unix)|(-w|--windows [-s|--short-name]) filename\n\
+Usage: %s (-u|--unix)|(-w|--windows) [options] filename\n\n\
+  -u|--unix            print Unix form of filename\n\
+  -w|--windows         print Windows form of filename\n\n\
+Other options:\n\
   -a|--absolute                output absolute path\n\
   -c|--close handle    close handle (for use in captured process)\n\
   -f|--file file       read file for input path information\n\
   -i|--ignore          ignore missing argument\n\
+  -l|--long-name       print Windows long form of filename (with -w only)\n\
   -p|--path            filename argument is a path\n\
-  -s|--short-name      print Windows short form of filename\n\
-  -u|--unix            print Unix form of filename\n\
-  -v|--version         output version information and exit\n\
-  -w|--windows         print Windows form of filename\n\
+  -s|--short-name      print Windows short form of filename (with -w only)\n\
   -A|--allusers                use `All Users' instead of current user for -D, -P\n\
   -D|--desktop         output `Desktop' directory and exit\n\
   -H|--homeroot                output `Profiles' directory (home root) and exit\n\
   -P|--smprograms      output Start Menu `Programs' directory and exit\n\
   -S|--sysdir          output system directory and exit\n\
-  -W|--windir          output `Windows' directory and exit\n", prog_name);
+  -W|--windir          output `Windows' directory and exit\n\n\
+Informative output:\n\
+  -h|--help             print this help, then exit\n\
+  -v|--version         output version information and exit\n", prog_name);
   exit (ignore_flag ? 0 : status);
 }
 
@@ -123,6 +129,7 @@ get_short_paths (char *path)
        break;
       *sptr = ';';
       ++ptr, ++sptr;
+      acc -= len + 1;
     }
   return sbuf;
 }
@@ -130,8 +137,8 @@ get_short_paths (char *path)
 static char *
 get_short_name (const char *filename)
 {
-  char *sbuf;
-  DWORD len = GetShortPathName (filename, NULL, 0);
+  char *sbuf, buf[MAX_PATH];
+  DWORD len = GetShortPathName (filename, buf, MAX_PATH);
   if (len == 0 && GetLastError () == ERROR_INVALID_PARAMETER)
     {
       fprintf (stderr, "%s: cannot create short name of %s\n", prog_name,
@@ -144,14 +151,225 @@ get_short_name (const char *filename)
       fprintf (stderr, "%s: out of memory\n", prog_name);
       exit (1);
     }
-  len = GetShortPathName (filename, sbuf, len);
+  return strcpy (sbuf, buf);
+}
+
+static DWORD
+get_long_path_name_w32impl (LPCSTR src, LPSTR sbuf, DWORD)
+{
+  char buf1[MAX_PATH], buf2[MAX_PATH], *ptr;
+  const char *pelem, *next;
+  WIN32_FIND_DATA w32_fd;
+  int len;
+  
+  strcpy (buf1, src);
+  *buf2 = 0;
+  pelem = src;
+  ptr = buf2;
+  while (pelem)
+    {
+      next = pelem;
+      if (*next == '\\')
+       {
+         strcat (ptr++, "\\");
+         pelem++;
+         if (!*pelem)
+           break;
+         continue;
+       }
+      pelem = strchr (next, '\\');
+      len = pelem ? (pelem++ - next) : strlen (next);
+      strncpy (ptr, next, len);
+      ptr[len] = 0;
+      if (next[1] != ':' && strcmp(next, ".") && strcmp(next, ".."))
+       {
+         if (FindFirstFile (buf2, &w32_fd) != INVALID_HANDLE_VALUE)
+           strcpy (ptr, w32_fd.cFileName);
+       }
+      ptr += strlen (ptr);
+      if (pelem)
+       {
+         *ptr++ = '\\';
+         *ptr = 0;
+       }
+    }
+  if (sbuf)
+    strcpy (sbuf, buf2);
+  SetLastError (0);
+  return strlen (buf2) + (sbuf ? 0 : 1);
+}
+
+static char *
+get_long_paths (char *path)
+{
+  char *sbuf;
+  char *sptr;
+  char *next;
+  char *ptr = path;
+  char *end = strrchr (path, 0);
+  DWORD acc = 0;
+  DWORD len;
+
+  HINSTANCE hinst;
+  DWORD (*GetLongPathNameAPtr) (LPCSTR, LPSTR, DWORD) = 0;
+  hinst = LoadLibrary ("kernel32");
+  if (hinst)
+    GetLongPathNameAPtr = (DWORD (*) (LPCSTR, LPSTR, DWORD))
+      GetProcAddress (hinst, "GetLongPathNameA");
+  /* subsequent calls of kernel function with NULL cause SegFault in W2K!! */
+  if (1 || !GetLongPathNameAPtr)
+    GetLongPathNameAPtr = get_long_path_name_w32impl;
+
+  while (ptr != NULL)
+    {
+      next = ptr;
+      ptr = strchr (ptr, ';');
+      if (ptr)
+       *ptr++ = 0;
+      len = (*GetLongPathNameAPtr) (next, NULL, 0);
+      if (len == 0 && GetLastError () == ERROR_INVALID_PARAMETER)
+       {
+         fprintf (stderr, "%s: cannot create long name of %s\n", prog_name,
+                  next);
+         exit (2);
+       }
+      acc += len + 1;
+    }
+  sptr = sbuf = (char *) malloc (acc + 1);
+  if (sbuf == NULL)
+    {
+      fprintf (stderr, "%s: out of memory\n", prog_name);
+      exit (1);
+    }
+  ptr = path;
+  for (;;)
+    {
+      len = (*GetLongPathNameAPtr) (ptr, sptr, acc);
+      if (len == 0 && GetLastError () == ERROR_INVALID_PARAMETER)
+       {
+         fprintf (stderr, "%s: cannot create long name of %s\n", prog_name,
+                  ptr);
+         exit (2);
+       }
+
+      ptr = strrchr (ptr, 0);
+      sptr = strrchr (sptr, 0);
+      if (ptr == end)
+       break;
+      *ptr = *sptr = ';';
+      ++ptr, ++sptr;
+      acc -= len + 1;
+    }
+  return sbuf;
+}
+
+static char *
+get_long_name (const char *filename)
+{
+  char *sbuf, buf[MAX_PATH];
+  DWORD len;
+  HINSTANCE hinst;
+  DWORD (*GetLongPathNameAPtr) (LPCSTR, LPSTR, DWORD) = 0;
+  hinst = LoadLibrary ("kernel32");
+  if (hinst)
+    GetLongPathNameAPtr = (DWORD (*) (LPCSTR, LPSTR, DWORD))
+      GetProcAddress (hinst, "GetLongPathNameA");
+  if (!GetLongPathNameAPtr)
+    GetLongPathNameAPtr = get_long_path_name_w32impl;
+  
+  len = (*GetLongPathNameAPtr) (filename, buf, MAX_PATH);
   if (len == 0 && GetLastError () == ERROR_INVALID_PARAMETER)
     {
-      fprintf (stderr, "%s: cannot create short name of %s\n", prog_name,
+      fprintf (stderr, "%s: cannot create long name of %s\n", prog_name,
               filename);
       exit (2);
     }
-  return sbuf;
+  sbuf = (char *) malloc (++len);
+  if (sbuf == NULL)
+    {
+      fprintf (stderr, "%s: out of memory\n", prog_name);
+      exit (1);
+    }
+  return strcpy (sbuf, buf);
+}
+
+static void
+dowin (char option)
+{
+  char *buf, buf1[MAX_PATH], buf2[MAX_PATH];
+  DWORD len = MAX_PATH;
+  WIN32_FIND_DATA w32_fd;
+  LPITEMIDLIST id;
+  HINSTANCE hinst;
+  BOOL (*GetProfilesDirectoryAPtr) (LPSTR, LPDWORD) = 0;
+      
+  buf = buf1;
+  switch (option)
+    {
+    case 'D':
+      SHGetSpecialFolderLocation (NULL, allusers_flag ? 
+       CSIDL_COMMON_DESKTOPDIRECTORY : CSIDL_DESKTOPDIRECTORY, &id);
+      SHGetPathFromIDList (id, buf);
+      /* This if clause is a Fix for Win95 without any "All Users" */
+      if (strlen (buf) == 0)
+       {
+         SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
+         SHGetPathFromIDList (id, buf);
+       }
+      break;
+
+    case 'P':
+      SHGetSpecialFolderLocation (NULL, allusers_flag ? 
+       CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, &id);
+      SHGetPathFromIDList (id, buf);
+      /* This if clause is a Fix for Win95 without any "All Users" */
+      if (strlen (buf) == 0)
+       {
+         SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
+         SHGetPathFromIDList (id, buf);
+       }
+      break;
+
+    case 'H':
+      hinst = LoadLibrary ("userenv");
+      if (hinst)
+       GetProfilesDirectoryAPtr = (BOOL (*) (LPSTR, LPDWORD))
+         GetProcAddress (hinst, "GetProfilesDirectoryA");
+      if (GetProfilesDirectoryAPtr)
+        (*GetProfilesDirectoryAPtr) (buf, &len);
+      else
+       {
+         GetWindowsDirectory (buf, MAX_PATH);
+         strcat (buf, "\\Profiles");
+       }
+      break;
+
+    case 'S':
+      GetSystemDirectory (buf, MAX_PATH);
+      FindFirstFile (buf, &w32_fd);
+      strcpy (strrchr (buf, '\\') + 1, w32_fd.cFileName);
+      break;
+
+    case 'W':
+      GetWindowsDirectory (buf, MAX_PATH);
+      break;
+
+    default:
+      usage (stderr, 1);
+    }
+
+  if (!windows_flag)
+    {
+      cygwin_conv_to_posix_path (buf, buf2);
+      buf = buf2;
+    }
+  else
+    {
+      if (shortname_flag)
+        buf = get_short_name (buf);
+    }
+  printf ("%s\n", buf);
+  exit (0);
 }
 
 static void
@@ -213,6 +431,8 @@ doit (char *filename)
          cygwin_posix_to_win32_path_list (filename, buf);
          if (shortname_flag)
            buf = get_short_paths (buf);
+         if (longname_flag)
+           buf = get_long_paths (buf);
        }
     }
   else
@@ -230,8 +450,13 @@ doit (char *filename)
                   prog_name, filename);
          exit (1);
        }
-      if (!unix_flag && shortname_flag)
-       buf = get_short_name (buf);
+      if (!unix_flag)
+       {
+       if (shortname_flag)
+         buf = get_short_name (buf);
+       if (longname_flag)
+         buf = get_long_name (buf);
+       }
     }
 
   puts (buf);
@@ -278,12 +503,13 @@ main (int argc, char **argv)
   unix_flag = 0;
   windows_flag = 0;
   shortname_flag = 0;
+  longname_flag = 0;
   ignore_flag = 0;
   options_from_file_flag = 0;
   allusers_flag = 0;
   output_flag = 0;
   while ((c =
-         getopt_long (argc, argv, (char *) "hac:f:opsSuvwWiDPAH",
+         getopt_long (argc, argv, (char *) "hac:f:opslSuvwWiDPAH",
                       long_options, (int *) NULL)) != EOF)
     {
       switch (c)
@@ -320,8 +546,14 @@ main (int argc, char **argv)
          windows_flag = 1;
          break;
 
+       case 'l':
+         if (unix_flag || shortname_flag)
+           usage (stderr, 1);
+         longname_flag = 1;
+         break;
+
        case 's':
-         if (unix_flag)
+         if (unix_flag || longname_flag)
            usage (stderr, 1);
          shortname_flag = 1;
          break;
@@ -360,97 +592,17 @@ main (int argc, char **argv)
 
     }
 
-  if (output_flag)
-    {
-      char *buf, buf1[MAX_PATH], buf2[MAX_PATH];
-      DWORD len = MAX_PATH;
-      WIN32_FIND_DATA w32_fd;
-      LPITEMIDLIST id;
-      HINSTANCE hinst;
-      BOOL (*GetProfilesDirectoryAPtr) (LPSTR, LPDWORD) = 0;
-      
-      buf = buf1;
-      switch (o)
-       {
-       case 'D':
-         if (!allusers_flag)
-           SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
-         else
-           SHGetSpecialFolderLocation (NULL, CSIDL_COMMON_DESKTOPDIRECTORY,
-                                       &id);
-         SHGetPathFromIDList (id, buf);
-         /* This if clause is a Fix for Win95 without any "All Users" */
-         if (strlen (buf) == 0)
-           {
-             SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
-             SHGetPathFromIDList (id, buf);
-           }
-         break;
-
-       case 'P':
-         if (!allusers_flag)
-           SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
-         else
-           SHGetSpecialFolderLocation (NULL, CSIDL_COMMON_PROGRAMS, &id);
-         SHGetPathFromIDList (id, buf);
-         /* This if clause is a Fix for Win95 without any "All Users" */
-         if (strlen (buf) == 0)
-           {
-             SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
-             SHGetPathFromIDList (id, buf);
-           }
-         break;
-
-       case 'H':
-         hinst = LoadLibrary ("userenv");
-         if (hinst)
-           GetProfilesDirectoryAPtr = (BOOL (*) (LPSTR, LPDWORD))
-             GetProcAddress (hinst, "GetProfilesDirectoryA");
-         if (GetProfilesDirectoryAPtr)
-           (*GetProfilesDirectoryAPtr) (buf, &len);
-         else
-           {
-             GetWindowsDirectory (buf, MAX_PATH);
-             strcat (buf, "\\Profiles");
-           }
-         break;
-
-       case 'S':
-         GetSystemDirectory (buf, MAX_PATH);
-         FindFirstFile (buf, &w32_fd);
-         strcpy (strrchr (buf, '\\') + 1, w32_fd.cFileName);
-         break;
-
-       case 'W':
-         GetWindowsDirectory (buf, MAX_PATH);
-         break;
-
-       default:
-         usage (stderr, 1);
-       }
-
-       if (!windows_flag)
-         {
-           cygwin_conv_to_posix_path (buf, buf2);
-           buf = buf2;
-         }
-       else
-         {
-           if (shortname_flag)
-             buf = get_short_name (buf);
-         }
-       printf ("%s\n", buf);
-       exit (0);
-    }
-
   if (options_from_file_flag && !file_arg)
     usage (stderr, 1);
 
-  if (!unix_flag && !windows_flag && !options_from_file_flag)
+  if (!output_flag && !unix_flag && !windows_flag && !options_from_file_flag)
     usage (stderr, 1);
 
   if (!file_arg)
     {
+      if (output_flag)
+       dowin (o);
+
       if (optind != argc - 1)
        usage (stderr, 1);
 
@@ -499,6 +651,11 @@ main (int argc, char **argv)
                    break;
                  case 's':
                    shortname_flag = 1;
+                   longname_flag = 0;
+                   break;
+                 case 'l':
+                   shortname_flag = 0;
+                   longname_flag = 1;
                    break;
                  case 'w':
                    unix_flag = 0;
@@ -510,14 +667,25 @@ main (int argc, char **argv)
                    break;
                  case 'p':
                    path_flag = 1;
+                   break;
+                 case 'D':
+                 case 'H':
+                 case 'P':
+                 case 'S':
+                 case 'W':
+                   output_flag = 1;
+                   o = c;
+                   break;
                  }
              if (*s)
                do
                  s++;
                while (*s && isspace (*s));
            }
-         if (*s)
+         if (*s && !output_flag)
            doit (s);
+         if (!*s && output_flag)
+           dowin (o);
        }
     }
 
index cbda63184638600f2e8b6b0d4f9fa3098ae9fbb1..53448f2b0bf3542610b887533783d23405524f49 100644 (file)
@@ -71,18 +71,22 @@ or if you know what everything is already, just leave this out.</para>
 <sect2 id="cygpath"><title>cygpath</title>
 
 <screen>
-Usage: cygpath.exe [-p|--path] (-u|--unix)|(-w|--windows [-s|--short-name]) filename
+Usage: cygpath [-p|--path] (-w|--windows) ([-s|--short-name]|[-l|--long-name]) filename
+Usage: cygpath [-p|--path] (-u|--unix) filename
+Usage: cygpath (-H|--homeroot)|(-S|--sysdir)|(-W|--windir) [-s|--short-name]
+Usage: cygpath [-A|--allusers] (-D|--desktop)|(-P|--smprograms) [-s|--short-name]
   -a|--absolute         output absolute path
   -c|--close handle     close handle (for use in captured process)
   -f|--file file        read file for input path information
   -i|--ignore           ignore missing argument
+  -l|--long-name        print Windows long form of filename
   -p|--path             filename argument is a path
   -s|--short-name       print Windows short form of filename
   -u|--unix             print Unix form of filename
   -v|--version          output version information and exit
   -w|--windows          print Windows form of filename
   -A|--allusers         use `All Users' instead of current user for -D, -P
-  -H|--homeroot                output `Profiles' directory (home root) and exit\n\
+  -H|--homeroot                output `Profiles' directory (home root) and exit
   -D|--desktop          output `Desktop' directory and exit
   -P|--smprograms       output Start Menu `Programs' directory and exit
   -S|--sysdir           output system directory and exit
@@ -102,8 +106,14 @@ indicate whether you want a conversion from Windows to UNIX (POSIX)
 format (<literal>-u</literal>) or a conversion from UNIX (POSIX) to
 Windows format (<literal>-w</literal>).  You must give exactly
 one of these.  To give neither or both is an error.  Use the
-<literal>-s</literal> option in combination with the <literal>-w
-</literal> option to convert to Windows short form.</para>
+<literal>-l</literal> or <literal>-s</literal> option in combination 
+with the <literal>-w</literal> option to convert to Windows long or 
+short form.</para>
+
+<para>Caveat: The <literal>-l</literal> option does not work if the
+<em>check_case</em> parameter of <em>CYGWIN</em> is set to <em>strict</em>,
+since Cygwin is not able to match any Windows short path in this mode.
+</para>
 
 <para>The <literal>-p</literal> option means that you want to convert
 a path-style string rather than a single filename.  For example, the
This page took 0.047421 seconds and 5 git commands to generate.