aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mingw.h2
-rw-r--r--win32/winansi.c76
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);
146int winansi_fputs(const char *str, FILE *stream); 146int winansi_fputs(const char *str, FILE *stream);
147int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); 147int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
148int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3))); 148int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
149int 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
156int winansi_get_terminal_width_height(struct winsize *win); 158int 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
541static 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
602int 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}