commit 6fde7d8a51a18eb127a375e78b88df6c5e7a7f91
parent e4abef5768a8d1a43d7525486cb99a2f76ee9d52
Author: Benno Schulenberg <bensberg@telfort.nl>
Date: Sun, 25 Sep 2022 15:51:02 +0200
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.
Diffstat:
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/src/nano.c b/src/nano.c
@@ -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;
}
diff --git a/src/prompt.c b/src/prompt.c
@@ -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;
}
}