This is the mail archive of the
cygwin-patches@sources.redhat.com
mailing list for the Cygwin project.
Console codepage
- To: Cygwin-Patches <cygwin-patches at cygwin dot com>
- Subject: Console codepage
- From: Benjamin Riefenstahl <Benjamin dot Riefenstahl at epost dot de>
- Date: 28 Jan 2001 21:42:30 +0100
Hi everybody,
The code to support I/O to the console (fhandler_console.cc) currently
assumes that the console uses the default OEM codepage. The user can
change that with CHCP.COM though, and I for one do that routinely. It
is amoung other things a very usefull to do when running a shell in
NTEmacs. Because of this customization, 8-bit character console I/O
in Cygwin has for some time been broken for me.
I corrected this in fhandler_console.cc by replacing functions
OemToChar() and CharToOem() with a combo of MultiByteToWideChar() and
WideCharToMultiByte().
I tested console output on Win2000 with "time od test.data" and it
doesn't look like there is a noticeable difference in efficiency.
I include the result of a "cvs diff" below.
This is my first submission for Cygwin so if there is anything I can
do to make this easier to process, just tell me.
so long, benny
Index: fhandler.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v
retrieving revision 1.40
diff -r1.40 fhandler.h
611a612,613
> BOOL prepare_output (char * buf, DWORD * buf_len,
> const char * src, DWORD * src_len);
Index: fhandler_console.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_console.cc,v
retrieving revision 1.36
diff -r1.36 fhandler_console.cc
20a21
> #include <winnls.h> // MultiByteToWideChar() and friends
31a33,89
>
> #define CONVERT_LIMIT 4096
>
> /* The codepages are resolved here instead of using CP_ACP and
> CP_OEMCP, so that they can later be compared for equality. */
> inline UINT cp_get_internal ()
> { return current_codepage == ansi_cp ? GetACP() : GetOEMCP(); }
>
> static BOOL
> cp_convert (UINT destcp, char * dest,
> UINT srccp, const char * src,
> DWORD size)
> {
> if( 0 == size )
> ; /* no action */
> else if (destcp == srccp)
> {
> if (dest != src)
> memcpy(dest, src, size);
> }
> else
> {
> WCHAR wbuffer[CONVERT_LIMIT]; /* same size as the maximum input, s.b. */
> if (0 == MultiByteToWideChar (srccp, 0 /* no options */,
> src, size, wbuffer, sizeof(wbuffer)) )
> return FALSE;
> if (0 == WideCharToMultiByte (destcp, 0 /* no options */,
> wbuffer, size, dest, size,
> NULL, NULL /* no default char */) )
> return FALSE;
> }
> return TRUE;
> }
>
> /* The results of GetConsoleCP() and GetConsoleOutputCP() can not be
> cached, because a program or the user can change these values at
> any time. */
> inline BOOL con_to_str (char * d, const char * s, DWORD sz)
> { return cp_convert (cp_get_internal (), d, GetConsoleCP (), s, sz); }
> inline BOOL str_to_con (char * d, const char * s, DWORD sz)
> { return cp_convert (GetConsoleOutputCP (), d, cp_get_internal (), s, sz); }
>
> BOOL
> fhandler_console::prepare_output (char * buf, DWORD * buf_len,
> const char * src, DWORD * src_len)
> {
> *buf_len = *src_len = min (*buf_len, *src_len);
> if (! str_to_con (buf, src, *src_len) )
> {
> debug_printf ("conversion error, handle %p", get_output_handle ());
> __seterrno();
> return FALSE;
> }
> return TRUE;
> }
>
>
219,222c277,280
< /* Need this check since US code page seems to have a bug when
< converting a CTRL-U. */
< if ((unsigned char)ich > 0x7f && current_codepage == ansi_cp)
< OemToCharBuff (tmp + 1, tmp + 1, 1);
---
> /* Need this check since US code page seems to have a
> bug when converting a CTRL-U. */
> if ((unsigned char)ich > 0x7f)
> con_to_str (tmp+1, tmp+1, 1);
1180,1181c1238,1239
< char buf[4096];
< size_t len = found - src;
---
> char buf[CONVERT_LIMIT];
> DWORD len = found - src;
1183,1188c1241,1245
< size_t l2 = min (sizeof (buf), len);
< if (current_codepage == ansi_cp)
< CharToOemBuff ((LPCSTR)src, buf, l2);
< else
< strncpy (buf, (LPCSTR)src, l2);
< if (! WriteFile (get_output_handle (), buf, l2, &done, 0))
---
> DWORD buf_len = sizeof (buf);
> done = len;
> if (! prepare_output(buf, &buf_len, (const char*)src, &done) )
> return 0;
> if (! WriteFile (get_output_handle (), buf, buf_len, &done, 0) )