[PATCH 4/6] [WinePath]: No longer use the unix stdio functions, but the kernel32 equivalent

Eric Pouech eric.pouech at orange.fr
Fri Nov 4 15:14:17 CDT 2011


Moved also internal strings to Unicode
#28190

A+
---

 programs/winepath/winepath.c |  178 ++++++++++++++++++++++++++++++------------
 1 files changed, 127 insertions(+), 51 deletions(-)


diff --git a/programs/winepath/winepath.c b/programs/winepath/winepath.c
index 6e5f58d..8e4f310 100644
--- a/programs/winepath/winepath.c
+++ b/programs/winepath/winepath.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "wine/unicode.h"
 #include "wine/debug.h"
 
 enum {
@@ -38,38 +39,101 @@ enum {
     PRINT0        = 16,
 };
 
-static const char progname[] = "winepath";
+static const WCHAR progname[] = {'w','i','n','e','p','a','t','h',0};
+
+static int mywprintf(BOOL out, const WCHAR *format, ...)
+{
+    static char         output_bufA[65536];
+    static WCHAR        output_bufW[sizeof(output_bufA) / sizeof(WCHAR)];
+    va_list             parms;
+    DWORD               nOut;
+    int                 len;
+    BOOL                res = FALSE;
+    HANDLE              hout = GetStdHandle(out ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
+
+    va_start(parms, format);
+    len = vsnprintfW(output_bufW, sizeof(output_bufW), format, parms);
+    va_end(parms);
+    if (len < 0)
+    {
+        /* String too long */
+        return 0;
+    }
+
+    /* Try to write as unicode whenever we think it's a console */
+    if (((DWORD_PTR)hout & 3) == 3)
+    {
+        res = WriteConsoleW(hout, output_bufW, len, &nOut, NULL);
+    }
+    else
+    {
+        BOOL    usedDefaultChar = FALSE;
+        DWORD   convertedChars;
+
+        /* Convert to OEM, then output */
+        convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0, output_bufW, len,
+                                             output_bufA, sizeof(output_bufA),
+                                             "?", &usedDefaultChar);
+        res = WriteFile(hout, output_bufA, convertedChars, &nOut, FALSE);
+    }
+
+    return res ? nOut : 0;
+}
 
 /*
  * handle an option
  */
 static int option(int shortopt, const WCHAR *longopt)
 {
-    static const char helpmsg[] =
-    "Convert PATH(s) to Unix or Windows long or short paths.\n"
-    "\n"
-    "  -u, --unix    converts a Windows path to a Unix path\n"
-    "  -w, --windows converts a Unix path to a long Windows path\n"
-    "  -l, --long    converts the short Windows path of an existing file or\n"
-    "                directory to the long format\n"
-    "  -s, --short   converts the long Windows path of an existing file or\n"
-    "                directory to the short format\n"
-    "  -0            separate output with \\0 character, instead of a newline\n"
-    "  -h, --help    output this help message and exit\n"
-    "  -v, --version output version information and exit\n"
-    "\n"
-    "If more than one option is given then the input paths are output in\n"
-    "all formats specified, in the order long, short, Unix, Windows.\n"
-    "If no option is given the default is Unix format.\n";
+    static const WCHAR help_msg[] = {
+        'C','o','n','v','e','r','t',' ','P','A','T','H','(','s',')',' ','t','o',' ','U','n','i','x',' ','o','r',' ','W','i','n','d','o','w','s',' ',
+                'l','o','n','g',' ','o','r',' ','s','h','o','r','t',' ','p','a','t','h','s','.','\n',
+        '\n',
+        ' ',' ','-','u',',',' ','-','-','u','n','i','x',' ',' ',' ',' ','c','o','n','v','e','r','t','s',' ','a',' ','W','i','n','d','o','w','s',' ',
+                'p','a','t','h',' ','t','o',' ','a',' ','U','n','i','x',' ','p','a','t','h','\n',
+        ' ',' ','-','w',',',' ','-','-','w','i','n','d','o','w','s',' ','c','o','n','v','e','r','t','s',' ','a',' ','U','n','i','x',' ',
+                'p','a','t','h',' ','t','o',' ','a',' ','l','o','n','g',' ','W','i','n','d','o','w','s',' ','p','a','t','h','\n',
+        ' ',' ','-','l',',',' ','-','-','l','o','n','g',' ',' ',' ',' ','c','o','n','v','e','r','t','s',' ','t','h','e',' ',
+                's','h','o','r','t',' ','W','i','n','d','o','w','s',' ','p','a','t','h',' ','o','f',' ','a','n',' ','e','x','i','s','t','i','n','g',' ','f','i','l','e',' ','o','r','\n',
+        ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','d','i','r','e','c','t','o','r','y',' ','t','o',' ','t','h','e',' ','l','o','n','g',' ','f','o','r','m','a','t','\n',
+        ' ',' ','-','s',',',' ','-','-','s','h','o','r','t',' ',' ',' ','c','o','n','v','e','r','t','s',' ','t','h','e',' ','l','o','n','g',' ',
+                'W','i','n','d','o','w','s',' ','p','a','t','h',' ','o','f',' ','a','n',' ','e','x','i','s','t','i','n','g',' ','f','i','l','e',' ','o','r','\n',
+        ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','d','i','r','e','c','t','o','r','y',' ','t','o',' ','t','h','e',' ',
+                's','h','o','r','t',' ','f','o','r','m','a','t','\n',
+        ' ',' ','-','0',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','s','e','p','a','r','a','t','e',' ','o','u','t','p','u','t',' ',
+                'w','i','t','h',' ','\\','0',' ','c','h','a','r','a','c','t','e','r',',',' ','i','n','s','t','e','a','d',' ','o','f',' ','a',' ','n','e','w','l','i','n','e','\n',
+        ' ',' ','-','h',',',' ','-','-','h','e','l','p',' ',' ',' ',' ','o','u','t','p','u','t',' ','t','h','i','s',' ','h','e','l','p',' ',
+                'm','e','s','s','a','g','e',' ','a','n','d',' ','e','x','i','t','\n',
+        ' ',' ','-','v',',',' ','-','-','v','e','r','s','i','o','n',' ','o','u','t','p','u','t',' ','v','e','r','s','i','o','n',' ',
+                'i','n','f','o','r','m','a','t','i','o','n',' ','a','n','d',' ','e','x','i','t','\n',
+        '\n',
+        'I','f',' ','m','o','r','e',' ','t','h','a','n',' ','o','n','e',' ','o','p','t','i','o','n',' ','i','s',' ','g','i','v','e','n',' ',
+                't','h','e','n',' ','t','h','e',' ','i','n','p','u','t',' ','p','a','t','h','s',' ','a','r','e',' ','o','u','t','p','u','t',' ','i','n','\n',
+        'a','l','l',' ','f','o','r','m','a','t','s',' ','s','p','e','c','i','f','i','e','d',',',' ','i','n',' ','t','h','e',' ',
+        'o','r','d','e','r',' ','l','o','n','g',',',' ','s','h','o','r','t',',',' ','U','n','i','x',',',' ','W','i','n','d','o','w','s','.','\n',
+        'I','f',' ','n','o',' ','o','p','t','i','o','n',' ','i','s',' ','g','i','v','e','n',' ','t','h','e',' ',
+        'd','e','f','a','u','l','t',' ','i','s',' ','U','n','i','x',' ','f','o','r','m','a','t','.','\n',0};
+
+    static const WCHAR  usage_msg[] = {'U','s','a','g','e',':',' ','%','s',' ','[','O','P','T','I','O','N',']',' ','[','P','A','T','H',']','.','.','.','\n',0};
+    static const WCHAR  invalid_opt[] = {'%','s',':',' ','i','n','v','a','l','i','d',' ','o','p','t','i','o','n',0};
+    static const WCHAR  long_opt_msg[] = {'%','s',0};
+    static const WCHAR  short_opt_msg[] = {'\'','-','%','c',0};
+    static const WCHAR  try_help_msg[] = {'\n','T','r','y',' ','\'','%','s',' ','-','-','h','e','l','p','\'','\n',0};
+    static const WCHAR  version_msg[] = {'%','s',' ','v','e','r','s','i','o','n',' ','%','s','\n',0};
 
     switch (shortopt) {
         case 'h':
-            printf("Usage: %s [OPTION] [PATH]...\n", progname);
-            printf(helpmsg);
+            mywprintf(TRUE, usage_msg, progname);
+            mywprintf(TRUE, help_msg);
             exit(0);
         case 'v':
-            printf("%s version " PACKAGE_VERSION "\n", progname);
-            exit(0);
+            {
+                WCHAR       tmp[64];
+
+                MultiByteToWideChar(CP_ACP, 0, PACKAGE_VERSION, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
+                mywprintf(TRUE, version_msg, tmp, progname);
+                exit(0);
+            }
         case 'l':
             return LONGFORMAT;
         case 's':
@@ -82,12 +146,12 @@ static int option(int shortopt, const WCHAR *longopt)
             return PRINT0;
     }
 
-    fprintf(stderr, "%s: invalid option ", progname);
+    mywprintf(FALSE, invalid_opt, progname);
     if (longopt)
-        fprintf(stderr, "%s\n", wine_dbgstr_w(longopt));
+        mywprintf(FALSE, long_opt_msg, longopt);
     else
-        fprintf(stderr, "'-%c'\n", shortopt);
-    fprintf(stderr, "Try '%s --help' for help\n", progname);
+        mywprintf(FALSE, short_opt_msg, shortopt);
+    mywprintf(FALSE, try_help_msg, progname);
     exit(2);
 }
 
@@ -149,10 +213,16 @@ int wmain(int argc, WCHAR *argv[])
     LPSTR (*CDECL wine_get_unix_file_name_ptr)(LPCWSTR) = NULL;
     LPWSTR (*CDECL wine_get_dos_file_name_ptr)(LPCSTR) = NULL;
     WCHAR dos_pathW[MAX_PATH];
-    char path[MAX_PATH];
     int outputformats;
     int i;
     int separator;
+    static const WCHAR fmt_c[] = {'%','c',0};
+    static const WCHAR fmt_sc[] = {'%','s','%','c',0};
+    static const WCHAR fmt_ssc[] = {'%','s','/','%','s','%','c',0};
+    static const WCHAR unix_file_msg[] = {'%','s',':',' ','c','a','n','n','o','t',' ','g','e','t',' ','t','h','e',' ','a','d','d','r','e','s','s',' ','o','f',' ',
+                                          '\'','w','i','n','e','_','g','e','t','_','u','n','i','x','_','f','i','l','e','_','n','a','m','e','\'','\n',0};
+    static const WCHAR dos_file_msg[] =  {'%','s',':',' ','c','a','n','n','o','t',' ','g','e','t',' ','t','h','e',' ','a','d','d','r','e','s','s',' ','o','f',' ',
+                                          '\'','w','i','n','e','_','g','e','t','_','d','o','s','_','f','i','l','e','_','n','a','m','e','\'','\n',0};
 
     outputformats = parse_options(argv);
 
@@ -172,8 +242,7 @@ int wmain(int argc, WCHAR *argv[])
             GetProcAddress(GetModuleHandleA("KERNEL32"),
                            "wine_get_unix_file_name");
         if (wine_get_unix_file_name_ptr == NULL) {
-            fprintf(stderr, "%s: cannot get the address of "
-                            "'wine_get_unix_file_name'\n", progname);
+            mywprintf(FALSE, unix_file_msg, progname);
             exit(3);
         }
     }
@@ -183,24 +252,22 @@ int wmain(int argc, WCHAR *argv[])
             GetProcAddress(GetModuleHandleA("KERNEL32"),
                            "wine_get_dos_file_name");
         if (wine_get_dos_file_name_ptr == NULL) {
-            fprintf(stderr, "%s: cannot get the address of "
-                            "'wine_get_dos_file_name'\n", progname);
+            mywprintf(FALSE, dos_file_msg, progname);
             exit(3);
         }
     }
 
     for (i = 1; argv[i]; i++)
     {
-        *path='\0';
         if (outputformats & LONGFORMAT) {
-            if (GetLongPathNameW(argv[i], dos_pathW, MAX_PATH))
-                WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL);
-            printf("%s%c", path, separator);
+            if (!GetLongPathNameW(argv[i], dos_pathW, MAX_PATH))
+                dos_pathW[0] = '\0';
+            mywprintf(TRUE, fmt_sc, dos_pathW, separator);
         }
         if (outputformats & SHORTFORMAT) {
-            if (GetShortPathNameW(argv[i], dos_pathW, MAX_PATH))
-                WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL);
-            printf("%s%c", path, separator);
+            if (!GetShortPathNameW(argv[i], dos_pathW, MAX_PATH))
+                dos_pathW[0] = '\0';
+            mywprintf(TRUE, fmt_sc, dos_pathW, separator);
         }
         if (outputformats & UNIXFORMAT) {
             WCHAR *ntpath, *tail;
@@ -211,22 +278,32 @@ int wmain(int argc, WCHAR *argv[])
             while (1)
             {
                 char *unix_name;
+                WCHAR *unix_nameW;
                 WCHAR *slash, *c;
+                unsigned sz;
 
                 unix_name = wine_get_unix_file_name_ptr(ntpath);
+
                 if (unix_name)
                 {
-                    if (tail)
-                    {
-                        WideCharToMultiByte(CP_UNIXCP, 0, tail+1, -1, path, MAX_PATH, NULL, NULL);
-                        printf("%s/%s%c", unix_name, path, separator);
-                    }
-                    else
+                    sz = MultiByteToWideChar(CP_UNIXCP, 0, unix_name, -1, NULL, 0);
+                    unix_nameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * sz);
+                    MultiByteToWideChar(CP_UNIXCP, 0, unix_name, -1, unix_nameW, sz);
+                    HeapFree( GetProcessHeap(), 0, unix_name );
+
+                    if (unix_nameW)
                     {
-                        printf("%s%c", unix_name, separator);
+                        if (tail)
+                        {
+                            mywprintf(TRUE, fmt_ssc, unix_nameW, tail + 1, separator);
+                        }
+                        else
+                        {
+                            mywprintf(TRUE, fmt_sc, unix_nameW, separator);
+                        }
+                        HeapFree( GetProcessHeap(), 0, unix_nameW );
+                        break;
                     }
-                    HeapFree( GetProcessHeap(), 0, unix_name );
-                    break;
                 }
 
                 slash=(tail ? tail : ntpath+ntpathlen);
@@ -237,7 +314,7 @@ int wmain(int argc, WCHAR *argv[])
                     /* This is a complete path conversion failure.
                      * It would typically happen if ntpath == "".
                      */
-                    printf("%c", separator);
+                    mywprintf(TRUE, fmt_c, separator);
                     break;
                 }
                 c=slash+1;
@@ -249,7 +326,7 @@ int wmain(int argc, WCHAR *argv[])
                     /* If this is not a valid NT path to start with,
                      * then obviously we cannot convert it.
                      */
-                    printf("%c", separator);
+                    mywprintf(TRUE, fmt_c, separator);
                     break;
                 }
                 if (tail)
@@ -270,11 +347,10 @@ int wmain(int argc, WCHAR *argv[])
 
             if ((windows_name = wine_get_dos_file_name_ptr(unix_name)))
             {
-                WideCharToMultiByte(CP_UNIXCP, 0, windows_name, -1, path, MAX_PATH, NULL, NULL);
-                printf("%s%c", path, separator);
+                mywprintf(TRUE, fmt_sc, windows_name, separator);
                 HeapFree( GetProcessHeap(), 0, windows_name );
             }
-            else printf("%c", separator);
+            else mywprintf(TRUE, fmt_c, separator);
             HeapFree( GetProcessHeap(), 0, unix_name );
         }
     }




More information about the wine-patches mailing list