home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_11_04 / 1104051a < prev    next >
Text File  |  1992-12-29  |  10KB  |  407 lines

  1. /* LISTING 3  Prompt Function     */
  2.  
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <ctype.h>
  6. #include <dos.h>
  7. #include <string.h>
  8. #include "./keys.h"
  9.  
  10. #ifndef YES
  11. #define YES   1
  12. #endif
  13.  
  14. #ifndef NO
  15. #define NO    0
  16. #endif
  17.  
  18. #define M_INSERT        1
  19. #define M_TYPEOVER      2
  20.  
  21. #define MOVE_CUR(row,col) printf("\x1B[%d;%df",row,col);
  22. #define NORMAL  "\x1B[0m"  /* ANSI Normal  Video */
  23. #define REVERSE "\x1B[7m"  /* ANSI Reverse Video */
  24.  
  25. /* Prototypes */
  26. extern int  match  (int, char);
  27. extern void change_cur (int, int);
  28. extern void main (void);
  29.  
  30. int    key;
  31.  
  32. int prompt( data, match_ch, min_len, max_len, row, col, 
  33.         message, fyi_row, fyi_col)
  34.  
  35. char   data [];       /* Return Message              */
  36. char   match_ch;      /* Code For Which Characters 
  37.              Are Allowed                 */
  38. int    min_len;       /* Min Length Allowed          */
  39. int    max_len;       /* Max Length Allowed          */
  40. int    row;           /* Window Row                  */
  41. int    col;           /* Window Column               */
  42. char   *message;      /* Prompt Message              */
  43. int    fyi_row;       /* FYI Window Row              */
  44. int    fyi_col;       /* FYI Window Column           */
  45. {
  46.    char  buf [80];
  47.    int   terminate;   /* Key That Caused Termination */
  48.    int   index,i;     /* General Index Variables     */
  49.    int   mode;        /* Mode: INSERT or TYPEOVER    */
  50.    int   changed;     /* Changed Flag:  1=YES, 0=NO  */
  51.    int   edit;        /* Edit Flag:     1=YES, 0=NO  */
  52.    int   frst_key;    /* First Key Flag: 1=YES, 0=NO */
  53.    char  more;        /* YES/NO Flag . . . 
  54.              Used To Terminate Input     */
  55.  
  56.    /* Initializations */
  57.    edit     = NO;
  58.    frst_key = NO;
  59.    changed  = NO;
  60.  
  61.    mode = M_TYPEOVER;
  62.    change_cur(0, 13); /* Set Cursor To Block Mode    */
  63.  
  64.    /* Display The FYI Message At The FYI Row, Colunn */
  65.    if (strlen(message)) { 
  66.       MOVE_CUR (fyi_row, fyi_col);
  67.       printf(message);
  68.    }
  69.  
  70.    printf(REVERSE);   /* Change To Reverse Video    */
  71.  
  72.    strcpy(buf, data); /* Make A Copy Of The Default 
  73.              Return Value               */
  74.  
  75.    for (index = strlen(buf); index < max_len; ++index) {
  76.       buf [index] = ' ';     /* Fill Remainder Of Default 
  77.                 Value With Blanks  */
  78.    }
  79.    buf [index] = '\0';
  80.  
  81.    /* Display Default Value For Field */
  82.    MOVE_CUR (row, col);  
  83.    printf(buf);
  84.  
  85.    /* Position Cursor At Beginning Of Field */
  86.    MOVE_CUR (row, col);  
  87.    
  88.    /* Get Input From User */
  89.    for (index = 0,more = YES; more; ) {
  90.        key = getch();
  91.        if (key == 0)
  92.       key = getch()+256;
  93.  
  94.        switch(key) {
  95.        case C_F1       : /* F1  Key        */
  96.        case C_F2       : /* F2  Key        */
  97.        case C_F3       : /* F3  Key        */
  98.        case C_F4       : /* F4  Key        */
  99.        case C_F5       : /* F4  Key        */
  100.        case C_F6       : /* F6  Key        */
  101.        case C_F7       : /* F7  Key        */
  102.        case C_F8       : /* F8  Key        */
  103.        case C_F9       : /* F9  Key        */
  104.        case C_F10      : /* F0  Key        */
  105.        case C_F11      : /* F11 Key        */
  106.        case C_F12      : /* F12 Key        */
  107.        case C_ESC      : /* ESCAPE Key     */
  108.         frst_key = NO;
  109.         terminate = key;
  110.         buf[index] = '\0';
  111.         more = NO;
  112.         break;
  113.  
  114.        case C_INS  : /* INSERT Key       */
  115.         frst_key = NO;
  116.         if (mode == M_INSERT) {
  117.            /* Set The Mode To TYPEOVER and
  118.           Change Cursor To Block Mode */
  119.            mode = M_TYPEOVER;
  120.            change_cur(0, 13); 
  121.         }
  122.         else {
  123.            /* Set The Mode To INSERT And
  124.           Change Cursor To Underline  */
  125.            mode = M_INSERT;
  126.            change_cur(12, 13);  
  127.         }
  128.         putchar(buf[index]);
  129.         MOVE_CUR(row, (col + index));
  130.         break;
  131.  
  132.        case C_BACK   : /* BACKSPACE Key  */
  133.        case C_DEL    : /* DELETE Key     */
  134.         frst_key = NO;
  135.         changed  = YES;
  136.         if (index >= max_len)
  137.            index = max_len - 1;
  138.         for (i = index; i < max_len; i++) {
  139.         if (buf[i+1] == '\0')
  140.            buf[i] = ' ';
  141.         else
  142.            buf[i] = buf[i+1];
  143.         }
  144.  
  145.         /* Redisplay The Field */
  146.         MOVE_CUR(row, col);
  147.         printf(buf);
  148.  
  149.         /* Reposition The Cursor. */
  150.         MOVE_CUR(row, (col + index));
  151.         putchar(buf[index]);
  152.         MOVE_CUR(row, (col + index));
  153.  
  154.         if (key == C_DEL)
  155.            break;
  156.  
  157.        case C_LEFT : /* LEFT ARROW      */
  158.         frst_key = NO;
  159.         if (index <= 0)
  160.            break;
  161.         if (index >= max_len) 
  162.            index = max_len -1;
  163.         index--;
  164.         MOVE_CUR(row, (col + index));
  165.         break;
  166.  
  167.        case C_RIGHT: /* RIGHT ARROW     */
  168.         frst_key = NO;
  169.         edit = YES;
  170.         if (index >= (max_len - 1))
  171.            break;
  172.         index++;
  173.         MOVE_CUR(row, (col + index));
  174.         break;
  175.  
  176.        case C_HOME : /* HOME KEY      */
  177.        case C_END  : /* END  KEY      */
  178.         frst_key = NO;
  179.         if (edit == YES) {
  180.            if (key == C_END) 
  181.           index = end_of_fld(buf,(strlen(buf)));
  182.            else 
  183.           index = 0;
  184.            MOVE_CUR(row, (col + index));
  185.            break;
  186.         }
  187.  
  188.        case C_DOWN : /* DOWN ARROW      */
  189.        case C_UP   : /* UP ARROW        */
  190.        case C_PGDN : /* PAGE DOWN       */
  191.        case C_PGUP : /* PAGE UP         */
  192.        case C_CR   : /* CARRIAGE RETURN */
  193.        case C_TAB  : /* TAB    Key      */
  194.  
  195.         frst_key = NO;
  196.  
  197.         /* Reset Mode and Edit Flag */
  198.         edit = NO;
  199.         mode = M_INSERT;
  200.  
  201.         if (strlen(data) >= (unsigned)min_len && 
  202.         index == 0 && changed == NO) {
  203.            /* If The User Has Not Changed The Value Of
  204.           The Data Field, Return The Appropriate
  205.           NO CHANGE Key For The terminating Key
  206.           That Was Pressed. */
  207.  
  208.            if (key == C_CR) {
  209.           /* Return No Change For Carriage Return */
  210.           terminate = CR_NO_CHG;
  211.            }
  212.            if (key == C_UP) {
  213.           /* Return No Change For Up Arrow   */
  214.           terminate = UP_NO_CHG;
  215.            }
  216.            if (key == C_DOWN) {
  217.           /* Return No Change For Down Arrow */
  218.           terminate = DN_NO_CHG;
  219.            }
  220.            if (key == C_TAB) {
  221.           /* Return No Change For Tab Key    */
  222.           terminate = TB_NO_CHG;
  223.            }
  224.            if (key != C_CR   &&
  225.            key != C_UP   &&
  226.            key != C_DOWN &&
  227.            key != C_TAB)
  228.           terminate = key;
  229.  
  230.            strcpy(buf, data);
  231.  
  232.            more = NO;
  233.            break;
  234.         }
  235.  
  236.         /* If Minimum Length Requirement Has been Met,
  237.            Quit */
  238.         if (index >= min_len) {
  239.            terminate = key;
  240.            more = NO;
  241.            break;
  242.         }
  243.  
  244.         /* Else Ignore */
  245.         break;
  246.  
  247.        default     :
  248.         if (index == max_len)
  249.            /* At End Of Data Field - Do Nothing */
  250.            break;
  251.  
  252.         /* We Have Dealt With All Of The Keys That We
  253.            Needed Above, So Now We Will Filter Out All
  254.            Keys And Characters Above 122 (z) Here. */
  255.  
  256.         if (key > 'z')              /* Ignore Key */
  257.            break;
  258.  
  259.         if (match(index, match_ch) == YES) {
  260.            /* Only Accept The User Entered Character
  261.           If It Successfully Passed The match
  262.           function. */
  263.            edit    = YES;
  264.            changed = YES;
  265.  
  266.            if (frst_key == YES) {
  267.           /* If This Is The First Valid Key That
  268.              The User Has Entered, Then Wipe Out
  269.              The Field. */
  270.           for (i = 0; i < max_len; i++) 
  271.               buf[i] = ' ';
  272.           frst_key = NO;
  273.            }
  274.  
  275.            if (mode == M_INSERT) {
  276.           /* Insert The User Entered Character
  277.              Into The Field */
  278.           for (i = (max_len - 1); i > index; i--) 
  279.               buf[i] = buf[i-1];
  280.            }
  281.  
  282.            /* Overwrite The Buffer With The User Entered
  283.           Character */
  284.            buf[index] = (char)key;
  285.  
  286.            /* Redisplay The Field */
  287.            MOVE_CUR(row, col);
  288.            printf(buf);
  289.  
  290.            /* Reposition The Cursor. */
  291.            index++;
  292.            if (index >= max_len) 
  293.           index --;
  294.            MOVE_CUR(row, (col + index));
  295.            putchar(buf[index]);
  296.            MOVE_CUR(row, (col + index));
  297.         }
  298.         break;
  299.        }
  300.    }
  301.    /* Redraw The Field In The Window's Normal
  302.       Color Attribute */
  303.    printf(NORMAL);
  304.    MOVE_CUR (row, col);
  305.    printf(buf);
  306.  
  307.    strcpy(data, buf);
  308.    data[(end_of_fld(data,(strlen(data))) + 1)] = '\0';
  309.    
  310.    /* Change Cursor Back To Underline */
  311.    change_cur(12, 13);
  312.    return (terminate);
  313. }
  314.  
  315. static int match(index,match_ch)
  316. int  index;
  317. char match_ch;
  318. {
  319.    int matches = YES;
  320.  
  321.    switch (match_ch) {
  322.    case '$' : /* 0-9 or ,$. */
  323.     if (!isdigit(key) && !strchr(".,$",key))
  324.        matches = NO;
  325.     break;
  326.  
  327.    case '#' : /* 0 - 9 */
  328.     if (!isdigit(key))
  329.        matches = NO;
  330.     break;
  331.  
  332.    case 'A' : /* A - Z */
  333.     if (!isalpha(key) && !strchr(" ",key))
  334.        matches = NO;
  335.     break;
  336.  
  337.    case 'D' : /* Date: 0-9 or - or / or .*/
  338.     if (!isdigit(key) && !strchr(".-*/",key))
  339.        matches = NO;
  340.     break;
  341.  
  342.    case 'l' : /* a-z, A-Z, 0-9, or ;:.,/?*-$#()'! or
  343.          leading space */
  344.     if (!isalnum(key) &&
  345.         !strchr(" !@#$%^&*()-_=+[{]}';:.,/?",key))
  346.        matches = NO;
  347.     break;
  348.  
  349.    case 'Q' : /* YyNn as Reply To Yes/No Question */
  350.     if (!strchr("YyNn",key))
  351.        matches = NO;
  352.     key = toupper(key);
  353.     break;
  354.  
  355.    case 'S' : /* 0-9 or + or - */
  356.     if (!isdigit(key) && !strchr("+-",key))
  357.        matches = NO;
  358.     break;
  359.  
  360.    case 'T' : /* Time: 0-9 or . or : */
  361.     if (!isdigit(key) && !strchr(".:",key))
  362.        matches = NO;
  363.     break;
  364.  
  365.    case 'X' : /* MmFf As Reply To Male/Female */
  366.     if (!strchr("MmFf",key))
  367.        matches = NO;
  368.     key = toupper(key);
  369.     break;
  370.  
  371.    default :
  372.     matches = NO;
  373.     break;
  374.    }
  375.    return (matches);
  376. }
  377.  
  378. /* This Function Will Return A 0 Based Index Of The
  379.    First Non-Blank Character At The End Of A String. */
  380. int end_of_fld(string, length)
  381. char *string;
  382. int  length;
  383. {
  384.    int  i;
  385.  
  386.    for (i = length - 1; i >= 0; i--) {
  387.        if (string[i] != ' ' && string[i] != '\0')
  388.       return(i);
  389.    }
  390.    return(0);
  391. }
  392.  
  393. /* This Function Will Change The Appearance Of The 
  394.    Cursor To A Block Or An Underscore */
  395. void change_cur(start, end)
  396. int start;
  397. int end;
  398. {
  399.    union REGS r;
  400.  
  401.    r.h.ah = 1;
  402.    r.h.ch = start;
  403.    r.h.cl = end;
  404.    int86(0x10, &r, &r);
  405. }
  406.  
  407.