diff options
Diffstat (limited to '')
-rw-r--r-- | editors/awk.c | 21 | ||||
-rw-r--r-- | editors/diff.c | 26 | ||||
-rw-r--r-- | editors/sed.c | 21 | ||||
-rw-r--r-- | editors/vi.c | 66 |
4 files changed, 133 insertions, 1 deletions
diff --git a/editors/awk.c b/editors/awk.c index d25508e5d..c4553728d 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -734,7 +734,11 @@ static char *skip_spaces(char *p) | |||
734 | if (*p == '\\' && p[1] == '\n') { | 734 | if (*p == '\\' && p[1] == '\n') { |
735 | p++; | 735 | p++; |
736 | t_lineno++; | 736 | t_lineno++; |
737 | #if !ENABLE_PLATFORM_MINGW32 | ||
737 | } else if (*p != ' ' && *p != '\t') { | 738 | } else if (*p != ' ' && *p != '\t') { |
739 | #else | ||
740 | } else if (*p != ' ' && *p != '\t' && *p != '\r') { | ||
741 | #endif | ||
738 | break; | 742 | break; |
739 | } | 743 | } |
740 | p++; | 744 | p++; |
@@ -1991,6 +1995,21 @@ static int ptest(node *pattern) | |||
1991 | return istrue(evaluate(pattern, &G.ptest__v)); | 1995 | return istrue(evaluate(pattern, &G.ptest__v)); |
1992 | } | 1996 | } |
1993 | 1997 | ||
1998 | #if ENABLE_PLATFORM_MINGW32 | ||
1999 | static ssize_t FAST_FUNC safe_read_strip_cr(int fd, void *buf, size_t count) | ||
2000 | { | ||
2001 | ssize_t n; | ||
2002 | |||
2003 | do { | ||
2004 | n = safe_read(fd, buf, count); | ||
2005 | } while (n > 0 && (n=remove_cr((char *)buf, n)) == 0); | ||
2006 | |||
2007 | return n; | ||
2008 | } | ||
2009 | |||
2010 | #define safe_read safe_read_strip_cr | ||
2011 | #endif | ||
2012 | |||
1994 | /* read next record from stream rsm into a variable v */ | 2013 | /* read next record from stream rsm into a variable v */ |
1995 | static int awk_getline(rstream *rsm, var *v) | 2014 | static int awk_getline(rstream *rsm, var *v) |
1996 | { | 2015 | { |
@@ -2100,7 +2119,7 @@ static int fmt_num(char *b, int size, const char *format, double n, int int_as_i | |||
2100 | const char *s = format; | 2119 | const char *s = format; |
2101 | 2120 | ||
2102 | if (int_as_int && n == (long long)n) { | 2121 | if (int_as_int && n == (long long)n) { |
2103 | r = snprintf(b, size, "%lld", (long long)n); | 2122 | r = snprintf(b, size, "%"LL_FMT"d", (long long)n); |
2104 | } else { | 2123 | } else { |
2105 | do { c = *s; } while (c && *++s); | 2124 | do { c = *s; } while (c && *++s); |
2106 | if (strchr("diouxX", c)) { | 2125 | if (strchr("diouxX", c)) { |
diff --git a/editors/diff.c b/editors/diff.c index 1462a9b18..cf531460f 100644 --- a/editors/diff.c +++ b/editors/diff.c | |||
@@ -709,6 +709,10 @@ static int diffreg(char *file[2]) | |||
709 | FILE *fp[2]; | 709 | FILE *fp[2]; |
710 | bool binary = false, differ = false; | 710 | bool binary = false, differ = false; |
711 | int status = STATUS_SAME, i; | 711 | int status = STATUS_SAME, i; |
712 | #if ENABLE_PLATFORM_MINGW32 | ||
713 | char *tmpfile[2] = { NULL, NULL }; | ||
714 | char *tmpdir; | ||
715 | #endif | ||
712 | 716 | ||
713 | fp[0] = stdin; | 717 | fp[0] = stdin; |
714 | fp[1] = stdin; | 718 | fp[1] = stdin; |
@@ -730,10 +734,19 @@ static int diffreg(char *file[2]) | |||
730 | * When we meet non-seekable file, we must make a temp copy. | 734 | * When we meet non-seekable file, we must make a temp copy. |
731 | */ | 735 | */ |
732 | if (lseek(fd, 0, SEEK_SET) == -1 && errno == ESPIPE) { | 736 | if (lseek(fd, 0, SEEK_SET) == -1 && errno == ESPIPE) { |
737 | #if !ENABLE_PLATFORM_MINGW32 | ||
733 | char name[] = "/tmp/difXXXXXX"; | 738 | char name[] = "/tmp/difXXXXXX"; |
734 | int fd_tmp = xmkstemp(name); | 739 | int fd_tmp = xmkstemp(name); |
735 | 740 | ||
736 | unlink(name); | 741 | unlink(name); |
742 | #else | ||
743 | int fd_tmp; | ||
744 | |||
745 | if (!(tmpdir=getenv("TMPDIR"))) | ||
746 | goto out; | ||
747 | tmpfile[i] = xasprintf("%s/difXXXXXX", tmpdir); | ||
748 | fd_tmp = xmkstemp(tmpfile[i]); | ||
749 | #endif | ||
737 | if (bb_copyfd_eof(fd, fd_tmp) < 0) | 750 | if (bb_copyfd_eof(fd, fd_tmp) < 0) |
738 | xfunc_die(); | 751 | xfunc_die(); |
739 | if (fd != STDIN_FILENO) | 752 | if (fd != STDIN_FILENO) |
@@ -776,6 +789,14 @@ static int diffreg(char *file[2]) | |||
776 | out: | 789 | out: |
777 | fclose_if_not_stdin(fp[0]); | 790 | fclose_if_not_stdin(fp[0]); |
778 | fclose_if_not_stdin(fp[1]); | 791 | fclose_if_not_stdin(fp[1]); |
792 | #if ENABLE_PLATFORM_MINGW32 | ||
793 | for (i = 0; i < 2; i++) { | ||
794 | if (tmpfile[i]) { | ||
795 | unlink(tmpfile[i]); | ||
796 | free(tmpfile[i]); | ||
797 | } | ||
798 | } | ||
799 | #endif | ||
779 | 800 | ||
780 | return status; | 801 | return status; |
781 | } | 802 | } |
@@ -1019,6 +1040,11 @@ int diff_main(int argc UNUSED_PARAM, char **argv) | |||
1019 | * 255, or if a local inode number (st_ino) exceeds 16777215. | 1040 | * 255, or if a local inode number (st_ino) exceeds 16777215. |
1020 | */ | 1041 | */ |
1021 | if (ENABLE_DESKTOP | 1042 | if (ENABLE_DESKTOP |
1043 | && (ENABLE_PLATFORM_POSIX || ENABLE_FEATURE_EXTRA_FILE_DATA) | ||
1044 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | ||
1045 | /* ignore invalid inode numbers */ | ||
1046 | && stb[0].st_ino != 0 | ||
1047 | #endif | ||
1022 | && stb[0].st_ino == stb[1].st_ino | 1048 | && stb[0].st_ino == stb[1].st_ino |
1023 | && stb[0].st_dev == stb[1].st_dev | 1049 | && stb[0].st_dev == stb[1].st_dev |
1024 | && stb[0].st_size == stb[1].st_size | 1050 | && stb[0].st_size == stb[1].st_size |
diff --git a/editors/sed.c b/editors/sed.c index bb39de149..a5cedbd8d 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -74,6 +74,9 @@ | |||
74 | //usage: "\n Optionally back files up, appending SFX" | 74 | //usage: "\n Optionally back files up, appending SFX" |
75 | //usage: "\n -n Suppress automatic printing of pattern space" | 75 | //usage: "\n -n Suppress automatic printing of pattern space" |
76 | //usage: "\n -r,-E Use extended regex syntax" | 76 | //usage: "\n -r,-E Use extended regex syntax" |
77 | //usage: IF_PLATFORM_MINGW32( | ||
78 | //usage: "\n -b Keep CR/LF (Windows-only)" | ||
79 | //usage: ) | ||
77 | //usage: "\n" | 80 | //usage: "\n" |
78 | //usage: "\nIf no -e or -f, the first non-option argument is the sed command string." | 81 | //usage: "\nIf no -e or -f, the first non-option argument is the sed command string." |
79 | //usage: "\nRemaining arguments are input files (stdin if none)." | 82 | //usage: "\nRemaining arguments are input files (stdin if none)." |
@@ -132,6 +135,9 @@ static const char semicolon_whitespace[] ALIGN1 = "; \n\r\t\v"; | |||
132 | struct globals { | 135 | struct globals { |
133 | /* options */ | 136 | /* options */ |
134 | int be_quiet, regex_type; | 137 | int be_quiet, regex_type; |
138 | #if ENABLE_PLATFORM_MINGW32 | ||
139 | int keep_cr; | ||
140 | #endif | ||
135 | 141 | ||
136 | FILE *nonstdout; | 142 | FILE *nonstdout; |
137 | char *outname, *hold_space; | 143 | char *outname, *hold_space; |
@@ -1024,6 +1030,11 @@ static char *get_next_line(char *gets_char, char *last_puts_char) | |||
1024 | char c = temp[len-1]; | 1030 | char c = temp[len-1]; |
1025 | if (c == '\n' || c == '\0') { | 1031 | if (c == '\n' || c == '\0') { |
1026 | temp[len-1] = '\0'; | 1032 | temp[len-1] = '\0'; |
1033 | #if ENABLE_PLATFORM_MINGW32 | ||
1034 | if (!G.keep_cr && c == '\n' && len > 1 && temp[len-2] == '\r') { | ||
1035 | temp[len-2] = '\0'; | ||
1036 | } | ||
1037 | #endif | ||
1027 | gc = c; | 1038 | gc = c; |
1028 | if (c == '\0') { | 1039 | if (c == '\0') { |
1029 | int ch = fgetc(fp); | 1040 | int ch = fgetc(fp); |
@@ -1498,7 +1509,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1498 | "quiet\0" No_argument "n" | 1509 | "quiet\0" No_argument "n" |
1499 | "silent\0" No_argument "n" | 1510 | "silent\0" No_argument "n" |
1500 | "expression\0" Required_argument "e" | 1511 | "expression\0" Required_argument "e" |
1512 | # if !ENABLE_PLATFORM_MINGW32 | ||
1501 | "file\0" Required_argument "f"; | 1513 | "file\0" Required_argument "f"; |
1514 | # else | ||
1515 | "file\0" Required_argument "f" | ||
1516 | "binary\0" No_argument "b"; | ||
1517 | # endif | ||
1502 | #endif | 1518 | #endif |
1503 | 1519 | ||
1504 | INIT_G(); | 1520 | INIT_G(); |
@@ -1522,6 +1538,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1522 | */ | 1538 | */ |
1523 | opt = getopt32long(argv, "^" | 1539 | opt = getopt32long(argv, "^" |
1524 | "i::rEne:*f:*" | 1540 | "i::rEne:*f:*" |
1541 | IF_PLATFORM_MINGW32("b") | ||
1525 | "\0" "nn"/*count -n*/, | 1542 | "\0" "nn"/*count -n*/, |
1526 | sed_longopts, | 1543 | sed_longopts, |
1527 | &opt_i, &opt_e, &opt_f, | 1544 | &opt_i, &opt_e, &opt_f, |
@@ -1535,6 +1552,10 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1535 | G.regex_type |= REG_EXTENDED; // -r or -E | 1552 | G.regex_type |= REG_EXTENDED; // -r or -E |
1536 | //if (opt & 8) | 1553 | //if (opt & 8) |
1537 | // G.be_quiet++; // -n (implemented with a counter instead) | 1554 | // G.be_quiet++; // -n (implemented with a counter instead) |
1555 | #if ENABLE_PLATFORM_MINGW32 | ||
1556 | if (opt & 0x40) | ||
1557 | G.keep_cr = 1; | ||
1558 | #endif | ||
1538 | while (opt_e) { // -e | 1559 | while (opt_e) { // -e |
1539 | add_cmd_block(llist_pop(&opt_e)); | 1560 | add_cmd_block(llist_pop(&opt_e)); |
1540 | } | 1561 | } |
diff --git a/editors/vi.c b/editors/vi.c index c4360f8d3..a8b4dc5a4 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -349,7 +349,9 @@ struct globals { | |||
349 | #if ENABLE_FEATURE_VI_USE_SIGNALS | 349 | #if ENABLE_FEATURE_VI_USE_SIGNALS |
350 | sigjmp_buf restart; // int_handler() jumps to location remembered here | 350 | sigjmp_buf restart; // int_handler() jumps to location remembered here |
351 | #endif | 351 | #endif |
352 | #if !ENABLE_PLATFORM_MINGW32 | ||
352 | struct termios term_orig; // remember what the cooked mode was | 353 | struct termios term_orig; // remember what the cooked mode was |
354 | #endif | ||
353 | #if ENABLE_FEATURE_VI_COLON | 355 | #if ENABLE_FEATURE_VI_COLON |
354 | char *initial_cmds[3]; // currently 2 entries, NULL terminated | 356 | char *initial_cmds[3]; // currently 2 entries, NULL terminated |
355 | #endif | 357 | #endif |
@@ -545,6 +547,23 @@ static ALWAYS_INLINE int query_screen_dimensions(void) | |||
545 | // sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready) | 547 | // sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready) |
546 | static int mysleep(int hund) | 548 | static int mysleep(int hund) |
547 | { | 549 | { |
550 | #if ENABLE_PLATFORM_MINGW32 | ||
551 | HANDLE h = GetStdHandle(STD_INPUT_HANDLE); | ||
552 | DWORD ret; | ||
553 | |||
554 | if (hund == 0) { | ||
555 | // Allow two events in the queue. Otherwise pasted test isn't | ||
556 | // displayed because there's still a key release event waiting | ||
557 | // after the last character is processed. | ||
558 | DWORD nevent_out; | ||
559 | |||
560 | ret = GetNumberOfConsoleInputEvents(h, &nevent_out); | ||
561 | return ret != 0 ? (nevent_out > 2) : 0; | ||
562 | } | ||
563 | fflush_all(); | ||
564 | ret = WaitForSingleObject(h, hund*10); | ||
565 | return ret != WAIT_TIMEOUT; | ||
566 | #else | ||
548 | struct pollfd pfd[1]; | 567 | struct pollfd pfd[1]; |
549 | 568 | ||
550 | if (hund != 0) | 569 | if (hund != 0) |
@@ -553,9 +572,11 @@ static int mysleep(int hund) | |||
553 | pfd[0].fd = STDIN_FILENO; | 572 | pfd[0].fd = STDIN_FILENO; |
554 | pfd[0].events = POLLIN; | 573 | pfd[0].events = POLLIN; |
555 | return safe_poll(pfd, 1, hund*10) > 0; | 574 | return safe_poll(pfd, 1, hund*10) > 0; |
575 | #endif | ||
556 | } | 576 | } |
557 | 577 | ||
558 | //----- Set terminal attributes -------------------------------- | 578 | //----- Set terminal attributes -------------------------------- |
579 | #if !ENABLE_PLATFORM_MINGW32 | ||
559 | static void rawmode(void) | 580 | static void rawmode(void) |
560 | { | 581 | { |
561 | // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals | 582 | // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals |
@@ -567,6 +588,10 @@ static void cookmode(void) | |||
567 | fflush_all(); | 588 | fflush_all(); |
568 | tcsetattr_stdin_TCSANOW(&term_orig); | 589 | tcsetattr_stdin_TCSANOW(&term_orig); |
569 | } | 590 | } |
591 | #else | ||
592 | #define rawmode() ((void)0) | ||
593 | #define cookmode fflush_all | ||
594 | #endif | ||
570 | 595 | ||
571 | //----- Terminal Drawing --------------------------------------- | 596 | //----- Terminal Drawing --------------------------------------- |
572 | // The terminal is made up of 'rows' line of 'columns' columns. | 597 | // The terminal is made up of 'rows' line of 'columns' columns. |
@@ -1105,7 +1130,11 @@ static char *get_input_line(const char *prompt) | |||
1105 | c = get_one_char(); | 1130 | c = get_one_char(); |
1106 | if (c == '\n' || c == '\r' || c == 27) | 1131 | if (c == '\n' || c == '\r' || c == 27) |
1107 | break; // this is end of input | 1132 | break; // this is end of input |
1133 | #if !ENABLE_PLATFORM_MINGW32 | ||
1108 | if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { | 1134 | if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { |
1135 | #else | ||
1136 | if (c == 8 || c == 127) { | ||
1137 | #endif | ||
1109 | // user wants to erase prev char | 1138 | // user wants to erase prev char |
1110 | buf[--i] = '\0'; | 1139 | buf[--i] = '\0'; |
1111 | write1("\b \b"); // erase char on screen | 1140 | write1("\b \b"); // erase char on screen |
@@ -1858,6 +1887,18 @@ static char *yank_delete(char *start, char *stop, int dist, int yf, int undo) | |||
1858 | return p; | 1887 | return p; |
1859 | } | 1888 | } |
1860 | 1889 | ||
1890 | #if ENABLE_PLATFORM_MINGW32 | ||
1891 | static int count_cr(char *p, int len) | ||
1892 | { | ||
1893 | int i, cnt; | ||
1894 | |||
1895 | for (i = cnt = 0; i < len; ++i) | ||
1896 | if (p[i] == '\n') | ||
1897 | ++cnt; | ||
1898 | return cnt; | ||
1899 | } | ||
1900 | #endif | ||
1901 | |||
1861 | // might reallocate text[]! | 1902 | // might reallocate text[]! |
1862 | static int file_insert(const char *fn, char *p, int initial) | 1903 | static int file_insert(const char *fn, char *p, int initial) |
1863 | { | 1904 | { |
@@ -1870,7 +1911,11 @@ static int file_insert(const char *fn, char *p, int initial) | |||
1870 | if (p > end) | 1911 | if (p > end) |
1871 | p = end; | 1912 | p = end; |
1872 | 1913 | ||
1914 | #if !ENABLE_PLATFORM_MINGW32 | ||
1873 | fd = open(fn, O_RDONLY); | 1915 | fd = open(fn, O_RDONLY); |
1916 | #else | ||
1917 | fd = open(fn, O_RDONLY | _O_TEXT); | ||
1918 | #endif | ||
1874 | if (fd < 0) { | 1919 | if (fd < 0) { |
1875 | if (!initial) | 1920 | if (!initial) |
1876 | status_line_bold_errno(fn); | 1921 | status_line_bold_errno(fn); |
@@ -1893,8 +1938,15 @@ static int file_insert(const char *fn, char *p, int initial) | |||
1893 | status_line_bold_errno(fn); | 1938 | status_line_bold_errno(fn); |
1894 | p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert | 1939 | p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert |
1895 | } else if (cnt < size) { | 1940 | } else if (cnt < size) { |
1941 | #if ENABLE_PLATFORM_MINGW32 | ||
1942 | // On WIN32 a partial read might just mean CRs have been removed | ||
1943 | int cnt_cr = cnt + count_cr(p, cnt); | ||
1944 | #endif | ||
1896 | // There was a partial read, shrink unused space | 1945 | // There was a partial read, shrink unused space |
1897 | p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO); | 1946 | p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO); |
1947 | #if ENABLE_PLATFORM_MINGW32 | ||
1948 | if (cnt_cr < size) | ||
1949 | #endif | ||
1898 | status_line_bold("can't read '%s'", fn); | 1950 | status_line_bold("can't read '%s'", fn); |
1899 | } | 1951 | } |
1900 | fi: | 1952 | fi: |
@@ -2001,7 +2053,11 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2001 | if ((p[-1] != '\n') && (dot > text)) { | 2053 | if ((p[-1] != '\n') && (dot > text)) { |
2002 | p--; | 2054 | p--; |
2003 | } | 2055 | } |
2056 | #if !ENABLE_PLATFORM_MINGW32 | ||
2004 | } else if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { // Is this a BS | 2057 | } else if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { // Is this a BS |
2058 | #else | ||
2059 | } else if (c == 8 || c == 127) { // Is this a BS | ||
2060 | #endif | ||
2005 | if (p > text) { | 2061 | if (p > text) { |
2006 | p--; | 2062 | p--; |
2007 | p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char | 2063 | p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char |
@@ -2122,12 +2178,22 @@ static int file_write(char *fn, char *first, char *last) | |||
2122 | // By popular request we do not open file with O_TRUNC, | 2178 | // By popular request we do not open file with O_TRUNC, |
2123 | // but instead ftruncate() it _after_ successful write. | 2179 | // but instead ftruncate() it _after_ successful write. |
2124 | // Might reduce amount of data lost on power fail etc. | 2180 | // Might reduce amount of data lost on power fail etc. |
2181 | #if !ENABLE_PLATFORM_MINGW32 | ||
2125 | fd = open(fn, (O_WRONLY | O_CREAT), 0666); | 2182 | fd = open(fn, (O_WRONLY | O_CREAT), 0666); |
2183 | #else | ||
2184 | fd = open(fn, (O_WRONLY | O_CREAT | _O_TEXT), 0666); | ||
2185 | #endif | ||
2126 | if (fd < 0) | 2186 | if (fd < 0) |
2127 | return -1; | 2187 | return -1; |
2128 | cnt = last - first + 1; | 2188 | cnt = last - first + 1; |
2129 | charcnt = full_write(fd, first, cnt); | 2189 | charcnt = full_write(fd, first, cnt); |
2190 | #if !ENABLE_PLATFORM_MINGW32 | ||
2130 | ftruncate(fd, charcnt); | 2191 | ftruncate(fd, charcnt); |
2192 | #else | ||
2193 | // File was written in text mode; this makes it bigger so adjust | ||
2194 | // the truncation to match. | ||
2195 | ftruncate(fd, charcnt + count_cr(first, cnt)); | ||
2196 | #endif | ||
2131 | if (charcnt == cnt) { | 2197 | if (charcnt == cnt) { |
2132 | // good write | 2198 | // good write |
2133 | //modified_count = FALSE; | 2199 | //modified_count = FALSE; |