diff options
author | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2023-08-03 11:57:01 +0300 |
---|---|---|
committer | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2023-08-03 20:17:16 +0300 |
commit | a42cc92778545d21429f9267540330991185f1f1 (patch) | |
tree | d9d670b3a11e7bdf39e7ee11bc7abb8276b2f930 | |
parent | 9e2c3594ccbd3ef45beab57cba6796f97f06906c (diff) | |
download | busybox-w32-a42cc92778545d21429f9267540330991185f1f1.tar.gz busybox-w32-a42cc92778545d21429f9267540330991185f1f1.tar.bz2 busybox-w32-a42cc92778545d21429f9267540330991185f1f1.zip |
win32: unify 'convert and write to console' (no-op)
Use one call to do both charToCon and then write it to the console.
Technically, this commit only reduces boilerplate code slightly,
but it also makes it easier for future modifications to make
changes to this sequence in one place.
-rw-r--r-- | win32/winansi.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/win32/winansi.c b/win32/winansi.c index f280177e6..e6528926e 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -10,6 +10,9 @@ | |||
10 | static BOOL charToConBuffA(LPSTR s, DWORD len); | 10 | static BOOL charToConBuffA(LPSTR s, DWORD len); |
11 | static BOOL charToConA(LPSTR s); | 11 | static BOOL charToConA(LPSTR s); |
12 | 12 | ||
13 | static int conv_fwriteCon(FILE *stream, char *buf, size_t siz); | ||
14 | static int conv_writeCon(int fd, char *buf, size_t siz); | ||
15 | |||
13 | /* | 16 | /* |
14 | Functions to be wrapped: | 17 | Functions to be wrapped: |
15 | */ | 18 | */ |
@@ -814,9 +817,7 @@ static int ansi_emulate(const char *s, FILE *stream) | |||
814 | size_t len = pos - str; | 817 | size_t len = pos - str; |
815 | 818 | ||
816 | if (len) { | 819 | if (len) { |
817 | *pos = '\0'; /* NB, '\033' has been overwritten */ | 820 | if (conv_fwriteCon(stream, str, len) == EOF) |
818 | charToConA(str); | ||
819 | if (fputs(str, stream) == EOF) | ||
820 | return EOF; | 821 | return EOF; |
821 | rv += len; | 822 | rv += len; |
822 | } | 823 | } |
@@ -837,9 +838,9 @@ static int ansi_emulate(const char *s, FILE *stream) | |||
837 | return EOF; | 838 | return EOF; |
838 | 839 | ||
839 | } else { | 840 | } else { |
840 | rv += strlen(str); | 841 | size_t len = strlen(str); |
841 | charToConA(str); | 842 | rv += len; |
842 | return fputs(str, stream) == EOF ? EOF : rv; | 843 | return conv_fwriteCon(stream, str, len) == EOF ? EOF : rv; |
843 | } | 844 | } |
844 | } | 845 | } |
845 | return rv; | 846 | return rv; |
@@ -853,8 +854,7 @@ int winansi_putchar(int c) | |||
853 | if (!is_console(STDOUT_FILENO)) | 854 | if (!is_console(STDOUT_FILENO)) |
854 | return putchar(c); | 855 | return putchar(c); |
855 | 856 | ||
856 | charToConBuffA(s, 1); | 857 | return conv_fwriteCon(stdout, s, 1) == EOF ? EOF : (unsigned char)c; |
857 | return putchar(t) == EOF ? EOF : (unsigned char)c; | ||
858 | } | 858 | } |
859 | 859 | ||
860 | int winansi_puts(const char *s) | 860 | int winansi_puts(const char *s) |
@@ -952,8 +952,7 @@ int winansi_fputc(int c, FILE *stream) | |||
952 | return ret; | 952 | return ret; |
953 | } | 953 | } |
954 | 954 | ||
955 | charToConBuffA(s, 1); | 955 | return conv_fwriteCon(stream, s, 1) == EOF ? EOF : (unsigned char )c; |
956 | return fputc(t, stream) == EOF ? EOF : (unsigned char )c; | ||
957 | } | 956 | } |
958 | 957 | ||
959 | #if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO | 958 | #if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO |
@@ -1083,8 +1082,7 @@ static int ansi_emulate_write(int fd, const void *buf, size_t count) | |||
1083 | len = pos - str; | 1082 | len = pos - str; |
1084 | 1083 | ||
1085 | if (len) { | 1084 | if (len) { |
1086 | charToConBuffA(str, len); | 1085 | out_len = conv_writeCon(fd, str, len); |
1087 | out_len = write(fd, str, len); | ||
1088 | if (out_len == -1) | 1086 | if (out_len == -1) |
1089 | return -1; | 1087 | return -1; |
1090 | rv += out_len; | 1088 | rv += out_len; |
@@ -1100,8 +1098,7 @@ static int ansi_emulate_write(int fd, const void *buf, size_t count) | |||
1100 | pos = str; | 1098 | pos = str; |
1101 | } else { | 1099 | } else { |
1102 | len = strlen(str); | 1100 | len = strlen(str); |
1103 | charToConA(str); | 1101 | out_len = conv_writeCon(fd, str, len); |
1104 | out_len = write(fd, str, len); | ||
1105 | return (out_len == -1) ? -1 : rv+out_len; | 1102 | return (out_len == -1) ? -1 : rv+out_len; |
1106 | } | 1103 | } |
1107 | } | 1104 | } |
@@ -1446,9 +1443,39 @@ void console_write(const char *str, int len) | |||
1446 | { | 1443 | { |
1447 | char *buf = xmemdup(str, len); | 1444 | char *buf = xmemdup(str, len); |
1448 | int fd = _open("CONOUT$", _O_WRONLY); | 1445 | int fd = _open("CONOUT$", _O_WRONLY); |
1449 | HANDLE fh = (HANDLE)_get_osfhandle(fd); | 1446 | conv_writeCon(fd, buf, len); |
1450 | charToConBuffA(buf, len); | ||
1451 | WriteConsole(fh, buf, len, NULL, NULL); | ||
1452 | close(fd); | 1447 | close(fd); |
1453 | free(buf); | 1448 | free(buf); |
1454 | } | 1449 | } |
1450 | |||
1451 | // TODO: improvements: | ||
1452 | // | ||
1453 | // 1. currently conv_[f]writeCon modify buf inplace, which means the caller | ||
1454 | // typically has to make a writable copy first just for this. | ||
1455 | // Sometimes it allocates a big copy once, and calls us with substrings. | ||
1456 | // Instead, we could make a writable copy here - it's not used later anyway. | ||
1457 | // To avoid the performance hit of many small allocations, we could use | ||
1458 | // a local buffer for short strings, and allocate only if it doesn't fit | ||
1459 | // (or maybe just reuse the local buffer with substring iterations). | ||
1460 | // | ||
1461 | // 2. Instead of converting from ACP to the console out CP - which guarantees | ||
1462 | // potential data-loss if they differ, we could convert it to wchar_t and | ||
1463 | // write it using WriteConsoleW. This should prevent all output data-loss. | ||
1464 | // care should be taken with DBCS codepages (e.g. 936) or other multi-byte | ||
1465 | // because then converting on arbitrary substring boundaries can fail. | ||
1466 | |||
1467 | // convert buf inplace from ACP to console out CP and write it to stream | ||
1468 | // returns EOF on error, 0 on success | ||
1469 | static int conv_fwriteCon(FILE *stream, char *buf, size_t siz) | ||
1470 | { | ||
1471 | charToConBuffA(buf, siz); | ||
1472 | return fwrite(buf, 1, siz, stream) < siz ? EOF : 0; | ||
1473 | } | ||
1474 | |||
1475 | // similar to above, but using lower level write | ||
1476 | // returns -1 on error, actually-written bytes on suceess | ||
1477 | static int conv_writeCon(int fd, char *buf, size_t siz) | ||
1478 | { | ||
1479 | charToConBuffA(buf, siz); | ||
1480 | return write(fd, buf, siz); | ||
1481 | } | ||