diff options
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r-- | libbb/lineedit.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b1e971f88..19b579782 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -356,7 +356,7 @@ int adjust_width_and_validate_wc(unsigned *width_adj, int wc); | |||
356 | /* Put 'command_ps[cursor]', cursor++. | 356 | /* Put 'command_ps[cursor]', cursor++. |
357 | * Advance cursor on screen. If we reached right margin, scroll text up | 357 | * Advance cursor on screen. If we reached right margin, scroll text up |
358 | * and remove terminal margin effect by printing 'next_char' */ | 358 | * and remove terminal margin effect by printing 'next_char' */ |
359 | #define HACK_FOR_WRONG_WIDTH 1 | 359 | #define HACK_FOR_WRONG_WIDTH 1 && !ENABLE_PLATFORM_MINGW32 |
360 | static void put_cur_glyph_and_inc_cursor(void) | 360 | static void put_cur_glyph_and_inc_cursor(void) |
361 | { | 361 | { |
362 | CHAR_T c = command_ps[cursor]; | 362 | CHAR_T c = command_ps[cursor]; |
@@ -419,6 +419,42 @@ static void put_cur_glyph_and_inc_cursor(void) | |||
419 | } | 419 | } |
420 | } | 420 | } |
421 | 421 | ||
422 | #if ENABLE_PLATFORM_MINGW32 | ||
423 | static void inc_cursor(void) | ||
424 | { | ||
425 | CHAR_T c = command_ps[cursor]; | ||
426 | unsigned width = 0; | ||
427 | int ofs_to_right; | ||
428 | |||
429 | /* advance cursor */ | ||
430 | cursor++; | ||
431 | if (unicode_status == UNICODE_ON) { | ||
432 | IF_UNICODE_WIDE_WCHARS(width = cmdedit_x;) | ||
433 | c = adjust_width_and_validate_wc(&cmdedit_x, c); | ||
434 | IF_UNICODE_WIDE_WCHARS(width = cmdedit_x - width;) | ||
435 | } else { | ||
436 | cmdedit_x++; | ||
437 | } | ||
438 | |||
439 | ofs_to_right = cmdedit_x - cmdedit_termw; | ||
440 | if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right <= 0) { | ||
441 | /* cursor remains on this line */ | ||
442 | printf(ESC"[1C"); | ||
443 | } | ||
444 | |||
445 | if (ofs_to_right >= 0) { | ||
446 | /* we go to the next line */ | ||
447 | printf(ESC"[1B"); | ||
448 | bb_putchar('\r'); | ||
449 | cmdedit_y++; | ||
450 | if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) { | ||
451 | width = 0; | ||
452 | } | ||
453 | cmdedit_x = width; | ||
454 | } | ||
455 | } | ||
456 | #endif | ||
457 | |||
422 | /* Move to end of line (by printing all chars till the end) */ | 458 | /* Move to end of line (by printing all chars till the end) */ |
423 | static void put_till_end_and_adv_cursor(void) | 459 | static void put_till_end_and_adv_cursor(void) |
424 | { | 460 | { |
@@ -478,6 +514,7 @@ static void input_backward(unsigned num) | |||
478 | 514 | ||
479 | if (cmdedit_x >= num) { | 515 | if (cmdedit_x >= num) { |
480 | cmdedit_x -= num; | 516 | cmdedit_x -= num; |
517 | #if !ENABLE_PLATFORM_MINGW32 | ||
481 | if (num <= 4) { | 518 | if (num <= 4) { |
482 | /* This is longer by 5 bytes on x86. | 519 | /* This is longer by 5 bytes on x86. |
483 | * Also gets miscompiled for ARM users | 520 | * Also gets miscompiled for ARM users |
@@ -490,6 +527,7 @@ static void input_backward(unsigned num) | |||
490 | } while (--num); | 527 | } while (--num); |
491 | return; | 528 | return; |
492 | } | 529 | } |
530 | #endif | ||
493 | printf(ESC"[%uD", num); | 531 | printf(ESC"[%uD", num); |
494 | return; | 532 | return; |
495 | } | 533 | } |
@@ -628,7 +666,11 @@ static void input_backspace(void) | |||
628 | static void input_forward(void) | 666 | static void input_forward(void) |
629 | { | 667 | { |
630 | if (cursor < command_len) | 668 | if (cursor < command_len) |
669 | #if !ENABLE_PLATFORM_MINGW32 | ||
631 | put_cur_glyph_and_inc_cursor(); | 670 | put_cur_glyph_and_inc_cursor(); |
671 | #else | ||
672 | inc_cursor(); | ||
673 | #endif | ||
632 | } | 674 | } |
633 | 675 | ||
634 | #if ENABLE_FEATURE_TAB_COMPLETION | 676 | #if ENABLE_FEATURE_TAB_COMPLETION |
@@ -748,7 +790,11 @@ static int path_parse(char ***p) | |||
748 | tmp = (char*)pth; | 790 | tmp = (char*)pth; |
749 | npth = 1; /* path component count */ | 791 | npth = 1; /* path component count */ |
750 | while (1) { | 792 | while (1) { |
793 | #if ENABLE_PLATFORM_MINGW32 | ||
794 | tmp = (char *)next_path_sep(tmp); | ||
795 | #else | ||
751 | tmp = strchr(tmp, ':'); | 796 | tmp = strchr(tmp, ':'); |
797 | #endif | ||
752 | if (!tmp) | 798 | if (!tmp) |
753 | break; | 799 | break; |
754 | tmp++; | 800 | tmp++; |
@@ -761,7 +807,11 @@ static int path_parse(char ***p) | |||
761 | res[0] = tmp = xstrdup(pth); | 807 | res[0] = tmp = xstrdup(pth); |
762 | npth = 1; | 808 | npth = 1; |
763 | while (1) { | 809 | while (1) { |
810 | #if ENABLE_PLATFORM_MINGW32 | ||
811 | tmp = (char *)next_path_sep(tmp); | ||
812 | #else | ||
764 | tmp = strchr(tmp, ':'); | 813 | tmp = strchr(tmp, ':'); |
814 | #endif | ||
765 | if (!tmp) | 815 | if (!tmp) |
766 | break; | 816 | break; |
767 | *tmp++ = '\0'; /* ':' -> '\0' */ | 817 | *tmp++ = '\0'; /* ':' -> '\0' */ |
@@ -847,6 +897,9 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
847 | if (stat(found, &st) && lstat(found, &st)) | 897 | if (stat(found, &st) && lstat(found, &st)) |
848 | goto cont; /* hmm, remove in progress? */ | 898 | goto cont; /* hmm, remove in progress? */ |
849 | 899 | ||
900 | if (type == FIND_EXE_ONLY && !file_is_executable(found)) | ||
901 | goto cont; | ||
902 | |||
850 | /* Save only name */ | 903 | /* Save only name */ |
851 | len = strlen(name_found); | 904 | len = strlen(name_found); |
852 | found = xrealloc(found, len + 2); /* +2: for slash and NUL */ | 905 | found = xrealloc(found, len + 2); /* +2: for slash and NUL */ |
@@ -1952,7 +2005,16 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1952 | char *after_home_user; | 2005 | char *after_home_user; |
1953 | 2006 | ||
1954 | /* /home/user[/something] -> ~[/something] */ | 2007 | /* /home/user[/something] -> ~[/something] */ |
2008 | #if !ENABLE_PLATFORM_MINGW32 | ||
1955 | after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf); | 2009 | after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf); |
2010 | #else | ||
2011 | after_home_user = NULL; | ||
2012 | l = strlen(home_pwd_buf); | ||
2013 | if (l != 0 | ||
2014 | && strncasecmp(home_pwd_buf, cwd_buf, l) == 0) { | ||
2015 | after_home_user = cwd_buf + l; | ||
2016 | } | ||
2017 | #endif | ||
1956 | if (after_home_user | 2018 | if (after_home_user |
1957 | && (*after_home_user == '/' || *after_home_user == '\0') | 2019 | && (*after_home_user == '/' || *after_home_user == '\0') |
1958 | ) { | 2020 | ) { |
@@ -2318,7 +2380,7 @@ static int32_t reverse_i_search(int timeout) | |||
2318 | */ | 2380 | */ |
2319 | int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) | 2381 | int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) |
2320 | { | 2382 | { |
2321 | int len, n; | 2383 | int len IF_NOT_PLATFORM_MINGW32(, n); |
2322 | int timeout; | 2384 | int timeout; |
2323 | #if ENABLE_FEATURE_TAB_COMPLETION | 2385 | #if ENABLE_FEATURE_TAB_COMPLETION |
2324 | smallint lastWasTab = 0; | 2386 | smallint lastWasTab = 0; |
@@ -2328,15 +2390,23 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2328 | smallint vi_cmdmode = 0; | 2390 | smallint vi_cmdmode = 0; |
2329 | #endif | 2391 | #endif |
2330 | struct termios initial_settings; | 2392 | struct termios initial_settings; |
2393 | #if !ENABLE_PLATFORM_MINGW32 | ||
2331 | struct termios new_settings; | 2394 | struct termios new_settings; |
2395 | #endif | ||
2332 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; | 2396 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; |
2333 | 2397 | ||
2334 | INIT_S(); | 2398 | INIT_S(); |
2335 | 2399 | ||
2400 | #if !ENABLE_PLATFORM_MINGW32 | ||
2336 | n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 | 2401 | n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 |
2337 | | TERMIOS_CLEAR_ISIG /* turn off INTR (ctrl-C), QUIT, SUSP */ | 2402 | | TERMIOS_CLEAR_ISIG /* turn off INTR (ctrl-C), QUIT, SUSP */ |
2338 | ); | 2403 | ); |
2339 | if (n != 0 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON) { | 2404 | if (n != 0 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON) { |
2405 | #else | ||
2406 | initial_settings.c_cc[VINTR] = CTRL('C'); | ||
2407 | initial_settings.c_cc[VEOF] = CTRL('D'); | ||
2408 | if (!isatty(0) || !isatty(1)) { | ||
2409 | #endif | ||
2340 | /* Happens when e.g. stty -echo was run before. | 2410 | /* Happens when e.g. stty -echo was run before. |
2341 | * But if ICANON is not set, we don't come here. | 2411 | * But if ICANON is not set, we don't come here. |
2342 | * (example: interactive python ^Z-backgrounded, | 2412 | * (example: interactive python ^Z-backgrounded, |
@@ -2389,7 +2459,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2389 | #endif | 2459 | #endif |
2390 | #define command command_must_not_be_used | 2460 | #define command command_must_not_be_used |
2391 | 2461 | ||
2462 | #if !ENABLE_PLATFORM_MINGW32 | ||
2392 | tcsetattr_stdin_TCSANOW(&new_settings); | 2463 | tcsetattr_stdin_TCSANOW(&new_settings); |
2464 | #endif | ||
2393 | 2465 | ||
2394 | #if ENABLE_USERNAME_OR_HOMEDIR | 2466 | #if ENABLE_USERNAME_OR_HOMEDIR |
2395 | { | 2467 | { |
@@ -2442,6 +2514,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2442 | } | 2514 | } |
2443 | #endif | 2515 | #endif |
2444 | ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); | 2516 | ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); |
2517 | #if ENABLE_PLATFORM_MINGW32 | ||
2518 | /* scroll to cursor position on any keypress */ | ||
2519 | if (isatty(fileno(stdin)) && isatty(fileno(stdout))) | ||
2520 | move_cursor_row(0); | ||
2521 | #endif | ||
2445 | 2522 | ||
2446 | #if ENABLE_FEATURE_REVERSE_SEARCH | 2523 | #if ENABLE_FEATURE_REVERSE_SEARCH |
2447 | again: | 2524 | again: |
@@ -2875,8 +2952,10 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2875 | free_tab_completion_data(); | 2952 | free_tab_completion_data(); |
2876 | #endif | 2953 | #endif |
2877 | 2954 | ||
2955 | #if !ENABLE_PLATFORM_MINGW32 | ||
2878 | /* restore initial_settings */ | 2956 | /* restore initial_settings */ |
2879 | tcsetattr_stdin_TCSANOW(&initial_settings); | 2957 | tcsetattr_stdin_TCSANOW(&initial_settings); |
2958 | #endif | ||
2880 | #if ENABLE_FEATURE_EDITING_WINCH | 2959 | #if ENABLE_FEATURE_EDITING_WINCH |
2881 | /* restore SIGWINCH handler */ | 2960 | /* restore SIGWINCH handler */ |
2882 | sigaction_set(SIGWINCH, &S.SIGWINCH_handler); | 2961 | sigaction_set(SIGWINCH, &S.SIGWINCH_handler); |