X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Flineedit.c;h=0563e6d011599e6dbf08f4e13579e3b1cee3cdac;hb=0bfb9c2cf0e8b711634014e06d39b5f47c5a95c2;hp=5dd835ccad95bc4858d79a5a779bdaa44a265a16;hpb=f3763033e457b100a863731c16a80648d85995c9;p=oweals%2Fbusybox.git diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5dd835cca..0563e6d01 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -204,65 +204,82 @@ static void deinit_S(void) #if ENABLE_UNICODE_SUPPORT static size_t load_string(const char *src, int maxsize) { - ssize_t len = mbstowcs(command_ps, src, maxsize - 1); - if (len < 0) - len = 0; - command_ps[len] = BB_NUL; - return len; + if (unicode_status == UNICODE_ON) { + ssize_t len = mbstowcs(command_ps, src, maxsize - 1); + if (len < 0) + len = 0; + command_ps[len] = BB_NUL; + return len; + } else { + unsigned i = 0; + while ((command_ps[i] = src[i]) != 0) + i++; + return i; + } } static unsigned save_string(char *dst, unsigned maxsize) { + if (unicode_status == UNICODE_ON) { # if !ENABLE_UNICODE_PRESERVE_BROKEN - ssize_t len = wcstombs(dst, command_ps, maxsize - 1); - if (len < 0) - len = 0; - dst[len] = '\0'; - return len; + ssize_t len = wcstombs(dst, command_ps, maxsize - 1); + if (len < 0) + len = 0; + dst[len] = '\0'; + return len; # else - unsigned dstpos = 0; - unsigned srcpos = 0; + unsigned dstpos = 0; + unsigned srcpos = 0; - maxsize--; - while (dstpos < maxsize) { - wchar_t wc; - int n = srcpos; + maxsize--; + while (dstpos < maxsize) { + wchar_t wc; + int n = srcpos; - /* Convert up to 1st invalid byte (or up to end) */ - while ((wc = command_ps[srcpos]) != BB_NUL - && !unicode_is_raw_byte(wc) - ) { + /* Convert up to 1st invalid byte (or up to end) */ + while ((wc = command_ps[srcpos]) != BB_NUL + && !unicode_is_raw_byte(wc) + ) { + srcpos++; + } + command_ps[srcpos] = BB_NUL; + n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); + if (n < 0) /* should not happen */ + break; + dstpos += n; + if (wc == BB_NUL) /* usually is */ + break; + + /* We do have invalid byte here! */ + command_ps[srcpos] = wc; /* restore it */ srcpos++; + if (dstpos == maxsize) + break; + dst[dstpos++] = (char) wc; } - command_ps[srcpos] = BB_NUL; - n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); - if (n < 0) /* should not happen */ - break; - dstpos += n; - if (wc == BB_NUL) /* usually is */ - break; - - /* We do have invalid byte here! */ - command_ps[srcpos] = wc; /* restore it */ - srcpos++; - if (dstpos == maxsize) - break; - dst[dstpos++] = (char) wc; - } - dst[dstpos] = '\0'; - return dstpos; + dst[dstpos] = '\0'; + return dstpos; # endif + } else { + unsigned i = 0; + while ((dst[i] = command_ps[i]) != 0) + i++; + return i; + } } /* I thought just fputwc(c, stdout) would work. But no... */ static void BB_PUTCHAR(wchar_t c) { - char buf[MB_CUR_MAX + 1]; - mbstate_t mbst = { 0 }; - ssize_t len; - - len = wcrtomb(buf, c, &mbst); - if (len > 0) { - buf[len] = '\0'; - fputs(buf, stdout); + if (unicode_status == UNICODE_ON) { + char buf[MB_CUR_MAX + 1]; + mbstate_t mbst = { 0 }; + ssize_t len = wcrtomb(buf, c, &mbst); + if (len > 0) { + buf[len] = '\0'; + fputs(buf, stdout); + } + } else { + /* In this case, c is always one byte */ + putchar(c); } } # if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS @@ -1226,12 +1243,26 @@ line_input_t* FAST_FUNC new_line_input_t(int flags) { line_input_t *n = xzalloc(sizeof(*n)); n->flags = flags; + n->max_history = MAX_HISTORY; return n; } #if MAX_HISTORY > 0 +unsigned size_from_HISTFILESIZE(const char *hp) +{ + int size = MAX_HISTORY; + if (hp) { + size = atoi(hp); + if (size <= 0) + return 1; + if (size > MAX_HISTORY) + return MAX_HISTORY; + } + return size; +} + static void save_command_ps_at_cur_history(void) { if (command_ps[0] != BB_NUL) { @@ -1322,7 +1353,7 @@ static void load_history(line_input_t *st_parm) temp_h[idx] = line; st_parm->cnt_history_in_file++; idx++; - if (idx == MAX_HISTORY) + if (idx == st_parm->max_history) idx = 0; } fclose(fp); @@ -1331,18 +1362,18 @@ static void load_history(line_input_t *st_parm) if (st_parm->cnt_history_in_file) { while (temp_h[idx] == NULL) { idx++; - if (idx == MAX_HISTORY) + if (idx == st_parm->max_history) idx = 0; } } /* copy temp_h[] to st_parm->history[] */ - for (i = 0; i < MAX_HISTORY;) { + for (i = 0; i < st_parm->max_history;) { line = temp_h[idx]; if (!line) break; idx++; - if (idx == MAX_HISTORY) + if (idx == st_parm->max_history) idx = 0; line_len = strlen(line); if (line_len >= MAX_LINELEN) @@ -1373,7 +1404,7 @@ static void save_history(char *str) /* did we write so much that history file needs trimming? */ state->cnt_history_in_file++; - if (state->cnt_history_in_file > MAX_HISTORY * 4) { + if (state->cnt_history_in_file > state->max_history * 4) { char *new_name; line_input_t *st_temp; @@ -1381,6 +1412,7 @@ static void save_history(char *str) * load them */ st_temp = new_line_input_t(state->flags); st_temp->hist_file = state->hist_file; + st_temp->max_history = state->max_history; load_history(st_temp); /* write out temp file and replace hist_file atomically */ @@ -1419,20 +1451,20 @@ static void remember_in_history(char *str) if (i && strcmp(state->history[i-1], str) == 0) return; - free(state->history[MAX_HISTORY]); /* redundant, paranoia */ - state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */ + free(state->history[state->max_history]); /* redundant, paranoia */ + state->history[state->max_history] = NULL; /* redundant, paranoia */ /* If history[] is full, remove the oldest command */ - /* we need to keep history[MAX_HISTORY] empty, hence >=, not > */ - if (i >= MAX_HISTORY) { + /* we need to keep history[state->max_history] empty, hence >=, not > */ + if (i >= state->max_history) { free(state->history[0]); - for (i = 0; i < MAX_HISTORY-1; i++) + for (i = 0; i < state->max_history-1; i++) state->history[i] = state->history[i+1]; - /* i == MAX_HISTORY-1 */ + /* i == state->max_history-1 */ } - /* i <= MAX_HISTORY-1 */ + /* i <= state->max_history-1 */ state->history[i++] = xstrdup(str); - /* i <= MAX_HISTORY */ + /* i <= state->max_history */ state->cur_history = i; state->cnt_history = i; # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY @@ -1809,10 +1841,9 @@ static void win_changed(int nsig) errno = sv_errno; } -static int lineedit_read_key(char *read_key_buffer) +static int lineedit_read_key(char *read_key_buffer, int timeout) { int64_t ic; - int timeout = -1; #if ENABLE_UNICODE_SUPPORT char unicode_buf[MB_CUR_MAX + 1]; int unicode_idx = 0; @@ -1917,7 +1948,7 @@ static int isrtl_str(void) * 0 on ctrl-C (the line entered is still returned in 'command'), * >0 length of input string, including terminating '\n' */ -int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, line_input_t *st) +int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) { int len; #if ENABLE_FEATURE_TAB_COMPLETION @@ -1954,7 +1985,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li maxsize = MAX_LINELEN; S.maxsize = maxsize; - /* With null flags, no other fields are ever used */ + /* With zero flags, no other fields are ever used */ state = st ? st : (line_input_t*) &const_int_0; #if MAX_HISTORY > 0 # if ENABLE_FEATURE_EDITING_SAVEHISTORY @@ -1991,7 +2022,6 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li new_settings.c_cc[VINTR] = _POSIX_VDISABLE; tcsetattr_stdin_TCSANOW(&new_settings); - /* Now initialize things */ previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); win_changed(0); /* do initial resizing */ #if ENABLE_USERNAME_OR_HOMEDIR @@ -2007,7 +2037,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li #endif #if 0 - for (i = 0; i <= MAX_HISTORY; i++) + for (i = 0; i <= state->max_history; i++) bb_error_msg("history[%d]:'%s'", i, state->history[i]); bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history); #endif @@ -2033,7 +2063,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li int32_t ic, ic_raw; fflush_all(); - ic = ic_raw = lineedit_read_key(read_key_buffer); + ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); #if ENABLE_FEATURE_EDITING_VI newdelflag = 1; @@ -2194,7 +2224,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li case 'd'|VI_CMDMODE_BIT: { int nc, sc; - ic = lineedit_read_key(read_key_buffer); + ic = lineedit_read_key(read_key_buffer, timeout); if (errno) /* error */ goto return_error_indicator; if (ic == ic_raw) { /* "cc", "dd" */ @@ -2258,7 +2288,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li break; case 'r'|VI_CMDMODE_BIT: //FIXME: unicode case? - ic = lineedit_read_key(read_key_buffer); + ic = lineedit_read_key(read_key_buffer, timeout); if (errno) /* error */ goto return_error_indicator; if (ic < ' ' || ic > 255) {