! ras - Revisited

From: George (greerga@DRAGON.HAM.MUOHIO.EDU)
Date: 10/14/97


This look more along the lines of what you were looking for? :)

I decided to keep the buffer in the descriptor because it is more
player-related in input than anything to do with one character.  Memory is
allocated in new_descriptor, and released in close_socket.  I used a
circular array for efficiency. A linked list would have required a
head/tail pointer and a next pointer overhead.  A regular array would have
required moving each element down every command to keep the most recent
checked first.  I'll put this on my page if this is what Jeremy wanted.

diff -upPr -x *.o ../stk/comm.c ./comm.c
--- ../stk/comm.c       Sun Apr 14 14:28:46 1996
+++ ./comm.c    Tue Oct 14 23:19:47 1997
@@ -1041,6 +1041,7 @@ int new_descriptor(int s)
   newd->bufspace = SMALL_BUFSIZE - 1;
   newd->next = descriptor_list;
   newd->login_time = time(0);
+  CREATE(newd->history, char *, HISTORY_SIZE);

   if (++last_desc == 1000)
     last_desc = 1;
@@ -1259,13 +1260,33 @@ int process_input(struct descriptor_data
     }
     failed_subst = 0;

-    if (*tmp == '!')
+    if (*tmp == '!' && !(*(tmp + 1)))  /* Redo last command. */
       strcpy(tmp, t->last_input);
-    else if (*tmp == '^') {
+    else if (*tmp == '!' && *(tmp + 1)) {
+      char *commandln = (tmp + 1);
+      int starting_pos = t->history_pos,
+         cnt = (t->history_pos == 0 ? HISTORY_SIZE - 1 : t->history_pos - 1);
+
+      skip_spaces(&commandln);
+      for (; cnt != starting_pos; cnt--) {
+       if (t->history[cnt] && is_abbrev(commandln, t->history[cnt])) {
+         strcpy(tmp, t->history[cnt]);
+         break;
+       }
+        if (cnt == 0)  /* At top, loop to bottom. */
+         cnt = HISTORY_SIZE;
+      }
+    } else if (*tmp == '^') {
       if (!(failed_subst = perform_subst(t, t->last_input, tmp)))
        strcpy(t->last_input, tmp);
-    } else
+    } else {
       strcpy(t->last_input, tmp);
+      if (t->history[t->history_pos])
+       free(t->history[t->history_pos]);       /* Clear the old line. */
+      t->history[t->history_pos] = str_dup(tmp);       /* Save the new. */
+      if (++t->history_pos >= HISTORY_SIZE)    /* Wrap to top. */
+       t->history_pos = 0;
+    }

     if (!failed_subst)
       write_to_q(tmp, &t->input, 0);
@@ -1386,6 +1407,14 @@ void close_socket(struct descriptor_data

   REMOVE_FROM_LIST(d, descriptor_list, next);

+  /* Clear the command history. */
+  if (d->history) {
+    int cnt;
+    for (cnt = 0; cnt < HISTORY_SIZE; cnt++)
+      if (*d->history)
+       free(*d->history);
+    free(d->history);
+  }
   if (d->showstr_head)
     free(d->showstr_head);
   if (d->showstr_count)
diff -upPr -x *.o ../stk/structs.h ./structs.h
--- ../stk/structs.h    Fri Apr 12 23:39:22 1996
+++ ./structs.h Tue Oct 14 22:46:26 1997
@@ -428,6 +428,7 @@
 #define LARGE_BUFSIZE          (12 * 1024)
 #define GARBAGE_SPACE          32

+#define HISTORY_SIZE           5       /* Keep last 5 commands. */
 #define MAX_STRING_LENGTH      8192
 #define MAX_INPUT_LENGTH       256     /* Max length per *line* of input */
 #define MAX_RAW_INPUT_LENGTH   512     /* Max size of *raw* input */
@@ -893,6 +894,8 @@ struct descriptor_data {
    char        last_input[MAX_INPUT_LENGTH]; /* the last input                 */
    char small_outbuf[SMALL_BUFSIZE];  /* standard output buffer                */
    char *output;               /* ptr to the current output buffer     */
+   char **history;             /* History of commands, for ! mostly.   */
+   int history_pos;            /* Circular array position.             */
    int  bufptr;                        /* ptr to end of current output         */
    int bufspace;               /* space left in the output buffer      */
    struct txt_block *large_outbuf; /* ptr to large buffer, if we need it */


--
George Greer  -  Me@Null.net   | Genius may have its limitations, but stupidity
http://www.van.ml.org/~greerga | is not thus handicapped. -- Elbert Hubbard


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/08/00 PST