]> granicus.if.org Git - nethack/commitdiff
dumplog's saved_plines[]
authorPatR <rankin@nethack.org>
Mon, 27 Feb 2017 10:54:14 +0000 (02:54 -0800)
committerPatR <rankin@nethack.org>
Mon, 27 Feb 2017 10:54:14 +0000 (02:54 -0800)
Use a simple ring buffer instead of a flat array that needed to have
49 pointers shifted down a slot every time a pline message was issued.

'saved_plines[saved_pline_index]' is the oldest message in the buffer
and the next slot to use when adding a new one.

src/end.c
src/pline.c

index 817ca411120805c9139c36a911e408dcbd775846..f0d3e2f0709435bdac3e8d1229dee55090f568fd 100644 (file)
--- a/src/end.c
+++ b/src/end.c
@@ -675,15 +675,17 @@ char *defquery;
 STATIC_OVL void
 dump_plines()
 {
-    int i;
+    int i, j;
     char buf[BUFSZ], **strp;
     extern char *saved_plines[];
+    extern unsigned saved_pline_index;
 
     Strcpy(buf, " ");
     putstr(0, 0, "");
     putstr(0, 0, "Latest messages:");
-    for (i = 0; i < DUMPLOG_MSG_COUNT; ++i) {
-        strp = &saved_plines[DUMPLOG_MSG_COUNT - 1 - i];
+    for (i = 0, j = (int) saved_pline_index; i < DUMPLOG_MSG_COUNT;
+         ++i, j = (j + 1) % DUMPLOG_MSG_COUNT) {
+        strp = &saved_plines[j];
         if (*strp) {
             copynchars(&buf[1], *strp, BUFSZ - 1 - 1);
             putstr(0, 0, buf);
index 0f21b444b43ac9d46a73423696adc0f59469fc06..6103d29cfd9c10988d3fe12e71a617ce6ce66013 100644 (file)
@@ -15,7 +15,9 @@ static void FDECL(execplinehandler, (const char *));
 #endif
 
 #ifdef DUMPLOG
-char* saved_plines[DUMPLOG_MSG_COUNT] = {0};
+/* also used in end.c */
+unsigned saved_pline_index = 0; /* slot in saved_plines[] to use next */
+char *saved_plines[DUMPLOG_MSG_COUNT] = { (char *) 0 };
 #endif
 
 /*VARARGS1*/
@@ -84,6 +86,7 @@ VA_DECL(const char *, line)
         pbuf[BUFSZ - 1 - 1] = line[ln - 1];
         pbuf[BUFSZ - 1] = '\0';
         line = pbuf;
+        ln = BUFSZ - 1;
     }
     if (!iflags.window_inited) {
         raw_print(line);
@@ -92,12 +95,34 @@ VA_DECL(const char *, line)
     }
 
 #ifdef DUMPLOG
-    /* We hook here early to have options-agnostic output. */
-    free(saved_plines[DUMPLOG_MSG_COUNT - 1]);
-    for (ln = 0; ln < DUMPLOG_MSG_COUNT - 1; ++ln)
-        saved_plines[DUMPLOG_MSG_COUNT - ln - 1] = saved_plines[DUMPLOG_MSG_COUNT - ln - 2];
-    saved_plines[0] = malloc(strlen(line) + 1);
-    (void) strcpy(saved_plines[0], line);
+    /* We hook here early to have options-agnostic output.
+     * Unfortunately, that means Norep() isn't honored (general issue) and
+     * that short lines aren't combined into one longer one (tty behavior).
+     */
+    {
+        /*
+         * TODO:
+         *  This essentially duplicates message history, which is
+         *  currently implemented in an interface-specific manner.
+         *  The core should take responsibility for that and have
+         *  this share it.
+         *  Ideally history for prompt lines should be augmented
+         *  with the player's response once that has been specified.
+         */
+        unsigned indx = saved_pline_index; /* next slot to use */
+        char *oldest = saved_plines[indx]; /* current content of that slot */
+
+        if (oldest && (int) strlen(oldest) >= ln) { /* ln==strlen(line) */
+            /* this buffer will gradually shrink until the 'else' is needed;
+               there's no pressing need to track allocation size instead */
+            Strcpy(oldest, line);
+        } else {
+            if (oldest)
+                free((genericptr_t) oldest);
+            saved_plines[indx] = dupstr(line);
+        }
+        saved_pline_index = (indx + 1) % DUMPLOG_MSG_COUNT;
+    }
 #endif
 
     msgtyp = msgtype_type(line, no_repeat);
@@ -117,7 +142,7 @@ VA_DECL(const char *, line)
 
     /* this gets cleared after every pline message */
     iflags.last_msg = PLNMSG_UNKNOWN;
-    strncpy(prevmsg, line, BUFSZ), prevmsg[BUFSZ - 1] = '\0';
+    (void) strncpy(prevmsg, line, BUFSZ), prevmsg[BUFSZ - 1] = '\0';
     if (msgtyp == MSGTYP_STOP)
         display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */