diff options
-rw-r--r-- | include/mingw.h | 2 | ||||
-rw-r--r-- | win32/winansi.c | 76 |
2 files changed, 77 insertions, 1 deletions
diff --git a/include/mingw.h b/include/mingw.h index 23472e1b1..17db36c05 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -146,12 +146,14 @@ size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); | |||
146 | int winansi_fputs(const char *str, FILE *stream); | 146 | int winansi_fputs(const char *str, FILE *stream); |
147 | int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); | 147 | int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); |
148 | int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3))); | 148 | int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3))); |
149 | int winansi_write(int fd, const void *buf, size_t count); | ||
149 | #define putchar winansi_putchar | 150 | #define putchar winansi_putchar |
150 | #define puts winansi_puts | 151 | #define puts winansi_puts |
151 | #define fwrite winansi_fwrite | 152 | #define fwrite winansi_fwrite |
152 | #define fputs winansi_fputs | 153 | #define fputs winansi_fputs |
153 | #define printf(...) winansi_printf(__VA_ARGS__) | 154 | #define printf(...) winansi_printf(__VA_ARGS__) |
154 | #define fprintf(...) winansi_fprintf(__VA_ARGS__) | 155 | #define fprintf(...) winansi_fprintf(__VA_ARGS__) |
156 | #define write winansi_write | ||
155 | 157 | ||
156 | int winansi_get_terminal_width_height(struct winsize *win); | 158 | int winansi_get_terminal_width_height(struct winsize *win); |
157 | 159 | ||
diff --git a/win32/winansi.c b/win32/winansi.c index ba3167425..8f2bb72e4 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #undef putchar | 15 | #undef putchar |
16 | #undef fwrite | 16 | #undef fwrite |
17 | #undef puts | 17 | #undef puts |
18 | /* TODO: write */ | 18 | #undef write |
19 | 19 | ||
20 | /* | 20 | /* |
21 | ANSI codes used by git: m, K | 21 | ANSI codes used by git: m, K |
@@ -537,3 +537,77 @@ int winansi_get_terminal_width_height(struct winsize *win) | |||
537 | 537 | ||
538 | return ret ? 0 : -1; | 538 | return ret ? 0 : -1; |
539 | } | 539 | } |
540 | |||
541 | static int ansi_emulate_write(int fd, const void *buf, size_t count) | ||
542 | { | ||
543 | int rv = 0, i; | ||
544 | const char *s = (const char *)buf; | ||
545 | char *pos, *str; | ||
546 | size_t len, out_len; | ||
547 | static size_t max_len = 0; | ||
548 | static char *mem = NULL; | ||
549 | |||
550 | /* if no special treatment is required output the string as-is */ | ||
551 | for ( i=0; i<count; ++i ) { | ||
552 | if ( s[i] == '\033' || s[i] > 0x7f ) { | ||
553 | break; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | if ( i == count ) { | ||
558 | return write(fd, buf, count); | ||
559 | } | ||
560 | |||
561 | /* make a writable copy of the data and retain it for reuse */ | ||
562 | if ( count > max_len ) { | ||
563 | free(mem); | ||
564 | mem = xmalloc(count+1); | ||
565 | max_len = count; | ||
566 | } | ||
567 | memcpy(mem, buf, count); | ||
568 | mem[count] = '\0'; | ||
569 | pos = str = mem; | ||
570 | |||
571 | /* we're writing to the console so we assume the data isn't binary */ | ||
572 | while (*pos) { | ||
573 | pos = strstr(str, "\033["); | ||
574 | if (pos) { | ||
575 | len = pos - str; | ||
576 | |||
577 | if (len) { | ||
578 | CharToOemBuff(str, str, len); | ||
579 | out_len = write(fd, buf, len); | ||
580 | rv += out_len; | ||
581 | if (out_len < len) | ||
582 | return rv; | ||
583 | } | ||
584 | |||
585 | str = pos + 2; | ||
586 | rv += 2; | ||
587 | |||
588 | pos = (char *)set_attr(str); | ||
589 | rv += pos - str; | ||
590 | str = pos; | ||
591 | } else { | ||
592 | len = strlen(str); | ||
593 | rv += len; | ||
594 | CharToOem(str, str); | ||
595 | write(fd, str, len); | ||
596 | return rv; | ||
597 | } | ||
598 | } | ||
599 | return rv; | ||
600 | } | ||
601 | |||
602 | int winansi_write(int fd, const void *buf, size_t count) | ||
603 | { | ||
604 | if (!isatty(fd)) | ||
605 | return write(fd, buf, count); | ||
606 | |||
607 | init(); | ||
608 | |||
609 | if (!console) | ||
610 | return write(fd, buf, count); | ||
611 | |||
612 | return ansi_emulate_write(fd, buf, count); | ||
613 | } | ||