home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume14 / shellforms / part02 / field.c next >
C/C++ Source or Header  |  1988-05-09  |  7KB  |  260 lines

  1. /* Last update: 01/26/88  11:26 PM  (Edition: 25) */
  2. #include    <stdio.h>
  3. #include    <signal.h>
  4. #include    <strings.h>
  5. #include    <ctype.h>
  6. #include    "term.h"
  7. #include    "form.h"
  8. #include    "field.h"
  9. #include    "basic.h"
  10.  
  11. extern    int        Fno;
  12. extern    struct    field    Field[];
  13. extern    char        Screen[SCRLINE][SCRCOL+1];
  14. extern    char        Enter_mode[];
  15. extern    char        Exit_mode[];
  16. extern    int        Form_msg;
  17. extern    char        Exitc;
  18.  
  19. /*-------------------------------------------------------------05/09/86-+
  20. |                                    |
  21. |          get_field : get a copy of field data to buffer        |
  22. |                                    |
  23. +----------------------------------------------------------------------*/
  24. get_field (fno, buf)
  25. int    fno;                /* field number */
  26. char    *buf;                /* buffer to be filled */
  27.     {
  28.     struct    field    *f;
  29.     char        *p;
  30.     int        size;
  31.  
  32.     ENTER(get_field);
  33.     if (fno < 0 || fno >= Fno) EXIT;
  34.     f = &Field[fno];
  35.     p = &Screen [f-> f_line -1][f-> f_off];
  36.     size = fldlen (p, f-> f_len);
  37.     strncpy (buf, p, size);
  38.     buf[size] = EOS;        /* mark the end */
  39.     EXIT;
  40.     }
  41. /*----------------------------------------------------------------------+
  42. |                                    |
  43. |  fldlen : return the number of data in a field (skip trailing blanks) |
  44. |                                    |
  45. +----------------------------------------------------------------------*/
  46. fldlen (buf, size)
  47. char        *buf;        /* pointer to field buffer */
  48. unsigned    size;        /* size of the field */
  49.     {
  50.     int        blank;
  51.  
  52.     ENTER(fldlen);
  53.     for (blank=0; buf[size-1-blank] == ' '; blank++) {
  54.         if (blank >= size) break;
  55.         }
  56.     RETURN (size - blank);        /* return length of field */
  57.     }
  58.  
  59. /*----------------------------------------------------------------------+
  60. |                                    |
  61. |      upd_field : move data into a field and display it        |
  62. |                                    |
  63. +----------------------------------------------------------------------*/
  64. upd_field (idx, type, data)
  65. unsigned    idx;        /* field number (0 to Fno-1) */
  66. int        type;        /* type of output */
  67. int        data;        /* data, type may vary */
  68.     {
  69.     struct    field    *fp;
  70.     char        *fmt;
  71.     char        *scp;        /* pointer to screen buffer */
  72.     char        buf[81];
  73.     int        data2;        /* cents */
  74.  
  75.     ENTER(upd_field);
  76.     if (idx >= Fno) {
  77.         fprintf (stderr,
  78.              "Field number: %d out of range, max %d\r\n",
  79.              idx, Fno);
  80.         EXIT;
  81.         }
  82.  
  83.     fp = &Field[idx];
  84.     switch (type) {
  85.         case UF_MONEY:    fmt = "%5d.%02d";
  86.                 data2 = data % 100;
  87.                 data = data / 100;    break;
  88.         case UF_NUMBER: fmt = "%d";        break;
  89.         case UF_STRING:
  90.         default:    fmt = "%s";        break;
  91.         }
  92.  
  93.     sprintf (buf, fmt, data, data2);
  94.     scp = &Screen[fp-> f_line - 1][fp-> f_off];
  95.     bcopy (scp, buf, (unsigned)fp-> f_len);
  96.     poscur (fp-> f_line, fp-> f_col, (char *)NULL);
  97.     put_string (scp, fp-> f_len);
  98.     poscur (fp-> f_line, fp-> f_col, (char *)NULL);
  99.     EXIT;
  100.     }
  101.  
  102. /*-------------------------------------------------------------07/14/87-+
  103. |                                    |
  104. |    closest : find the closest field above/below current line    |
  105. |                                    |
  106. +----------------------------------------------------------------------*/
  107. closest (fno, direction)
  108. unsigned    fno;        /* current field number */
  109. int        direction;    /* compare direction: 1=below, -1=above */
  110.     {
  111.     struct    field    *fp = &Field[fno];
  112.     int        col;        /* target column */
  113.     int        line;        /* current line */
  114.     int        diff;        /* current difference */
  115.     int        mindiff = 100;    /* minimal difference */
  116.     int        mini = 0;    /* minimal field index */
  117.     register int    i;
  118.  
  119.     ENTER(closest);
  120.     col = fp->f_col;
  121.     line = fp->f_line;
  122.  
  123.     for (i=fno+direction; i != fno; i += direction) {
  124.         if (i < 0) i = Fno-1;
  125.         else if (i >= Fno) i = 0;
  126.         fp = &Field[i];
  127.         if (fp->f_line != line) break;
  128.         }
  129.     mini = i;
  130.     for (line = fp->f_line; ; i += direction) {
  131.         if (i < 0) i = Fno-1;
  132.         else if (i >= Fno) i = 0;
  133.         fp = &Field[i];
  134.         if (fp->f_line != line) break;
  135.         if ((diff = abs ((int)fp->f_col - (int)col)) == 0) RETURN (i);
  136.         if (diff < mindiff) {
  137.             mindiff = diff;
  138.             mini = i;
  139.             }
  140.         }
  141.     RETURN (mini);
  142.     }
  143.  
  144. /*----------------------------------------------------------------------+
  145. |                                    |
  146. |        edit_field : edit a given field in a form        |
  147. |                                    |
  148. +----------------------------------------------------------------------*/
  149. edit_field (idx, efopt)
  150. unsigned    idx;            /* index to Field array */
  151. int        efopt;            /* option */
  152.     {
  153.     struct    field    *fp;
  154.     char        c;
  155.     char        *p;
  156.     char        *s;        /* beginning of field buffer */
  157.     unsigned    n;
  158.     register int    i;
  159.  
  160.     ENTER (edit_field);
  161.     fp = &Field[idx];
  162.     poscur (fp-> f_line, fp-> f_col, Enter_mode);
  163.     p = s = &Screen [fp-> f_line - 1][fp-> f_off];
  164.     switch (efopt) {
  165.         case EF_FILL:
  166.         case EF_EOF:    n = fldlen (s, fp-> f_len);
  167.                 if (n != 0) {
  168.                     if (efopt == EF_FILL)
  169.                         put_string (p, n);
  170.                     p += n;
  171.                     }
  172.                 break;
  173.         default:    ;    /* start at beginning of field */
  174.         }
  175.     while (1) {
  176.         c = getkey ();
  177.         if (Form_msg) {
  178.             form_msg ((char *)NULL, fp-> f_line, fp-> f_col + (p-s));
  179.             put_string (Enter_mode, 0);
  180.             }
  181.         if ((c & 0x80) == 0x80) {
  182.             switch (c & 0x7f) {
  183.                 case KL:    goto cur_left;
  184.                 case KR:    goto cur_right;
  185.                 }
  186.             }
  187.         switch (c) {
  188.             case '\177':        /* delete char */
  189.                 if (p > s) { *(--p) = ' '; screen (SCR_DEL); }
  190.                 continue;
  191.             case CTRL('W'):        /* delete prev word */
  192.                 while (p > s) {
  193.                     if (*(p-1) != ' ') break;
  194.                     p--; screen (SCR_DEL);
  195.                     }
  196.                 while (p > s) {
  197.                     if (*(p-1) == ' ') break;
  198.                     *(--p) = ' ';
  199.                     screen (SCR_DEL);
  200.                     }
  201.                 continue;
  202.             case CTRL('K'):
  203.                 n = fldlen (s, fp-> f_len);
  204.                 for (i=0; i<n; i++) put_char (*(p+i) = ' ');
  205.                 for (i=0; i<n; i++) screen (SCR_BACKSPACE);
  206.                 continue;
  207.             case CTRL('H'):
  208.             case CTRL('B'):
  209. cur_left:            if (p > s) { p--; screen (SCR_BACKSPACE); }
  210.                 continue;
  211.             case CTRL('F'):
  212. cur_right:            if (p < s + fp-> f_len) {
  213.                     put_char (*p++);
  214.                     }
  215.                 continue;
  216.             case CTRL('G'):
  217.             case CTRL('U'):
  218.                 while (p > s) {
  219.                     *(--p) = ' ';  screen (SCR_DEL);
  220.                     }
  221.                 continue;
  222.             case CTRL('E'):        /* goto end of field */
  223.                 n = fldlen (s, fp-> f_len);
  224.                 p = s + n;
  225.                 poscur (fp-> f_line, fp-> f_col + n, (char *)NULL);
  226.                 continue;
  227.             case CTRL('A'):        /* emacs style */
  228.                 p = s;
  229.                 poscur (fp-> f_line, fp-> f_col, (char *)NULL);
  230.                 continue;
  231.             case CTRL('O'):
  232.                 prev_msg ();
  233.                 continue;
  234.             default:
  235.                 if ((fp-> f_attr & FA_NUMERIC) != 0 &&
  236.                      isprint (c) && !isdigit (c)) {
  237.                     put_char (CTRL('G'));
  238.                     form_msg ("Numeric field, 0-9 only",
  239.                           fp-> f_line,
  240.                           fp-> f_col + (p-s));
  241.                     continue;
  242.                     }
  243.                 if (c < LOW_GCHAR || c > HIGH_GCHAR) {
  244.                     Exitc = c;    /* save exit char */
  245.                     goto eoe;
  246.                     }
  247.             }
  248.         if (p - s >= fp-> f_len) { put_char (CTRL('G')); continue; }
  249.         *p++ = c;
  250.         put_char (c);
  251.         if ((fp-> f_attr & FA_AUTOTAB) != 0 && p - s == fp-> f_len) {
  252.             Exitc = TAB;        /* tab to next field */
  253.             break;
  254.             }
  255.         }
  256.     /* *p = EOS will put a marker at the end of buffer */
  257. eoe:    put_string (Exit_mode, 0);
  258.     RETURN (p-s);
  259.     }
  260.