home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / shellforms / part02 / selection.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-09  |  5.6 KB  |  220 lines

  1. /* Last update: 01/27/88  00:04 AM  (Edition: 45) */
  2. #include    <stdio.h>
  3. #include    <sys/ioctl.h>
  4. #include    <ctype.h>
  5. #include    <strings.h>
  6. #include    "term.h"
  7. #include    "form.h"
  8. #include    "field.h"
  9. #include    "basic.h"
  10.  
  11. int    Help_display = NO;        /* if YES, display help */
  12.  
  13. extern    struct    field    Field[];
  14. extern    char        Enter_mode[];
  15. extern    char        Exit_mode[];
  16. extern    int        Form_msg;
  17. extern    char        Exitc;
  18. extern    char        *malloc();
  19. extern    char        *calloc();
  20. /*
  21.     Selection buffer looks like:
  22.  
  23.     <delchr> string1 <delchr> string2 <delchr> ... stringn <delchr>
  24.  
  25.     The first character in the buffer will be used as the delimiter to
  26.     separate selection strings.  The last delimiter character is optional,
  27.     i.e., EOS will also terminate the last selection string.
  28. */
  29.  
  30. /*-------------------------------------------------------------08/01/87-+
  31. |                                    |
  32. |     build_selection : take selection definition and create a list    |
  33. |                                    |
  34. +----------------------------------------------------------------------*/
  35. build_selection (fldp, buf, len)
  36. struct    field    *fldp;            /* ptr to field structure */
  37. char        *buf;            /* selection strings */
  38. unsigned    len;            /* length of string */
  39.     {
  40.     register char    *p = (char *)malloc(len+1);
  41.     register char    **tp;
  42.     register int    i;
  43.     char        delimiter = buf[0];    /* selection delimiter */
  44.     char        c;
  45.     unsigned    cnt = 0;        /* # of selections */
  46.     char        *tmp[50];        /* temp array */
  47.  
  48.     ENTER(build_selection);
  49.     if (len == 0) len = strlen (buf);
  50.     while (len-- != 0) {
  51.         if ((c = *buf++) == delimiter) {
  52.             *p++ = EOS;
  53.             if (cnt >= 50) {
  54.                 /* silent ignored extra for now */
  55.                 }
  56.             else tmp[cnt++] = p;
  57.             }
  58.         else    *p++ = c;
  59.         }
  60.     fldp->f_sel = tp = (char **) malloc (sizeof (char *) * (cnt + 1));
  61.     for (i=0; i<cnt; i++) *tp++ = tmp[i];
  62.     *tp = NULL;
  63.     fldp->f_attr |= FA_SELECTION;
  64.     RETURN (0);
  65.     }
  66.  
  67. /*-------------------------------------------------------------08/01/87-+
  68. |                                    |
  69. |    sel_num : return the number of selections in a given field    |
  70. |                                    |
  71. +----------------------------------------------------------------------*/
  72. sel_num (fldp)
  73. struct    field    *fldp;
  74.     {
  75.     register int    i = 0;
  76.     register char    **pp = fldp-> f_sel;
  77.  
  78.     ENTER(sel_num);
  79.     while (*pp++ != NULL) i++;
  80.     RETURN (i);
  81.     }
  82.  
  83. /*-------------------------------------------------------------08/01/87-+
  84. |                                    |
  85. |    sel_field : allow user to select a selection from the list    |
  86. |                                    |
  87. +----------------------------------------------------------------------*/
  88. sel_field (idx)
  89. unsigned    idx;            /* index to Field array */
  90.     {
  91.     struct    field    *fldp = &Field[idx];
  92.     int        n = fldp-> f_sno;    /* selection number */
  93.     int        selno;            /* # of possible selections */
  94.     int        i = -1;
  95.     char        c;
  96.  
  97.     ENTER(sel_field);
  98.     selno = sel_num (fldp);
  99.     poscur (fldp-> f_line, fldp-> f_col, Enter_mode);
  100.     upd_field (idx, UF_STRING, fldp-> f_sel[n]);
  101.     while (1) {
  102.         int    might_tab;
  103.         if (Help_display) display_help (fldp, n);
  104.         c = getkey ();
  105.         might_tab = 0;
  106.         if (Form_msg) {
  107.             form_msg ((char *)NULL, fldp->f_line, fldp->f_col);
  108.             put_string (Enter_mode, 0);
  109.             }
  110.         if ((c & 0x80) == 0x80) {
  111.             switch (c & 0x7f) {
  112.                 case KL:    goto prev_sel;
  113.                 case KR:    goto next_sel;
  114.                 }
  115.             }
  116.         switch (c) {
  117.             case ' ':
  118.             case CTRL('F'):
  119. next_sel:            if (++n >= selno) n = 0;  break;
  120.             case CTRL('H'):
  121. prev_sel:            if (--n < 0) n = selno-1; break;
  122.             case '?':
  123.                 if (!Help_display) {
  124.                     display_help (fldp, n);
  125.                     break;
  126.                     }
  127.             default:if (c < LOW_GCHAR || c > HIGH_GCHAR) {
  128.                     Exitc = c;
  129.                     goto eoe;
  130.                     }
  131.                 i = cmp1st (c, fldp->f_sel, i+1);
  132.                 if (i < 0) continue;
  133.                 might_tab = 1;
  134.                 n = i;
  135.             }
  136.         upd_field (idx, UF_STRING, fldp-> f_sel[n]);
  137.         if (might_tab && (fldp->f_attr & FA_AUTOTAB) != 0) {
  138.             Exitc = TAB;
  139.             break;
  140.             }
  141.         }
  142. eoe:    put_string (Exit_mode, 0);
  143.     fldp-> f_sno = n;        /* save selection number */
  144.     EXIT;
  145.     }    
  146.  
  147. /*-------------------------------------------------------------08/03/87-+
  148. |                                    |
  149. |       cmp1st : compare 1st character in a keyword list        |
  150. |                                    |
  151. +----------------------------------------------------------------------*/
  152. cmp1st (c, list, start)
  153. char    c;                /* char to compare */
  154. char    **list;                /* keyword list */
  155. int    start;                /* start entry index */
  156.     {
  157.     register int    i, j;
  158.     register int    n;
  159.  
  160.     ENTER(cmp1st);
  161.     if (list == NULL || list[0] == NULL) RETURN (-1);
  162.     for (n=0; list[n] != NULL; n++);
  163.     for (i=start, j=0; j<n; i++, j++) {
  164.         if (i >= n) i = 0;
  165.         if ((c | 0x20) == (list[i][0] | 0x20)) RETURN (i);
  166.         }
  167.     RETURN (-1);            /* no match */
  168.     }
  169.  
  170. /*-------------------------------------------------------------08/04/87-+
  171. |                                    |
  172. |        build_help_msg : build help message list        |
  173. |                                    |
  174. +----------------------------------------------------------------------*/
  175. build_help_msg (fldp, buf)
  176. struct    field    *fldp;            /* field where the msg belongs */
  177. char        *buf;            /* message stores here */
  178.     {
  179.     unsigned    len = strlen (buf);
  180.     unsigned    n;
  181.     register int    i;
  182.     register char    *p;
  183.  
  184.     ENTER(build_help_msg);
  185.     n = sel_num (fldp);
  186.     if (fldp-> f_help == NULL) {        /* first time call */
  187.         fldp-> f_help = (char **) calloc(n+1, sizeof(char *));
  188.         }
  189.     for (i=0; i<n; i++) {
  190.         if (fldp-> f_help[i] == NULL) break;
  191.         }
  192.     if (i < n) {
  193.         fldp-> f_help[i] = p = (char *) malloc (len + 1);
  194.         strcpy (p, buf);
  195.         }
  196.     EXIT;
  197.     }
  198.  
  199. /*-------------------------------------------------------------08/04/87-+
  200. |                                    |
  201. |       display_help : display help message on message line        |
  202. |                                    |
  203. +----------------------------------------------------------------------*/
  204. display_help (fldp, i)
  205. struct    field    *fldp;            /* field pointer */
  206. int        i;            /* index to help message */
  207.     {
  208.     char        *p;
  209.     int        numchar;    /* # of pending input chars */
  210.  
  211.     ENTER(display_help);
  212.     if (fldp-> f_help == NULL) EXIT;
  213.     p = fldp-> f_help[i];
  214.     if (p != NULL) {
  215.         ioctl (0, FIONREAD, &numchar);
  216.         if (numchar == 0) form_msg (p, fldp->f_line, fldp->f_col);
  217.         }
  218.     EXIT;
  219.     }
  220.