This is the mail archive of the cygwin-patches@sources.redhat.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Console codepage


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) )


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]