aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbb/lineedit.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index a99f9b5fd..cb675f230 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -685,29 +685,34 @@ static void exe_n_cwd_tab_completion(char *command, int type)
#undef dirbuf
}
-//FIXME: HUH??? How about Unicode?
+/* QUOT is used on elements of int_buf[], which are bytes,
+ * not Unicode chars. Therefore it works correctly even in Unicode mode.
+ */
#define QUOT (UCHAR_MAX+1)
-#define collapse_pos(is, in) do { \
- memmove(int_buf+(is), int_buf+(in), (MAX_LINELEN+1-(is)-(in)) * sizeof(pos_buf[0])); \
- memmove(pos_buf+(is), pos_buf+(in), (MAX_LINELEN+1-(is)-(in)) * sizeof(pos_buf[0])); \
-} while (0)
+#define int_buf (S.find_match__int_buf)
+#define pos_buf (S.find_match__pos_buf)
+
+static void collapse_pos(int is, int in)
+{
+ memmove(int_buf+is, int_buf+in, (MAX_LINELEN+1 - is - in) * sizeof(int_buf[0]));
+ memmove(pos_buf+is, pos_buf+in, (MAX_LINELEN+1 - is - in) * sizeof(pos_buf[0]));
+}
static NOINLINE int find_match(char *matchBuf, int *len_with_quotes)
{
int i, j;
int command_mode;
int c, c2;
+/* Were local, but it uses too much stack */
/* int16_t int_buf[MAX_LINELEN + 1]; */
/* int16_t pos_buf[MAX_LINELEN + 1]; */
-#define int_buf (S.find_match__int_buf)
-#define pos_buf (S.find_match__pos_buf)
/* set to integer dimension characters and own positions */
for (i = 0;; i++) {
int_buf[i] = (unsigned char)matchBuf[i];
if (int_buf[i] == 0) {
- pos_buf[i] = -1; /* indicator end line */
+ pos_buf[i] = -1; /* end-fo-line indicator */
break;
}
pos_buf[i] = i;
@@ -720,7 +725,7 @@ static NOINLINE int find_match(char *matchBuf, int *len_with_quotes)
int_buf[j] |= QUOT;
i++;
#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
- if (matchBuf[i] == '\t') /* algorithm equivalent */
+ if (matchBuf[i] == '\t') /* algorithm equivalent */
int_buf[j] = ' ' | QUOT;
#endif
}
@@ -763,11 +768,11 @@ static NOINLINE int find_match(char *matchBuf, int *len_with_quotes)
}
if (command_mode) {
collapse_pos(0, i + command_mode);
- i = -1; /* hack incremet */
+ i = -1; /* hack incremet */
}
}
/* collapse `command...` */
- for (i = 0; int_buf[i]; i++)
+ for (i = 0; int_buf[i]; i++) {
if (int_buf[i] == '`') {
for (j = i + 1; int_buf[j]; j++)
if (int_buf[j] == '`') {
@@ -776,34 +781,37 @@ static NOINLINE int find_match(char *matchBuf, int *len_with_quotes)
break;
}
if (j) {
- /* not found close ` - command mode, collapse all previous */
+ /* not found closing ` - command mode, collapse all previous */
collapse_pos(0, i + 1);
break;
} else
- i--; /* hack incremet */
+ i--; /* hack incremet */
}
+ }
/* collapse (command...(command...)...) or {command...{command...}...} */
- c = 0; /* "recursive" level */
+ c = 0; /* "recursive" level */
c2 = 0;
- for (i = 0; int_buf[i]; i++)
+ for (i = 0; int_buf[i]; i++) {
if (int_buf[i] == '(' || int_buf[i] == '{') {
if (int_buf[i] == '(')
c++;
else
c2++;
collapse_pos(0, i + 1);
- i = -1; /* hack incremet */
+ i = -1; /* hack incremet */
}
- for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++)
+ }
+ for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++) {
if ((int_buf[i] == ')' && c > 0) || (int_buf[i] == '}' && c2 > 0)) {
if (int_buf[i] == ')')
c--;
else
c2--;
collapse_pos(0, i + 1);
- i = -1; /* hack incremet */
+ i = -1; /* hack incremet */
}
+ }
/* skip first not quote space */
for (i = 0; int_buf[i]; i++)
@@ -814,7 +822,7 @@ static NOINLINE int find_match(char *matchBuf, int *len_with_quotes)
/* set find mode for completion */
command_mode = FIND_EXE_ONLY;
- for (i = 0; int_buf[i]; i++)
+ for (i = 0; int_buf[i]; i++) {
if (int_buf[i] == ' ' || int_buf[i] == '<' || int_buf[i] == '>') {
if (int_buf[i] == ' ' && command_mode == FIND_EXE_ONLY
&& matchBuf[pos_buf[0]] == 'c'
@@ -826,6 +834,7 @@ static NOINLINE int find_match(char *matchBuf, int *len_with_quotes)
break;
}
}
+ }
for (i = 0; int_buf[i]; i++)
/* "strlen" */;
/* find last word */
@@ -873,9 +882,9 @@ static void showfiles(void)
int nrows = nfiles;
int l;
- /* find the longest file name- use that as the column width */
+ /* find the longest file name - use that as the column width */
for (row = 0; row < nrows; row++) {
- l = strlen(matches[row]);
+ l = bb_mbstrlen(matches[row]);
if (column_width < l)
column_width = l;
}
@@ -895,7 +904,8 @@ static void showfiles(void)
for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) {
printf("%s%-*s", matches[n],
- (int)(column_width - strlen(matches[n])), "");
+ (int)(column_width - bb_mbstrlen(matches[n])), ""
+ );
}
puts(matches[n]);
}
@@ -904,14 +914,14 @@ static void showfiles(void)
static char *add_quote_for_spec_chars(char *found)
{
int l = 0;
- char *s = xmalloc((strlen(found) + 1) * 2);
+ char *s = xzalloc((strlen(found) + 1) * 2);
while (*found) {
if (strchr(" `\"#$%^&*()=+{}[]:;\'|\\<>", *found))
s[l++] = '\\';
s[l++] = *found++;
}
- s[l] = 0;
+ /* s[l] = '\0'; - already is */
return s;
}