home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / flistfrontend / src / cmdstk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-21  |  3.8 KB  |  170 lines

  1. #ifndef NO_IDENT
  2. static char *Id = "$Id: cmdstk.c,v 1.8 1995/10/21 17:49:10 tom Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Title:    cmdstk.c
  7.  * Author:    Thomas E. Dickey
  8.  * Created:    17 Oct 1984 (broke out of 'dircmd')
  9.  * Last update:
  10.  *        27 May 1995, split-out cmdstk.h
  11.  *        18 Feb 1995, port to AXP (renamed 'alarm')
  12.  *        14 May 1985, was testing wrong variable in entry to '_put'.
  13.  *        30 Apr 1985, always store commands in lower-case.
  14.  *        27 Apr 1985, don't concat ' ' on end of stored-string!!
  15.  *        22 Dec 1984, permit bidirectional movement in 'cmdstk_get'.
  16.  *        18 Dec 1984, restrict stack to a page of memory.  Re-coded
  17.  *                 from a linked-list to a ring buffer.
  18.  *
  19.  * Function:    This module maintains a buffer of the most-recently-used
  20.  *        command strings of FLIST, permitting the user to retrieve
  21.  *        commands for re-use or alteration.
  22.  */
  23.  
  24. #include    <stdlib.h>
  25. #include    <string.h>
  26.  
  27. #include    "bool.h"
  28. #include    "crt.h"
  29. #include    "cmdstk.h"
  30. #include    "strutils.h"
  31.  
  32. /*
  33.  * Local (static) data:
  34.  *
  35.  * Save FLIST "visible commands" in a stack-list in memory, to provide
  36.  * last-command retrieval.
  37.  */
  38.  
  39. static    CMDSTK    *cmdstk_ = 0;
  40.  
  41. #define    HEAD    cmdstk_->head
  42. #define    STORED    cmdstk_->stored
  43. #define    DEPTH    cmdstk_->depth
  44. #define    TEXT(j)    cmdstk_->text[j]
  45.  
  46. #define    INDEX(j) cmdstk_index(HEAD-(j))
  47.  
  48. static    int    cmdstk_index (int n);
  49.  
  50. /*
  51.  * Allocate a page-buffer for the command-stack.  We provide a hierarchy
  52.  * for FLIST by copying the stack from a higher level to this level.  Thus,
  53.  * there is no loss of continuity on entering a new level; but on exit we
  54.  * resume with the set of stacked commands which were present on nesting.
  55.  */
  56. CMDSTK *
  57. cmdstk_init (void)
  58. {
  59.     CMDSTK    *new_ = calloc (1, PAGESIZE),
  60.         *old_ = cmdstk_;
  61.  
  62.     if (cmdstk_)    *new_ = *cmdstk_;
  63.     cmdstk_ = new_;
  64.     return (old_);
  65. }
  66.  
  67. void
  68. cmdstk_free (CMDSTK *old_)
  69. {
  70.     if (cmdstk_)        cfree (cmdstk_);
  71.     cmdstk_ = old_;
  72. }
  73.  
  74. void
  75. cmdstk_tos (void)
  76. {
  77.     DEPTH = -1;        /* Provide index to most-recent    */
  78. }
  79.  
  80. /*
  81.  * Retrieve the (next) most recent item on the command stack.  If we are at
  82.  * the end, sound an alarm.  Return TRUE iff there is text to process.
  83.  * Note that if no commands have been entered, we do not alter the output
  84.  * string from whatever the caller set it to.
  85.  */
  86. int
  87. cmdstk_get (char *string, int dir)
  88. {
  89.     int    deep    = DEPTH + dir;
  90.  
  91.     if ((deep < STORED) && (deep >= 0))
  92.     {
  93.         strcpy (string, TEXT(INDEX(deep)));
  94.         DEPTH = deep;
  95.         return (TRUE);
  96.     }
  97.     sound_alarm ();
  98.     return (*string);
  99. }
  100.  
  101. /*
  102.  * If the current command is the same as one of the last 'RING' commands,
  103.  * do not save it.  This permits the user to toggle between a couple
  104.  * of commands in the retrieval state.
  105.  *
  106.  * A command which duplicates one in the last 'RING' levels causes this
  107.  * item to be "popped" to the top-level of the ring.  The entire stack
  108.  * is pushed only when no match is found in the ring.
  109.  */
  110. void
  111. cmdstk_put (char *s_)
  112. {
  113.     register
  114.     int    j, k;
  115.     char    string[CRT_COLS+1];
  116. #define    RING    3
  117.  
  118.     if (*s_)        /* Save all "visible" commands    */
  119.     {
  120.         strlcpy (string, s_);
  121.         if (STORED)
  122.         {
  123.             for (j = 0; j < RING; j++)
  124.             {
  125.                 if (!strcmp (string, TEXT(INDEX(j))))
  126.                 {
  127.                     for (k = j; k > 0; k--)
  128.                         strcpy (TEXT(INDEX(k)),
  129.                             TEXT(INDEX(k-1)));
  130.                     strcpy (TEXT(HEAD), string);
  131.                     return;
  132.                 }
  133.             }
  134.         }
  135.         HEAD = INDEX(-1);
  136.         if (STORED < MAXSTK)    STORED += 1;
  137.         strcpy (TEXT(HEAD), string);
  138.     }
  139. }
  140.  
  141. /*
  142.  * This procedure is called by a "visible" command to alter to extend its
  143.  * saved-text, for command retrieval.  In particular, it is called by the
  144.  * protection-editor.
  145.  */
  146. void
  147. cmdstk_chg (char *string)
  148. {
  149.     if (STORED > 0)        /* Only "change" if there is something */
  150.     {
  151.         HEAD  = INDEX(1);        /* Redo this entry    */
  152.         cmdstk_tos ();
  153.         STORED--;
  154.         cmdstk_put (string);
  155.     }
  156.     else
  157.         sound_alarm ();
  158. }
  159.  
  160. /*
  161.  * Compute an index in the queue, accounting for wraparound.
  162.  */
  163. static int
  164. cmdstk_index (int n)
  165. {
  166.     if (n < 0)        n = MAXSTK - n;
  167.     else if (n >= MAXSTK)    n = n - MAXSTK;
  168.     return (n);
  169. }
  170.