Newer
Older
Microsoft / ice / SD2_FEDI.C
@tundra tundra on 24 May 2012 20 KB Initial revision
/* SD2_FEDI.C - Screen Door II Field Edit Routines

                Copyright (c), 1988 By T.A. Daneliuk
                Last Modified: 08-11-88

        These routines edit a specific field in accordance with the
        definitions in a structure type called SD2_FIELD.  On entry,
        the calling routine passes a pointer to such a field.  On
        return, SD2_NOERR is returned if the edit was successful.
        An error code is returned if the edit failed for some reason.
        This will occur under the following conditions:

            The pointer passed to sd2_fedit() is NULL     (SD2_NULFPTR)
            The passed structure points to a Prompt field (SD2_ENOTRES)
            The the "field" structure member is NULL      (SD2_EFNULL)

        The function will not accept any characters which do not meet
        the character validation conditions, and will not return until
        the whole field validation function passes successfully.
*/

#include    <stdio.h>
#include    <string.h>
#include    <sd2_defs.h>
#include    <ctype.h>

#if ANSI
static BOOL end_fld(struct SD2_FIELD *x);
static BOOL  mask_val(struct SD2_FIELD *x, KEYSTR *y, FLEN z);
#else
static BOOL end_fld();
static BOOL  mask_val();
#endif

static BOOL firsttime;


/*====================== MAIN FIELD EDITING FUNCTION =========================*/

ERRCODE sd2_fedit(fldptr, retnkey)

struct  SD2_FIELD   *fldptr;
KEYSTR              *retnkey;

