This is the mail archive of the
cygwin-patches@sources.redhat.com
mailing list for the Cygwin project.
Re: Console codepage
Hi Christopher,
Christopher Faylor <cgf@redhat.com> writes:
> Please look at the "Contributing" link on the Cygwin web page. I've
> gone to some pains to update it lately by showing examples of common
> problems with patch submissions. Unfortunately, there were several
> problems with this submission.
O.k., I hope this one is better (see below).
> In the meantime, however, please check out that page. If you could
> send an assignment form, too, that would help make sure that the
> legalities are covered.
That will take some time, especially for a disclaimer from my company.
so long, benny
Changelog entry:
Sun Jan 28 22:05:00 2001 Benjamin Riefenstahl <Benjamin.Riefenstahl@epost.de>
* fhandler_console.cc: Add functions cp_convert, con_to_str,
str_to_con.
* fhandler_console.cc,fhandler.h: Add method
fhandler_console::prepare_output.
* fhandler_console.cc (fhandler_console::read): Replace
OemToCharBuff with con_to_str.
* fhandler_console.cc (fhandler_console::write_normal): Replace
CharToOemBuff with fhandler_console::prepare_output.
Patch (cvs diff -up):
Index: fhandler.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v
retrieving revision 1.40
diff -u -p -r1.40 fhandler.h
--- fhandler.h 2001/01/17 14:57:09 1.40
+++ fhandler.h 2001/01/28 20:58:24
@@ -609,6 +609,8 @@ private:
const unsigned char * write_normal (unsigned const char*, unsigned const char *);
void char_command (char, bool);
int output_tcsetattr (int a, const struct termios *t);
+ BOOL prepare_output (char * buf, DWORD * buf_len,
+ const char * src, DWORD * src_len);
/* Input calls */
int igncr_enabled ();
Index: fhandler_console.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_console.cc,v
retrieving revision 1.36
diff -u -p -r1.36 fhandler_console.cc
--- fhandler_console.cc 2001/01/28 05:51:14 1.36
+++ fhandler_console.cc 2001/01/28 20:58:26
@@ -18,6 +18,7 @@ details. */
#include <wingdi.h>
#include <winuser.h>
#include <wincon.h>
+#include <winnls.h> // MultiByteToWideChar() and friends
#include <ctype.h>
#include <sys/cygwin.h>
#include "cygheap.h"
@@ -29,6 +30,63 @@ details. */
#include "shared_info.h"
#include "security.h"
+
+#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;
+}
+
+
/*
* Scroll the screen context.
* x1, y1 - ul corner
@@ -216,10 +274,10 @@ fhandler_console::read (void *pv, size_t
else
{
tmp[1] = ich;
- /* 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);
if (!(input_rec.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED))
toadd = tmp + 1;
else
@@ -1177,15 +1235,14 @@ fhandler_console::write_normal (const un
/* Print all the base ones out */
if (found != src)
{
- char buf[4096];
- size_t len = found - src;
+ char buf[CONVERT_LIMIT];
+ DWORD len = found - src;
do {
- 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) )
{
debug_printf ("write failed, handle %p", get_output_handle ());
__seterrno ();