home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / flistfrontend / src / debrief.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-04  |  3.6 KB  |  179 lines

  1. #ifndef NO_IDENT
  2. static char *Id = "$Id: debrief.c,v 1.4 1995/06/04 19:27:42 tom Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Title:    debrief.c
  7.  * Author:    Thomas E. Dickey
  8.  * Created:    16 Sep 1985
  9.  * Last update:
  10.  *        19 Feb 1995, prototypes
  11.  *        21 Sep 1985    The 'vec[]' array may not be sorted.  Allow
  12.  *                for this in generating a list of ambiguous
  13.  *                matches.
  14.  *        17 Sep 1985
  15.  *
  16.  * Function:    Perform a table-lookup for a command-keyword.  If the keyword
  17.  *        is not found, determine if there is a partial match, generating
  18.  *        an "ambiguous" message for this case, or "unknown" for the
  19.  *        default.
  20.  *
  21.  * Arguments:    msg    => buffer in which to return error message
  22.  *        vec    => array of structures a la VEC (no repeated entries!!)
  23.  *        vsize    = actual size of *vec
  24.  *        vlast    = number of entries in array *vec
  25.  *        find     - string to find (must be in the same case as the table).
  26.  *        fsize    = length of 'find' (need not be null-terminated).
  27.  *
  28.  * Returns:    0..vlast-1 if legal match found
  29.  *        -1, if partial match found (ambiguous)
  30.  *        -2, if no match at all
  31.  */
  32.  
  33. #include    <stdio.h>
  34. #include    <string.h>
  35. #include    <ctype.h>
  36.  
  37. #include    "strutils.h"
  38.  
  39. typedef    struct    {
  40.     char    *match;
  41.     int    brief;
  42.     }    VEC;
  43.  
  44. #define    LOOP    for (v_ = vec, k = 0;\
  45.              k < vlast;\
  46.              k++, v_ = (VEC *)((char *)v_ + vsize))
  47. #define    RANGE    4
  48.  
  49. int
  50. debrief (
  51.     char    *msg,
  52.     VEC    *vec,
  53.     int    vsize,        /* actual number of bytes/entry    */
  54.     int    vlast,
  55.     char    *find,
  56.     int    fsize)
  57. {
  58.     register VEC    *v_;
  59.     int    vlong    = 0,
  60.         i,
  61.         j,
  62.         k,
  63.         range,
  64.             toomany    = 0,
  65.         flen[RANGE];
  66.     char    key[255],
  67.         *s_,
  68.         *d_,
  69.         *fuse[RANGE];
  70.  
  71.     strncpy (key, find, fsize);
  72.     key[fsize] = '\0';
  73.     if (msg) *msg = '\0';
  74.  
  75.     LOOP
  76.     {
  77.         if ((fsize >= v_->brief) && !strncmp (key, v_->match, fsize))
  78.         return (k);
  79.         /*
  80.          * If the search-string is not as long as the minimum
  81.          * abbreviation, latch the length to which it matches.
  82.          */
  83.         else
  84.         {
  85.         for (s_ = key, d_ = v_->match, j = 0;
  86.             *s_ && *d_ && *s_ == *d_;
  87.             s_++, d_++, j++);
  88.         if (j > vlong)    vlong = j;
  89.         }
  90.     }
  91.  
  92.     /*
  93.      * If we have only partial-matches, make up a message showing the
  94.      * range:
  95.      */
  96.     if (vlong)
  97.     {
  98.         if (msg)
  99.         {
  100.         range = 0;
  101.         for (j = 0; j < RANGE; j++) {
  102.             fuse[j] = 0;
  103.             flen[j] = 0;
  104.         }
  105.         LOOP
  106.         {
  107. #define    CMP(j)    strcmp(v_->match, fuse[j])
  108.  
  109.             if (!strncmp (v_->match, key, vlong))
  110.             {
  111.             for (j = 0; j < range; j++) /* Find insertion-point */
  112.             {
  113.                 if (CMP(j) < 0) break;
  114.             }
  115.  
  116.             if (j >= range)    /* New entry is higher than table */
  117.             {
  118.                 if (++range > RANGE)
  119.                 {
  120.                 j--, range--, toomany++;
  121.                 /* Overwrite last entry in table */
  122.                 if (CMP(j) > 0)
  123.                 {
  124.                     flen[j] = v_->brief;
  125.                     fuse[j] = v_->match;
  126.                 }
  127.                 }
  128.                 else
  129.                 {
  130.                 flen[j] = v_->brief;
  131.                 fuse[j] = v_->match;
  132.                 }
  133.             }
  134.             else        /* Insert within the pointer-list */
  135.             {
  136.                 i = RANGE;    /* Assume we up-shift pointers */
  137.                 if (toomany)
  138.                 i--;
  139.                 else
  140.                 {
  141.                 if (++range >= RANGE)
  142.                     i--, range--, toomany++;
  143.                 }
  144.                 while (--i > j)
  145.                 {
  146.                 flen[i] = flen[i-1];
  147.                 fuse[i] = fuse[i-1];
  148.                 }
  149.                 if ((j < RANGE-1) || (CMP(j) > 0))
  150.                 {
  151.                 flen[j] = v_->brief;
  152.                 fuse[j] = v_->match;
  153.                 }
  154.             }
  155.             }
  156.         }
  157.         strcpy (msg, "Ambiguous keyword:");
  158.         for (j = 0; j < range; j++)
  159.         {
  160.             strcat (msg, " ");
  161.             if (toomany && (j == range-1))    strcat (msg, "... ");
  162.             for (d_ = strnull(msg), s_ = fuse[j]; *s_; s_++)
  163.             {
  164.             *d_++ = (s_ > fuse[j]+flen[j]-1)
  165.                 ? _tolower(*s_)
  166.                 : _toupper(*s_);
  167.             }
  168.             *d_ = '\0';
  169.         }
  170.         }
  171.         return (-1);
  172.     }
  173.     else
  174.     {
  175.         if (msg) sprintf (msg, "Unknown keyword: '%.80s'", key);
  176.         return (-2);
  177.     }
  178. }
  179.