{
    ERRCODE     fedit_status;
    BOOL        fediting;
    KEYSTR      key, ktemp;
    BOOL        fmodified;
    FLEN        fposn, flen, rlen, temp;
    BOOL        ins_mode;
    BOOL        paint;
    BOOL        get_next_key;
    BOOL        store_key;


    fedit_status = SD2_NOERR;

    if (fldptr == NULL)                         /* See If Bad Pointer Passed  */
        fedit_status = SD2_NULFPTR;

    if (fldptr->ftype != FLD_RESP)              /* See If Response Allowed    */
        fedit_status = SD2_ENOTRES;
    else
        if (fldptr->field == NULL)              /* Is Response Fld. Ptr. OK?  */
            fedit_status = SD2_EFNULL;


    firsttime       = TRUE;                     /* Setup The State Machine    */
    fediting        = TRUE;
    fmodified       = FALSE;
    fposn           = 0;
    ins_mode        = FALSE;
    paint           = TRUE;
    get_next_key    = TRUE;

    while ((fediting == TRUE) && (fedit_status == SD2_NOERR))
        {
        if (paint == TRUE)
            {
            if ((fldptr->mask != NULL) && (fldptr->field[fposn] != '\0'))
                {
                temp = fposn;   /* Make Any Case Corrections For Char. Val.   */
                while (fldptr->field[temp] != '\0')
                    {
                    mask_val(fldptr, &(fldptr->field[temp]), temp);
                    temp++;
                    }
                }
            sd2_fdsply(fldptr, fmodified, fposn);        /* Display Updates */
            }
        sd2_rowcol(fldptr->frow, (fldptr->fcol)+fposn);  /* Position Cursor */
        (ins_mode==TRUE ? sd2_cursor(CURBLK) : sd2_cursor(CURSML));
        if (get_next_key == TRUE)
            {
            key = sd2_keyin();                        /* Get Next Keystroke   */
            *retnkey = key;                           /* Save For Return      */
            }
        flen = strlen(fldptr->field);                 /* Current Field Length */
        rlen = fldptr->rlen;                          /* Maximum Field Length */


  /* Inter-Field, Exit-Field, & Exit-Screen All Force End Of Field Editing */

        if ((key == NXTFLD) || (key == PRVFLD) || (key == FSTFLD) ||
            (key == LSTFLD) || (key == EXTFLD) || (key == EXTSCR))
            {
            if (end_fld(fldptr) == TRUE)    /* All Field Validations OK       */
                {
                fediting = FALSE;           /* Done With Field Editing        */
                fposn = 0;                  /* For Cosmetic Consistency       */
                }
            }

        else
            if (key == SD2_EBAD_CTRL);      /* Ignore Bad Control Sequences   */

        else
            if (key == CURLFT)

                {
                if (flen > 0)               /* If Nothing In Field, Can't Move*/
                    fposn = (fposn == 0 ? flen : --fposn);   /* Wrap If Neces.*/
                fposn = (fposn == rlen ? --fposn : fposn);
                paint = FALSE;
                }
        else
            if (key == CURRGT)
                {
                if (flen > 0)
                    fposn = (fposn == flen ? 0: ++fposn);
                fposn = (fposn == rlen ? 0 : fposn);
                paint = FALSE;
                get_next_key = TRUE;     /* We Might Just Have Put A New Char */
                }

        else
            if (key == BEGFLD)
                {
                fposn = 0;
                paint = FALSE;
                }

        else
            if (key == ENDFLD)
                {
                fposn = flen;
                fposn = (fposn == rlen ? --fposn : fposn);
                paint = FALSE;
                }

        else
            if (key == CLRFLD)
                {
                fposn = 0;
                fldptr->field[0] = '\0';
                paint = TRUE;
                fmodified = TRUE;
                firsttime = TRUE;               /* Force Whole Field Repaint  */
                }

        else
            if (key == CLREND)
                {
                fldptr->field[fposn] = '\0';
                paint = TRUE;
                fmodified = TRUE;
                firsttime = TRUE;
                }

        else
            if (key == INSERT)
                {
                if (flen < rlen)                   /* No Insert On Full Field */
                    {
                    ins_mode = (ins_mode == TRUE ? FALSE : TRUE);
                    paint = FALSE;
                    }
                }

        else
            if (key == DELETE)
                {
                store_key = TRUE;
                if (fldptr->field[fposn] != '\0')
                    {
                    if (fldptr->mask != NULL)   /* Make Sure Moving Left Is OK*/
                        {
                        temp  = fposn;              /* Can Current Character  */
                        ktemp = fldptr->field[temp+1];/* Legally Move Over?   */

                        while(ktemp != '\0')        /* Check All Remaining    */
                            {
                            store_key = store_key && 
                                           mask_val(fldptr, &ktemp, temp);
                            temp++;
                            ktemp = fldptr->field[temp+1];
                            }
                        }
                    }
                    if (store_key == TRUE)      /* Character Validations OK   */
                        {
                        strcpy(&(fldptr->field[fposn]), &(fldptr->field[fposn+1]));
                        fldptr->field[flen-1] = '\0';
                        fmodified = TRUE;
                        paint = TRUE;
                        }
                    else
                        if (get_next_key == FALSE)  /* Were Trying To Bkspc   */
                            fposn++;

                    get_next_key = TRUE;        /* In Case We Just Backspaced */
                }

        else
            if (key == BKSPC)
                {
                if (fposn > 0)                 /* No Bksp. @ Fld. Beginning   */
                    {
                    --fposn;          /* Just Backup One Position And Delete  */
                    key = DELETE;
                    get_next_key = FALSE;     /* Inhibit Keyboard Read            */
                    }
                }

        else
            if (key == HELPKEY)
                {
                if (fldptr->rhelp != NULL) /* Help Is Avail.*/
                    sd2_help(fldptr->rhelp);
                }
        else                             /* We Have A Data Keystroke          */
            {
            store_key = TRUE;            /* Do Character Validations          */


            if ((key == ' ') && (fldptr->rspace == FALSE)) /* Spaces Allowed? */
                store_key = FALSE;

            if (fldptr->mask != NULL)  /* Do Only If Char Validations Enabled */
                {
                store_key = store_key && mask_val(fldptr, &key, fposn);

                if (ins_mode == TRUE)   /* Check All Subsequent If Inserting  */
                    {
                    if (fldptr->field[fposn] != '\0')  /* Only If Not At End  */
                        {
                        temp  = fposn;              /* Can Current Character  */
                        ktemp = fldptr->field[temp];  /* Legally Move Over?   */

                        while(ktemp != '\0')        /* Check All Remaining    */
                            {
                            store_key = store_key && 
                                           mask_val(fldptr, &ktemp, temp+1);
                            temp++;
                            ktemp = fldptr->field[temp];
                            }
                        }
                    }
                }

            if (store_key == TRUE)       /* Character Passed Validation       */
                {
                if (ins_mode == TRUE)
                    {
                   temp = flen;
                   while(temp >= fposn)
                        {
                        fldptr->field[temp+1] = fldptr->field[temp];
                        --temp;
                        }

                    fldptr->field[fposn]  = key;
                    if ((flen+1) == rlen)           /* Field Now Is Filled    */
                        {
                        ins_mode = FALSE;
                        sd2_cursor(CURSML);
                        }
                    }
                else
                    {
                    if (fldptr->field[fposn] == '\0')
                        fldptr->field[fposn+1] = '\0';           
                    fldptr->field[fposn] = key;
                    }
                key = CURRGT;                       /* Move Cursor Over One   */
                get_next_key = FALSE;               /* Before Getting Next    */
                fmodified = TRUE;                   /* Keystroke              */
                paint = TRUE;
                }
            }

        }


    sd2_fdsply(fldptr, FALSE, fposn);
    return(fedit_status);

}


