input: allocate two small character buffers too, and never free them

Analogous to commit 3922b531: instead of allocating and later freeing
a tiny fragment of memory for every character that the user enters (in
the edit window or at a prompt), reserve a small piece in the beginning
and retain it, and increase (but never decrease) its size as needed.

This addresses the second part of https://savannah.gnu.org/bugs/?63086.
This commit is contained in:
Benno Schulenberg 2022-09-25 15:51:02 +02:00
parent e4abef5768
commit 6fde7d8a51
2 changed files with 22 additions and 13 deletions

View File

@ -1547,6 +1547,8 @@ void process_a_keystroke(void)
/* The keystroke we read in: a character or a shortcut. */
static char *puddle = NULL;
/* The input buffer for actual characters. */
static size_t capacity = 12;
/* The size of the input buffer; gets doubled whenever needed. */
static size_t depth = 0;
/* The length of the input buffer. */
#ifndef NANO_TINY
@ -1593,21 +1595,23 @@ void process_a_keystroke(void)
refresh_needed = TRUE;
}
#endif
/* Store the byte, and leave room for a terminating zero. */
puddle = nrealloc(puddle, depth + 2);
/* When the input buffer (plus room for terminating NUL) is full,
* extend it; otherwise, if it does not exist yet, create it. */
if (depth + 1 == capacity) {
capacity = 2 * capacity;
puddle = nrealloc(puddle, capacity);
} else if (!puddle)
puddle = nmalloc(capacity);
puddle[depth++] = (char)input;
}
}
/* If we have a command, or if there aren't any other key codes waiting,
* it's time to insert the gathered bytes into the edit buffer. */
if ((function || waiting_keycodes() == 0) && puddle != NULL) {
if (depth > 0 && (function || waiting_keycodes() == 0)) {
puddle[depth] = '\0';
inject(puddle, depth);
free(puddle);
puddle = NULL;
depth = 0;
}

View File

@ -256,6 +256,8 @@ void absorb_character(int input, functionptrtype function)
{
static char *puddle = NULL;
/* The input buffer. */
static size_t capacity = 8;
/* The size of the input buffer; gets doubled whenever needed. */
static size_t depth = 0;
/* The length of the input buffer. */
@ -267,7 +269,14 @@ void absorb_character(int input, functionptrtype function)
beep();
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
openfile->filename[0] == '\0') {
puddle = nrealloc(puddle, depth + 2);
/* When the input buffer (plus room for terminating NUL) is full,
* extend it; otherwise, if it does not exist yet, create it. */
if (depth + 1 == capacity) {
capacity = 2 * capacity;
puddle = nrealloc(puddle, capacity);
} else if (!puddle)
puddle = nmalloc(capacity);
puddle[depth++] = (char)input;
}
}
@ -275,13 +284,9 @@ void absorb_character(int input, functionptrtype function)
/* If we got a shortcut, or if there aren't any other keystrokes waiting,
* it's time to insert all characters in the input buffer (if not empty)
* into the answer, and then clear the input buffer. */
if ((function || waiting_keycodes() == 0) && puddle != NULL) {
if (depth > 0 && (function || waiting_keycodes() == 0)) {
puddle[depth] = '\0';
inject_into_answer(puddle, depth);
free(puddle);
puddle = NULL;
depth = 0;
}
}