aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-03-19 11:44:05 +0000
committerRon Yorston <rmy@pobox.com>2014-03-19 11:44:05 +0000
commit114ddd900acf9de27cc9e651d0af26df3948d34f (patch)
tree2dacb8e311a33e319a8bd6385efff890487a7ba9
parentcfb45378f7ecbfa87ad0b61e9463dd83bc5ce615 (diff)
downloadbusybox-w32-114ddd900acf9de27cc9e651d0af26df3948d34f.tar.gz
busybox-w32-114ddd900acf9de27cc9e651d0af26df3948d34f.tar.bz2
busybox-w32-114ddd900acf9de27cc9e651d0af26df3948d34f.zip
Use OEM codepage for console I/O
Windows console applications use different codepages for console I/O and the rest of the API: http://msdn.microsoft.com/en-us/goglobal/bb688114.aspx#E2F Attempt to workaround this by converting characters when they're read from and written to the console. Not all possible paths are handled.
-rw-r--r--include/mingw.h4
-rw-r--r--win32/termios.c3
-rw-r--r--win32/winansi.c84
3 files changed, 87 insertions, 4 deletions
diff --git a/include/mingw.h b/include/mingw.h
index 31795bc40..a1a9f5f30 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -140,9 +140,13 @@ int mingw_pclose(FILE *fd);
140 * ANSI emulation wrappers 140 * ANSI emulation wrappers
141 */ 141 */
142 142
143int winansi_putchar(int c);
144size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
143int winansi_fputs(const char *str, FILE *stream); 145int winansi_fputs(const char *str, FILE *stream);
144int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); 146int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
145int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3))); 147int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
148#define putchar winansi_putchar
149#define fwrite winansi_fwrite
146#define fputs winansi_fputs 150#define fputs winansi_fputs
147#define printf(...) winansi_printf(__VA_ARGS__) 151#define printf(...) winansi_printf(__VA_ARGS__)
148#define fprintf(...) winansi_fprintf(__VA_ARGS__) 152#define fprintf(...) winansi_fprintf(__VA_ARGS__)
diff --git a/win32/termios.c b/win32/termios.c
index ad6ab117f..40e70309e 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -16,6 +16,7 @@ int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout)
16 INPUT_RECORD record; 16 INPUT_RECORD record;
17 DWORD nevent_out, mode; 17 DWORD nevent_out, mode;
18 int ret = -1; 18 int ret = -1;
19 char *s;
19 20
20 if (fd != 0) 21 if (fd != 0)
21 bb_error_msg_and_die("read_key only works on stdin"); 22 bb_error_msg_and_die("read_key only works on stdin");
@@ -74,6 +75,8 @@ int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout)
74 } 75 }
75 continue; 76 continue;
76 } 77 }
78 s = &record.Event.KeyEvent.uChar.AsciiChar;
79 OemToCharBuff(s, s, 1);
77 ret = record.Event.KeyEvent.uChar.AsciiChar; 80 ret = record.Event.KeyEvent.uChar.AsciiChar;
78 break; 81 break;
79 } 82 }
diff --git a/win32/winansi.c b/win32/winansi.c
index ea97a70c3..cafad031d 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -12,6 +12,8 @@
12#undef printf 12#undef printf
13#undef fprintf 13#undef fprintf
14#undef fputs 14#undef fputs
15#undef putchar
16#undef fwrite
15/* TODO: write */ 17/* TODO: write */
16 18
17/* 19/*
@@ -309,10 +311,36 @@ static const char *set_attr(const char *str)
309 return func + 1; 311 return func + 1;
310} 312}
311 313
312static int ansi_emulate(const char *str, FILE *stream) 314static int ansi_emulate(const char *s, FILE *stream)
313{ 315{
314 int rv = 0; 316 int rv = 0;
315 const char *pos = str; 317 char *pos, *str;
318 size_t out_len, cur_len;
319 static size_t max_len = 0;
320 static char *mem = NULL;
321
322 /* if no special treatment is required output the string as-is */
323 for ( pos=s; *pos; ++pos ) {
324 if ( *pos == '\033' || *pos > 0x7f ) {
325 break;
326 }
327 }
328
329 if ( *pos == '\0' ) {
330 return fputs(s, stream) == EOF ? EOF : strlen(s);
331 }
332
333 /* make a writable copy of the string and retain it for reuse */
334 cur_len = strlen(s);
335 if ( cur_len == 0 || cur_len > max_len ) {
336 free(mem);
337 mem = strdup(s);
338 max_len = cur_len;
339 }
340 else {
341 strcpy(mem, s);
342 }
343 pos = str = mem;
316 344
317 while (*pos) { 345 while (*pos) {
318 pos = strstr(str, "\033["); 346 pos = strstr(str, "\033[");
@@ -320,7 +348,8 @@ static int ansi_emulate(const char *str, FILE *stream)
320 size_t len = pos - str; 348 size_t len = pos - str;
321 349
322 if (len) { 350 if (len) {
323 size_t out_len = fwrite(str, 1, len, stream); 351 CharToOemBuff(str, str, len);
352 out_len = fwrite(str, 1, len, stream);
324 rv += out_len; 353 rv += out_len;
325 if (out_len < len) 354 if (out_len < len)
326 return rv; 355 return rv;
@@ -331,11 +360,12 @@ static int ansi_emulate(const char *str, FILE *stream)
331 360
332 fflush(stream); 361 fflush(stream);
333 362
334 pos = set_attr(str); 363 pos = (char *)set_attr(str);
335 rv += pos - str; 364 rv += pos - str;
336 str = pos; 365 str = pos;
337 } else { 366 } else {
338 rv += strlen(str); 367 rv += strlen(str);
368 CharToOem(str, str);
339 fputs(str, stream); 369 fputs(str, stream);
340 return rv; 370 return rv;
341 } 371 }
@@ -343,6 +373,52 @@ static int ansi_emulate(const char *str, FILE *stream)
343 return rv; 373 return rv;
344} 374}
345 375
376int winansi_putchar(int c)
377{
378 char t = c;
379 char *s = &t;
380
381 if (!isatty(0))
382 return putchar(c);
383
384 init();
385
386 if (!console)
387 return putchar(c);
388
389 CharToOemBuff(s, s, 1);
390 return putchar(t) == EOF ? EOF : c;
391}
392
393size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
394{
395 size_t lsize, lmemb;
396 char *str;
397 int rv;
398
399 lsize = MIN(size, nmemb);
400 lmemb = MAX(size, nmemb);
401 if (lsize != 1)
402 return fwrite(ptr, size, nmemb, stream);
403
404 if (!isatty(fileno(stream)))
405 return fwrite(ptr, size, nmemb, stream);
406
407 init();
408
409 if (!console)
410 return fwrite(ptr, size, nmemb, stream);
411
412 str = xmalloc(lmemb+1);
413 memcpy(str, ptr, lmemb);
414 str[lmemb] = '\0';
415
416 rv = ansi_emulate(str, stream);
417 free(str);
418
419 return rv;
420}
421
346int winansi_fputs(const char *str, FILE *stream) 422int winansi_fputs(const char *str, FILE *stream)
347{ 423{
348 int rv; 424 int rv;