[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