aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2023-08-03 11:57:01 +0300
committerAvi Halachmi (:avih) <avihpit@yahoo.com>2023-08-03 20:17:16 +0300
commita42cc92778545d21429f9267540330991185f1f1 (patch)
treed9d670b3a11e7bdf39e7ee11bc7abb8276b2f930
parent9e2c3594ccbd3ef45beab57cba6796f97f06906c (diff)
downloadbusybox-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.c61
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 @@
10static BOOL charToConBuffA(LPSTR s, DWORD len); 10static BOOL charToConBuffA(LPSTR s, DWORD len);
11static BOOL charToConA(LPSTR s); 11static BOOL charToConA(LPSTR s);
12 12
13static int conv_fwriteCon(FILE *stream, char *buf, size_t siz);
14static 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
860int winansi_puts(const char *s) 860int 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
1469static 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
1477static int conv_writeCon(int fd, char *buf, size_t siz)
1478{
1479 charToConBuffA(buf, siz);
1480 return write(fd, buf, siz);
1481}