lineedit: stop using permanent int_buf[] (16k!): allocate it

Now it is allocated temporarily only for the duretion of prefix generation,
and also we only allocate the needed size, not maximally possible.

function                                             old     new   delta
build_match_prefix                                   579     590     +11
remove_chunk                                          43      28     -15
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 11/-15)             Total: -4 bytes

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
Denys Vlasenko 2010-09-03 13:02:47 +02:00
parent 81254ed387
commit 9b56bf5416

View File

@ -154,7 +154,6 @@ struct lineedit_statics {
/* Formerly these were big buffers on stack: */ /* Formerly these were big buffers on stack: */
#if ENABLE_FEATURE_TAB_COMPLETION #if ENABLE_FEATURE_TAB_COMPLETION
char input_tab__matchBuf[MAX_LINELEN]; char input_tab__matchBuf[MAX_LINELEN];
int16_t find_match__int_buf[MAX_LINELEN + 1]; /* need to have 9 bits at least */
#endif #endif
}; };
@ -821,9 +820,8 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
* not Unicode chars. Therefore it works correctly even in Unicode mode. * not Unicode chars. Therefore it works correctly even in Unicode mode.
*/ */
#define QUOT (UCHAR_MAX+1) #define QUOT (UCHAR_MAX+1)
#define int_buf (S.find_match__int_buf)
#define dbg_bmp 0 #define dbg_bmp 0
static void remove_chunk(int beg, int end) static void remove_chunk(int16_t *int_buf, int beg, int end)
{ {
/* beg must be <= end */ /* beg must be <= end */
if (beg == end) if (beg == end)
@ -843,11 +841,11 @@ static NOINLINE int build_match_prefix(char *matchBuf)
{ {
int i, j; int i, j;
int command_mode; int command_mode;
/* Were local, but it used too much stack */ int16_t *int_buf;
/* int16_t int_buf[MAX_LINELEN + 1]; */
if (dbg_bmp) printf("\n%s\n", matchBuf); if (dbg_bmp) printf("\n%s\n", matchBuf);
int_buf = xmalloc(sizeof(int_buf[0]) * (strlen(matchBuf) + 1));
i = 0; i = 0;
while ((int_buf[i] = (unsigned char)matchBuf[i]) != '\0') while ((int_buf[i] = (unsigned char)matchBuf[i]) != '\0')
i++; i++;
@ -855,7 +853,7 @@ static NOINLINE int build_match_prefix(char *matchBuf)
/* Mark every \c as "quoted c" */ /* Mark every \c as "quoted c" */
for (i = j = 0; matchBuf[i]; i++, j++) { for (i = j = 0; matchBuf[i]; i++, j++) {
if (matchBuf[i] == '\\') { if (matchBuf[i] == '\\') {
remove_chunk(j, j + 1); remove_chunk(int_buf, j, j + 1);
int_buf[j] |= QUOT; int_buf[j] |= QUOT;
i++; i++;
} }
@ -871,7 +869,7 @@ static NOINLINE int build_match_prefix(char *matchBuf)
if (cur == '\'' || cur == '"') { if (cur == '\'' || cur == '"') {
if (!in_quote || (cur == in_quote)) { if (!in_quote || (cur == in_quote)) {
in_quote ^= cur; in_quote ^= cur;
remove_chunk(i, i + 1); remove_chunk(int_buf, i, i + 1);
continue; continue;
} }
} }
@ -894,7 +892,7 @@ static NOINLINE int build_match_prefix(char *matchBuf)
} else if (cur == '|' && prev == '>') { } else if (cur == '|' && prev == '>') {
continue; continue;
} }
remove_chunk(0, i + 1 + (cur == int_buf[i + 1])); remove_chunk(int_buf, 0, i + 1 + (cur == int_buf[i + 1]));
i = -1; /* back to square 1 */ i = -1; /* back to square 1 */
} }
} }
@ -908,12 +906,12 @@ static NOINLINE int build_match_prefix(char *matchBuf)
* not commands c*. Therefore we don't drop * not commands c*. Therefore we don't drop
* `cmd` entirely, we replace it with single `. * `cmd` entirely, we replace it with single `.
*/ */
remove_chunk(i, j); remove_chunk(int_buf, i, j);
goto next; goto next;
} }
} }
/* No closing ` - command mode, remove all up to ` */ /* No closing ` - command mode, remove all up to ` */
remove_chunk(0, i + 1); remove_chunk(int_buf, 0, i + 1);
break; break;
next: ; next: ;
} }
@ -925,7 +923,7 @@ static NOINLINE int build_match_prefix(char *matchBuf)
*/ */
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] == '(' || int_buf[i] == '{') {
remove_chunk(0, i + 1); remove_chunk(int_buf, 0, i + 1);
i = -1; /* hack increment */ i = -1; /* hack increment */
} }
} }
@ -934,7 +932,7 @@ static NOINLINE int build_match_prefix(char *matchBuf)
for (i = 0; int_buf[i]; i++) for (i = 0; int_buf[i]; i++)
if (int_buf[i] != ' ') if (int_buf[i] != ' ')
break; break;
remove_chunk(0, i); remove_chunk(int_buf, 0, i);
/* Determine completion mode */ /* Determine completion mode */
command_mode = FIND_EXE_ONLY; command_mode = FIND_EXE_ONLY;
@ -961,7 +959,7 @@ static NOINLINE int build_match_prefix(char *matchBuf)
for (--i; i >= 0; i--) { for (--i; i >= 0; i--) {
int cur = int_buf[i]; int cur = int_buf[i];
if (cur == ' ' || cur == '<' || cur == '>' || cur == '|' || cur == '&') { if (cur == ' ' || cur == '<' || cur == '>' || cur == '|' || cur == '&') {
remove_chunk(0, i + 1); remove_chunk(int_buf, 0, i + 1);
break; break;
} }
} }
@ -970,11 +968,12 @@ static NOINLINE int build_match_prefix(char *matchBuf)
i = 0; i = 0;
while ((matchBuf[i] = int_buf[i]) != '\0') while ((matchBuf[i] = int_buf[i]) != '\0')
i++; i++;
free(int_buf);
if (dbg_bmp) printf("final matchBuf:'%s'\n", matchBuf); if (dbg_bmp) printf("final matchBuf:'%s'\n", matchBuf);
return command_mode; return command_mode;
} }
#undef int_buf
/* /*
* Display by column (original idea from ls applet, * Display by column (original idea from ls applet,