/*========================== DISPLAY A FIELD =================================*/

void    sd2_fdsply(fld, modified, cposn)
struct SD2_FIELD    *fld;
BOOL            modified;
FLEN            cposn;

{

    FLEN    x, y;
    char    fill[2];

    sd2_cursor(CUROFF);                         /* Turn Off Cursor            */

    if (modified == FALSE)              /* Use Default Colors, No Fill        */
        {                               /* Use Input Color And Fill           */
        x = strlen(fld->field);
        fill[0] = fld->rclear;
        fill[1] = '\0';

        sd2_rowcol(fld->frow, (fld->fcol)+cposn);   /* Position Cursor        */
        sd2_aputs(&(fld->field[cposn]), fld->fattrib);   /* Display String */
        while (x < fld->rlen)
            {
            sd2_rowcol(fld->frow, (fld->fcol)+x);    /* Clear Any Fill Chars. */
            sd2_aputs(fill, fld->cattrib);
            x++;
            }
        }
    else
        {                               /* Use Input Color And Fill           */
        y = x = strlen(fld->field);
        fill[0] = fld->rfill;
        fill[1] = '\0';

        if (firsttime == TRUE)          /* First Time Display Whole Field     */
            {
            firsttime = FALSE;
            cposn = 0;
            }
        else                            /* At Most, Only Need 1 Fill Char     */
            y = (y == fld->rlen ? y : (fld->rlen) - 1);

        
        sd2_rowcol(fld->frow, (fld->fcol)+cposn);   /* Position Cursor        */
        sd2_aputs(&(fld->field[cposn]), fld->rattrib);   /* Display String */

        while (y < fld->rlen)                  /* Have To Add A Fill Char */
            {
            sd2_rowcol(fld->frow, (fld->fcol)+x);    /* Then Fill Chars. */
            sd2_aputs(fill, fld->rattrib);
            ++y;
            ++x;
            }
        }
}


/*======================= END FIELD PROCESSING ===============================*/

static BOOL end_fld(fld)    /* Does Whole Fld, RReq, User Validation, etc.    */
struct SD2_FIELD *fld;      /* Returns True If All OK, False If Not           */

{
    ERRCODE     status;
    char        *errmsg;
    static char mfill[] = "This Field Must Be Filled!";
    static char rreqd[] = "This Field Requires A Response!";
    
    status = SD2_NOERR;

    if ((fld->rmustfill == TRUE) && (strlen(fld->field) != fld->rlen))
        {
        status = SD2_MUSTFIL;
        errmsg = mfill;
        }        

    else
        if ((fld->rreqd == TRUE) && (fld->field[0] == '\0'))
            {
            status = SD2_RESREQD;
            errmsg = rreqd;
            }

    else if (fld->rvalid != NULL)
        {
        errmsg = (*(fld->rvalid)) (fld);
        if (errmsg != NULL)
            status = SD2_IEUVALID;
        }

    if ((status != SD2_NOERR) && (fld->flderr != NULL))
        (*(fld->flderr)) (fld, status, errmsg); 

    if (status != SD2_NOERR)
        return(FALSE);
    else
        return(TRUE);

}

/*============== CHECK A CHARACTER AGAINST THE MASK CONDITION ================*/

static BOOL  mask_val(fldptr, key, fposn)    /* Returns TRUE If All OK   */
struct SD2_FIELD    *fldptr;
KEYSTR              *key;
FLEN                fposn;

