* cygpath.cc (codepage): New variable.

(long_options): Add --codepage option.
	(options): Add -C option.
	(usage): Add -C/--codepage description.
	(my_wcstombs): New function.  Use througout instead of wcstombs.
	(do_options): Handle -C/--codepage option.
	* utils.sgml (cygpath): Add description for new -C/--codepage option.
This commit is contained in:
Corinna Vinschen 2009-05-17 11:16:12 +00:00
parent 48829c1d86
commit 0a23799aee
3 changed files with 85 additions and 10 deletions

View File

@ -1,3 +1,13 @@
2009-05-17 Corinna Vinschen <corinna@vinschen.de>
* cygpath.cc (codepage): New variable.
(long_options): Add --codepage option.
(options): Add -C option.
(usage): Add -C/--codepage description.
(my_wcstombs): New function. Use througout instead of wcstombs.
(do_options): Handle -C/--codepage option.
* utils.sgml (cygpath): Add description for new -C/--codepage option.
2009-05-16 Corinna Vinschen <corinna@vinschen.de> 2009-05-16 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (cygpath.exe): Link against cygwin.a before linking * Makefile.in (cygpath.exe): Link against cygwin.a before linking

View File

@ -38,6 +38,7 @@ static int path_flag, unix_flag, windows_flag, absolute_flag;
static int shortname_flag, longname_flag; static int shortname_flag, longname_flag;
static int ignore_flag, allusers_flag, output_flag; static int ignore_flag, allusers_flag, output_flag;
static int mixed_flag, options_from_file_flag, mode_flag; static int mixed_flag, options_from_file_flag, mode_flag;
static UINT codepage;
static const char *format_type_arg; static const char *format_type_arg;
@ -66,10 +67,11 @@ static struct option long_options[] = {
{(char *) "sysdir", no_argument, NULL, 'S'}, {(char *) "sysdir", no_argument, NULL, 'S'},
{(char *) "windir", no_argument, NULL, 'W'}, {(char *) "windir", no_argument, NULL, 'W'},
{(char *) "folder", required_argument, NULL, 'F'}, {(char *) "folder", required_argument, NULL, 'F'},
{(char *) "codepage", required_argument, NULL, 'C'},
{0, no_argument, 0, 0} {0, no_argument, 0, 0}
}; };
static char options[] = "ac:df:hilmMopst:uvwADHOPSWF:"; static char options[] = "ac:df:hilmMopst:uvwAC:DHOPSWF:";
static void static void
usage (FILE * stream, int status) usage (FILE * stream, int status)
@ -94,6 +96,11 @@ Path conversion options:\n\
-l, --long-name print Windows long form of NAMEs (with -w, -m only)\n\ -l, --long-name print Windows long form of NAMEs (with -w, -m only)\n\
-p, --path NAME is a PATH list (i.e., '/bin:/usr/bin')\n\ -p, --path NAME is a PATH list (i.e., '/bin:/usr/bin')\n\
-s, --short-name print DOS (short) form of NAMEs (with -w, -m only)\n\ -s, --short-name print DOS (short) form of NAMEs (with -w, -m only)\n\
-C, --codepage CP print DOS, Windows, or mixed pathname in Windows\n\
codepage CP. CP can be a numeric codepage identifier,\n\
or one of the reserved words ANSI, OEM, or UTF8.\n\
If this option is missing, %s defaults to the\n\
character set defined by the current locale.\n\
System information:\n\ System information:\n\
-A, --allusers use `All Users' instead of current user for -D, -O, -P\n\ -A, --allusers use `All Users' instead of current user for -D, -O, -P\n\
-D, --desktop output `Desktop' directory and exit\n\ -D, --desktop output `Desktop' directory and exit\n\
@ -103,7 +110,7 @@ System information:\n\
-S, --sysdir output system directory and exit\n\ -S, --sysdir output system directory and exit\n\
-W, --windir output `Windows' directory and exit\n\ -W, --windir output `Windows' directory and exit\n\
-F, --folder ID output special folder with numeric ID and exit\n\ -F, --folder ID output special folder with numeric ID and exit\n\
", prog_name, prog_name, prog_name, prog_name); ", prog_name, prog_name, prog_name, prog_name, prog_name);
if (ignore_flag) if (ignore_flag)
/* nothing to do */; /* nothing to do */;
else if (stream != stdout) else if (stream != stdout)
@ -132,6 +139,15 @@ RtlAllocateUnicodeString (PUNICODE_STRING uni, ULONG size)
return uni->Buffer != NULL; return uni->Buffer != NULL;
} }
static size_t
my_wcstombs (char *dest, const wchar_t *src, size_t n)
{
if (codepage)
return WideCharToMultiByte (codepage, 0, src, -1, dest, n, NULL, NULL);
else
return wcstombs (dest, src, n);
}
static char * static char *
get_device_name (char *path) get_device_name (char *path)
{ {
@ -331,14 +347,14 @@ get_short_paths (char *path)
++ptr, ++sptr; ++ptr, ++sptr;
acc -= len + 1; acc -= len + 1;
} }
len = wcstombs (NULL, sbuf, 0) + 1; len = my_wcstombs (NULL, sbuf, 0) + 1;
ptr = (char *) malloc (len); ptr = (char *) malloc (len);
if (ptr == NULL) if (ptr == NULL)
{ {
fprintf (stderr, "%s: out of memory\n", prog_name); fprintf (stderr, "%s: out of memory\n", prog_name);
exit (1); exit (1);
} }
wcstombs (ptr, sbuf, len); my_wcstombs (ptr, sbuf, len);
return ptr; return ptr;
} }
@ -355,14 +371,14 @@ get_short_name (const char *filename)
filename); filename);
exit (2); exit (2);
} }
len = wcstombs (NULL, buf, 0) + 1; len = my_wcstombs (NULL, buf, 0) + 1;
sbuf = (char *) malloc (len); sbuf = (char *) malloc (len);
if (sbuf == NULL) if (sbuf == NULL)
{ {
fprintf (stderr, "%s: out of memory\n", prog_name); fprintf (stderr, "%s: out of memory\n", prog_name);
exit (1); exit (1);
} }
wcstombs (sbuf, buf, len); my_wcstombs (sbuf, buf, len);
return sbuf; return sbuf;
} }
@ -452,14 +468,14 @@ get_long_name (const char *filename, DWORD& len)
wcsncat (buf, wpath, 32767); wcsncat (buf, wpath, 32767);
} }
} }
len = wcstombs (NULL, buf, 0); len = my_wcstombs (NULL, buf, 0);
sbuf = (char *) malloc (len + 1); sbuf = (char *) malloc (len + 1);
if (!sbuf) if (!sbuf)
{ {
fprintf (stderr, "%s: out of memory\n", prog_name); fprintf (stderr, "%s: out of memory\n", prog_name);
exit (1); exit (1);
} }
wcstombs (sbuf, buf, len + 1); my_wcstombs (sbuf, buf, len + 1);
return sbuf; return sbuf;
} }
@ -738,7 +754,7 @@ do_pathconv (char *filename)
} }
if (!unix_flag) if (!unix_flag)
{ {
wcstombs (buf, buf2, 32768); my_wcstombs (buf, buf2, 32768);
buf = get_device_name (buf); buf = get_device_name (buf);
if (shortname_flag) if (shortname_flag)
buf = get_short_name (buf); buf = get_short_name (buf);
@ -802,6 +818,7 @@ do_options (int argc, char **argv, int from_file)
allusers_flag = 0; allusers_flag = 0;
output_flag = 0; output_flag = 0;
mode_flag = 0; mode_flag = 0;
codepage = 0;
if (!from_file) if (!from_file)
options_from_file_flag = 0; options_from_file_flag = 0;
optind = 0; optind = 0;
@ -893,6 +910,25 @@ do_options (int argc, char **argv, int from_file)
allusers_flag = 1; allusers_flag = 1;
break; break;
case 'C':
if (!optarg)
usage (stderr, 1);
if (!strcasecmp (optarg, "ANSI"))
codepage = GetACP ();
else if (!strcasecmp (optarg, "OEM"))
codepage = GetOEMCP ();
else if (!strcasecmp (optarg, "UTF8")
|| !strcasecmp (optarg, "UTF-8"))
codepage = CP_UTF8;
else
{
char *c;
codepage = (UINT) strtoul (optarg, &c, 10);
if (*c)
usage (stderr, 1);
}
break;
case 'D': case 'D':
case 'H': case 'H':
case 'O': case 'O':

View File

@ -207,6 +207,11 @@ Path conversion options:
-l, --long-name print Windows long form of NAMEs (with -w, -m only) -l, --long-name print Windows long form of NAMEs (with -w, -m only)
-p, --path NAME is a PATH list (i.e., '/bin:/usr/bin') -p, --path NAME is a PATH list (i.e., '/bin:/usr/bin')
-s, --short-name print DOS (short) form of NAMEs (with -w, -m only) -s, --short-name print DOS (short) form of NAMEs (with -w, -m only)
-C, --codepage CP print DOS, Windows, or mixed pathname in Windows
codepage CP. CP can be a numeric codepage identifier,
or one of the reserved words ANSI, OEM, or UTF8.
If this option is missing, cygpath defaults to the
character set defined by the current locale.
System information: System information:
-A, --allusers use `All Users' instead of current user for -D, -P -A, --allusers use `All Users' instead of current user for -D, -P
-D, --desktop output `Desktop' directory and exit -D, --desktop output `Desktop' directory and exit
@ -249,6 +254,30 @@ the <literal>-l</literal> and <literal>-s</literal> options to use normal
identical to <literal>-w</literal> and <literal>-s</literal> together. identical to <literal>-w</literal> and <literal>-s</literal> together.
</para> </para>
<para>The <literal>-C</literal> option allows to specify a Windows codepage
to print DOS and Windows paths created with one of the <literal>-d</literal>,
<literal>-m</literal>, or <literal>-w</literal> options. The default is to
use the character set of the current locale defined by one of the
internationalization environment variables <envar>LC_ALL</envar>,
<envar>LC_CTYPE</envar>, or <envar>LANG</envar>, see
<xref linkend="setup-locale"></xref>. This is sometimes not sufficent for
interaction with native Windows tools, which might expect native, non-ASCII
characters in a specific Windows codepage. Console tools, for instance, might
expect pathnames in the current OEM codepage, while graphical tools like
Windows Explorer might expect pathnames in the current ANSI codepage.</para>
<para>The <literal>-C</literal> option takes a single parameter:</para>
<itemizedlist spacing="compact">
<listitem><para><literal>ANSI</literal>, to specify the current ANSI codepage</para></listitem>
<listitem><para><literal>OEM</literal>, to specify the current OEM (console) codepage</para></listitem>
<listitem><para><literal>UTF8</literal>, to specify UTF-8.</para></listitem>
<listitem><para>A numerical, decimal codepage number, for instance 936 for GBK,
28593 for ISO-8859-3, etc. A full list of supported codepages is listed on the
Microsoft MSDN page
<ulink url="http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx">Code Page Identifiers</ulink>. A codepage of 0 is the same as if the
<literal>-C</literal> hasn't been specified at all.</para></listitem>
</itemizedlist>
<para>The <literal>-p</literal> option means that you want to convert <para>The <literal>-p</literal> option means that you want to convert
a path-style string rather than a single filename. For example, the a path-style string rather than a single filename. For example, the
PATH environment variable is semicolon-delimited in Windows, but PATH environment variable is semicolon-delimited in Windows, but
@ -272,7 +301,7 @@ if [ "${1}" = "" ];
then then
XPATH="."; XPATH=".";
else else
XPATH="$(cygpath -w "${1}")"; XPATH="$(cygpath -C ANSI -w "${1}")";
fi fi
explorer $XPATH & explorer $XPATH &
]]> ]]>