{
    BOOL    store_key, btemp;
    FLEN    temp, temp1;
    KEYSTR  ktemp;

    store_key = TRUE;


        switch(fldptr->mask[fposn])  /* Check For Relevant Validation */
            {
            case SD2_LITERAL_N:
            case SD2_LITERAL_L:
            case SD2_LITERAL_U:
                switch (fldptr->mask[fposn])
                    {
                    case SD2_LITERAL_N:     /* No Case Conversion     */
                        break;              /* Do Nothing             */
                    case SD2_LITERAL_L:
                        *key = tolower(*key);
                           break;
                    case SD2_LITERAL_U:
                        *key = toupper(*key);
                           break;
                    }
                 break;

            case SD2_ALPHA_N:
            case SD2_ALPHA_L:
            case SD2_ALPHA_U:
                if (isalpha(*key))
                    {
                    switch (fldptr->mask[fposn])
                        {
                        case SD2_ALPHA_N:
                            break;
                        case SD2_ALPHA_L:
                            *key = tolower(*key);
                               break;
                        case SD2_ALPHA_U:
                            *key = toupper(*key);
                               break;
                        } 
                    }
                else
                    store_key = FALSE;
                   break;

            case SD2_ALPHANUM_N:
            case SD2_ALPHANUM_L:
            case SD2_ALPHANUM_U:
                if (isalnum(*key))
                    {
                    switch (fldptr->mask[fposn])
                        {
                        case SD2_ALPHANUM_N:
                            break;
                        case SD2_ALPHANUM_L:
                            *key = tolower(*key);
                               break;
                        case SD2_ALPHANUM_U:
                            *key = toupper(*key);
                               break;
                        } 
                    }
                else
                    store_key = FALSE;
                    break;

            case SD2_BINARY:
                if (*key != '0' && *key != '1')
                    store_key = FALSE;
                    break;

            case SD2_OCTAL:
                if (!isdigit(*key) || (*key > '7'))
                    store_key = FALSE;
                    break;

            case SD2_DECIMAL:
                if (!isdigit(*key))
                    store_key = FALSE;
                    break;

            case SD2_HEX_N:
            case SD2_HEX_L:
            case SD2_HEX_U:
                if (!isxdigit(*key))
                    store_key = FALSE;
                else
                    switch (fldptr->mask[fposn])
                        {
                        case SD2_HEX_N:
                            break;
                        case SD2_HEX_L:
                            *key = tolower(*key);
                            break;
                        case SD2_HEX_U:
                            *key = toupper(*key);
                            break;
                        }  
                break;

            case SD2_FLOATING:
                if (!isdigit(*key) && (*key != '+') && (*key != '-')
                                                  && (*key != '.'))
                    store_key = FALSE;
                    break;

                case SD2_SCIENT_N:
                case SD2_SCIENT_L:
                case SD2_SCIENT_U:
                if (!isdigit(*key) && (*key != '+') && (*key != '-')
                    && (*key != '.') && (*key != 'e') && (*key != 'E'))
                    store_key = FALSE;
                else
                    switch (fldptr->mask[fposn])
                        {
                        case SD2_SCIENT_N:
                            break;
                        case SD2_SCIENT_L:
                            *key = tolower(*key);
                            break;
                        case SD2_SCIENT_U:
                            *key = toupper(*key);
                            break;
                        }  
                    break;

             case SD2_FINANCIAL:
                if (!isdigit(*key) && (*key != '+') && (*key != '-')
                                  && (*key != '.') && (*key != '$'))
                    store_key = FALSE;
                    break;

                case SD2_YN_N:
                case SD2_YN_L:
                case SD2_YN_U:
                if ((toupper(*key) != 'Y') && (toupper(*key) != 'N'))
                    store_key = FALSE;
                else
                    switch (fldptr->mask[fposn])
                        {
                        case SD2_YN_N:
                            break;
                        case SD2_YN_L:
                            *key = tolower(*key);
                            break;
                        case SD2_YN_U:
                            *key = toupper(*key);
                            break;
                        }  
                    break;

            case SD2_LIST0:
            case SD2_LIST1:
            case SD2_LIST2:
            case SD2_LIST3:
            case SD2_LIST4:
            case SD2_LIST5:
            case SD2_LIST6:
            case SD2_LIST7:
            case SD2_LIST8:
            case SD2_LIST9:
                if (fldptr->v_lists != NULL)    /* Only If Enabled    */
                    {
                    temp = (fldptr->mask[fposn]) - '0'; /* Only Works In ASCII*/
                    if (fldptr->v_lists[temp] != NULL)
                        {
                        btemp = FALSE;  /* Scan Literal List And Look */
                        temp1 = 0;      /* For Matching Character     */
                        ktemp = 'x';    /* Dummy So While Below Works */
                         while ((btemp == FALSE) && (ktemp != '\0'))
                            {
                            ktemp = fldptr->v_lists[temp][temp1];
                            if (*key == ktemp)
                                btemp = TRUE;
                            ++temp1;
                            }
                        store_key = store_key && btemp;
                        }
                    }
                break;

             default:           /* Invalid Validation Code, Ignore *key */
                store_key = FALSE;
                break;
            }

    return(store_key);
}