T168_111\appl\Parser\Tspl:第9~第15个文件

expstr.c  、、、、、、、、、、、、、、、、、、、、、、、、、、、

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define EXPSTR_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

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

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XAppVer.h"
#include "XFileSys.h"
#include "XProFile.h"
#include "XCodePage.h"
#include "XFunction.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "TsplFunc.h"
#include "VarMgr.h"
#include "exprpn.h"
#include "exputil.h"
#include "expfmt.h"
#include "expr.h"
#include "error.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(TSPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

BYTE expStrFuncDispatch(BYTE *, BYTE *, BYTE **);
VOID expGetSetting(CHAR *, CHAR *, CHAR *, CHAR *);

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


VOID NextString(BYTE *szTarget, BYTE** pszState)
{
    BYTE szToken[TOKEN_LEN];                /*Token extracted from statement*/
    WORD bStringID;                            /*String ID for accessing variable*/
    BYTE *psTemp, bQuotes, bTemp1[5], bQuit;
    INT bIndex;                                /*Index for Temporary string*/
    INT n;

    bQuotes = 0;
    switch (CheckOperandType(*pszState))    /*Check the type of this token*/
    {
        case CSTRING:                        /*If it is a constant string*/
            Delimitate(szToken, pszState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
            /*Take next token delimitated by the given characters*/
            bIndex = 0;                        /*Initiate index value*/

        //    while (**pszState!='"')            /*Do until the end of string*/
        //    while (**pszState != 0x00 && **pszState != 0x0D && **pszState != '+' && **pszState != ')')
        //    {
        //        bQuotes = 0;
        //        bQuit = 0;
        //        if (bIndex > HUGE_LEN)    /*If the max string length is reached*/
        //        {
        //            wErrorword = OUT_OF_STRING_SPACE;
        //            break;
        //        }
            while ((bTemp1[1] = **pszState ) != '"')
            {
                bQuotes = 0;
                bQuit = 0;
                if (bIndex > STRING_LEN)    /*If the max string length is reached*/
                {
                    wErrorword = OUT_OF_STRING_SPACE;
                    break;
                }
                if (bTemp1[1] == '\\')
                {
                    *pszState += 1;
                    bTemp1[2] = **pszState;
                    bQuotes += 1;
                }
                if (bQuotes == 1)
                {
                    if (bTemp1[2] == '[')
                    {
                        bQuotes += 1;
                        *pszState += 1;
                        bTemp1[3] = **pszState;
                    }
                    else
                    {
                        bQuotes -= 1;
                        **pszState = bTemp1[2];
                        *pszState -= 1;
                    }
                }
                if (bQuotes == 2)
                {
                    if (bTemp1[3] == '"' || bTemp1[3] == 'R' || bTemp1[3] == 'L')
                    {
                        bQuotes += 1;
                        *pszState += 1;
                        bTemp1[4] = **pszState;
                        if (bTemp1[4] == 0x0D || bTemp1[4] == 0x00)
                        {
                            bQuit = 1;
                        }
                    }
                }
                if (bQuotes == 3)
                {
                    if (bTemp1[4] == ']')
                    {
                        bQuotes += 1;
                    }
                }
                if (bQuotes == 4)
                {
                    if (bTemp1[3] == 'R')
                        bTemp1[3] = '\r';
                    if (bTemp1[3] == 'L')
                        bTemp1[3] = '\n';
                    szTarget[bIndex++] = bTemp1[3];
                }
                else
                {
                    if (bQuotes != 0)
                    {
                        if (bQuit == 1)
                        {
                            for (n = 1; n <= bQuotes; n++)
                                szTarget[bIndex++] = bTemp1[n];
                            bQuit = 0;
                            break;
                        }
                        else
                        {
                            for (n = 1; n <= bQuotes + 1; n++)
                                szTarget[bIndex++] = bTemp1[n];
                        }
                    }
                    else
                    {
                        if (bTemp1[1] == '"' && bQuotes == 0)
                        {
                            break;
                        }
                        szTarget[bIndex++] = bTemp1[1];
                    }
                }
                *pszState += 1;
            }    // end while ((bTemp1[1] = **pszState) != '"')
            *pszState += 1;
        //    }    // end while (**pszState != 0x00 && **pszState != 0x0D && **pszState != '+' && **pszState != ')')
        //    *pszState += 1;                                    /*Skip quotation mark*/
            szTarget[bIndex] = 0;                            /*Add a null to target string*/
            break;

        case FUNCTION:                                        /*If it is a function*/
            Delimitate(szToken, pszState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
            /*Take next token delimitated by the given characters*/

            expStrFuncDispatch(szToken, szTarget, pszState);
            /*Call function handler*/
            if (strlen((CHAR *)szTarget) > HUGE_LEN)        /*If the max string length is reached*/
            {
                wErrorword = OUT_OF_STRING_SPACE;
            }
            break;

        case VARIABLE:                                        /*If it is a variable*/
            Delimitate(szToken, pszState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
            /*Take next token delimitated by the given characters*/
            if (CheckVariableType(szToken) == STRING_TYPE)    /*If it is a string*/
            {
                if (*szToken == '@')
                    bCounterUse = TRUE;
                if ((bStringID = CheckGlobalVariable(szToken)) != 0)
                {
                    GetGlobalVariable(bStringID, szTarget);    /*Get a variable value*/
                }
                else
                {
                    bStringID = CheckStringVariable(szToken);    /*Check variable ID*/
                    if (bStringID)                            /*If variable ID is available*/
                    {
                        GetStringVariable(bStringID, szTarget);    /*Get a variable value*/
                    }
                }
                if (strlen((CHAR *)szTarget) > HUGE_LEN)    /*If the max string length is reached*/
                {
                    wErrorword = OUT_OF_STRING_SPACE;
                }
            }
            else                                            /*If it is not a string variable*/
            {
                wErrorword = VARIABLE_NOT_DEFINED;
            }
            break;

        case PARENTHESIS:                                    /*If it is a round bracket */
            Delimitate(szToken, pszState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                        /*Launch another session of expression*/
            if (strlen((CHAR *)szTarget) > HUGE_LEN)        /*If the max string length is reached*/
            {
                wErrorword = OUT_OF_STRING_SPACE;
            }
            break;

        case STRING_DIM:
            GetDimToken(szToken, pszState);
            psTemp = szToken;
            bStringID = CheckStringDimension(&psTemp);        /*Check variable ID*/
            if (bStringID)                                    /*If variable ID is available*/
            {
                GetStringDimension(bStringID, szTarget);    /*Get a variable value*/
                if (strlen((CHAR *)szTarget) > HUGE_LEN)    /*If the max string length is reached*/
                {
                    wErrorword = OUT_OF_STRING_SPACE;
                }
            }
            else
            {
                wErrorword = ARRAY_NOT_DEFINED;
            }
            break;

        default:
            wErrorword = VARIABLE_NOT_DEFINED;                /*Error*/
    }
}

VOID expStringMain(BYTE *szTarget)
{
    BYTE *pTemp;                                        /*Temporary string storage*/
    BYTE bOperator = 0;
    INT Length;

    if ((pTemp = malloc(HUGE_LEN)) == 0)
    {
        wErrorword = OUT_OF_STRING_SPACE;
        return;
    }

    NextString(szTarget, pszStatement[szStatePtr]);
    while (isspace(**pszStatement[szStatePtr]))            /*Skip white space*/
        *pszStatement[szStatePtr] += 1;                    /*Increace pointer to string*/
    while ((wErrorword == NO_ERROR)&&
        (**pszStatement[szStatePtr]!=')')&&
        (**pszStatement[szStatePtr]!=',')&&
        (**pszStatement[szStatePtr]!='\0'))                /*Do until the end of statement*/
    {
        while (isspace(**pszStatement[szStatePtr]))        /*Skip white space*/
            *pszStatement[szStatePtr] += 1;                /*Increace pointer to string*/
        /*Take next token delimitated by the given characters*/
        if (**pszStatement[szStatePtr] == '\0')
        {
            break;
        }
        bOperator = 0;
        while (**pszStatement[szStatePtr] == '=' ||
            **pszStatement[szStatePtr] == '>' ||
            **pszStatement[szStatePtr] == '<' ||
            **pszStatement[szStatePtr] == '+')
        {
            bOperator += (**pszStatement[szStatePtr]);
            *pszStatement[szStatePtr] += 1;                /*Increace pointer to string*/
        }
        switch (bOperator)
        {
            case '=':
                Length = 0;
                while (1)
                {
                    NextString(pTemp + Length, pszStatement[szStatePtr]);
                    while (isspace(**pszStatement[szStatePtr]))    /*Skip white space*/
                        *pszStatement[szStatePtr] += 1;    /*Increace pointer to string*/
                    if (**pszStatement[szStatePtr] == '+')
                        *pszStatement[szStatePtr] += 1;    /*Increace pointer to string*/
                    else
                        break;
                    Length = strlen((CHAR *)pTemp);
                }
                bExpKind = DOUBLE_TYPE;                    /*This is double expression */
                dRetVal = (strcmp((CHAR *)szTarget, (CHAR *)pTemp) == 0) ? 1 : 0;
                break;

            case '>':
                NextString(pTemp, pszStatement[szStatePtr]);
                bExpKind = DOUBLE_TYPE;                    /*This is double expression */
                dRetVal = (strcmp((CHAR *)szTarget, (CHAR *)pTemp) > 0) ? 1 : 0;
                break;

            case '<':
                NextString(pTemp, pszStatement[szStatePtr]);
                bExpKind = DOUBLE_TYPE;                    /*This is double expression */
                dRetVal = (strcmp((CHAR *)szTarget, (CHAR *)pTemp) < 0) ? 1 : 0;
                break;

            case '>' + '<':
                NextString(pTemp, pszStatement[szStatePtr]);
                bExpKind = DOUBLE_TYPE;                    /*This is double expression */
                dRetVal = (strcmp((CHAR *)szTarget, (CHAR *)pTemp) == 0) ? 0 : 1;
                break;

            case '=' + '<':
                NextString(pTemp, pszStatement[szStatePtr]);
                bExpKind = DOUBLE_TYPE;                    /*This is double expression */
                dRetVal = (strcmp((CHAR *)szTarget, (CHAR *)pTemp) > 0) ? 0 : 1;
                break;

            case '=' + '>':
                NextString(pTemp, pszStatement[szStatePtr]);
                bExpKind = DOUBLE_TYPE;                    /*This is double expression */
                dRetVal = (strcmp((CHAR *)szTarget, (CHAR *)pTemp) < 0) ? 0 : 1;
                break;

            case '+':
                NextString(pTemp, pszStatement[szStatePtr]);
                strcat((CHAR *)szTarget, (CHAR *)pTemp);
                if (strlen((CHAR *)szTarget) > HUGE_LEN)    /*If the max string length is reached*/
                    wErrorword = OUT_OF_STRING_SPACE;
                break;

            case 0:
            //    break;

            default:
                wErrorword = UNKNOW_OPERATOR;
                break;
        }
    }
    *pszStatement[szStatePtr] += 1;                        /*Skip the end of statement*/

    free(pTemp);
}

/******************************************************************************
*
* Function:
* extStrFuncDispatch
*
* Description:
* This function dispatch string functions.
*
* Input:
* 1)Function token, 2)Pointer to target string, 3)Pointer to pointer to statement
*
* Output:
* If succeed return 0; else return nozero.
*
******************************************************************************/
BYTE expStrFuncDispatch(
BYTE *szToken,                    /*Pointer to function identifier*/
BYTE *szTarget,                    /*Pointer to target string*/
BYTE **pszState)                /*pointer to pointer to statement*/
{
    BYTE *pTemp;                /*Temporary string storage*/
    INT temp1, temp2;            /*Temporary int storage*/
    DOUBLE temp3;                /*Temporary double storage*/
    DATE date;                    /*Temporary date/time storage*/
    CHAR AppName[32], Section[32], Key[32];

    if ((pTemp = malloc(HUGE_LEN)) == 0)
    {
        wErrorword = OUT_OF_STRING_SPACE;
        return 0;
    }

    switch (CheckFunctionType(szToken))    /*Check function type*/
    {
        case FUNC_S_CHR:                                /*If CHR$()*/
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
            sprintf((CHAR *)szTarget, "%c", temp1);        /*Convert integer to character*/
            break;

        case FUNC_S_DATEADD:                            /* DATEADD$(INTERVAL$, NUMBER, DATE) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
        /* Required. String expression representing the time interval you want to add. */
            expStringMain(pTemp);
        /* Required. Numeric expression that is the number of intervals you want to add. */
            PushOperator('\0');
            temp1 = (INT)expDoubleMain();
        /* Required. Date value that you want to evaluate. */
            if (CheckExpressionType(*pszState) == NUMERAL)    /*Numeric expression*/
            {
                PushOperator('\0');                        /*Make a tag in RPN buffer*/
                temp3 = expDoubleMain();
                date = expDoubleToDate(temp3);            /*Convert the double to date/time*/
            }
            else                                        /*String expression*/
            {
                expStringMain(szTarget);                /*Launch another session of expression*/
                date = expStringToDate(szTarget);        /*Convert the string to date/time*/
            }
            if (expDateAdd((CHAR *)pTemp, temp1, &date))
                expDateToString(szTarget, date);
            else
                wErrorword = SYNTAX_ERROR;
            break;

        case FUNC_S_FORMAT:                                /* FORMAT$(EXP[, FMT$]) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            *pTemp = '\0';    /*Use date and time formats or numeric formats*/
            if (CheckExpressionType(*pszState) == NUMERAL)    /*Numeric expression*/
            {
                PushOperator('\0');                        /*Make a tag in RPN buffer*/
                temp3 = expDoubleMain();
                date = expDoubleToDate(temp3);            /*Convert the double to date/time*/
                expDoubleToString(szTarget, temp3);        /*Convert the double to string*/
            }
            else                                        /*String expression*/
            {
                expStringMain(szTarget);                /*Launch another session of expression*/
                temp3 = expStringToDouble(szTarget);    /*Convert the string to double*/
                date = expStringToDate(szTarget);        /*Convert the string to date/time*/
            }
            if (*(*pszState - 1) == ',')                /*Optional Format*/
                expStringMain(pTemp);
            expFormat((CHAR *)szTarget, date, temp3, (CHAR *)pTemp);
            break;

        case FUNC_S_FREAD:
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            temp1 = (INT)expDoubleMain();                /*Get file handle no.*/
            temp2 = (INT)expDoubleMain();                /*Get the count*/
            if (temp2 > HUGE_LEN)                        /*If larger than string length*/
            {
                wErrorword = OUT_OF_STRING_SPACE;
            }
            while (temp2)
            {
                if (temp1 == 0)
                    *szTarget = (BYTE)Fgetc(UseHandle_0);
                else if (temp1 == 1)
                    *szTarget = (BYTE)Fgetc(UseHandle_1);
                temp2--;
                szTarget += 1;
            }
            *(szTarget) = 0;
            break;

        case FUNC_S_GETSETTING:                            /* GETSETTING$(APP$, SEC$, KEY$[, DEF$]) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
        /* Required. String expression containing the name of the application or project whose key setting is requested. */
            expStringMain(pTemp);
            strncpy(AppName, (CHAR *)pTemp, sizeof(AppName));
        /* Required. String expression containing the name of the section in which the key setting is found. */
            expStringMain(pTemp);
            strncpy(Section, (CHAR *)pTemp, sizeof(Section));
        /* Required. String expression containing the name of the key setting to return. */
            expStringMain(pTemp);
            strncpy(Key, (CHAR *)pTemp, sizeof(Key));
        /* Optional. Expression containing the value to return if no value is set in the Key setting.
        If omitted, Default is assumed to be a zero-length string (""). */
            strcpy((CHAR *)szTarget, "");
            if (*(*pszState - 1) == ',')
                expStringMain(szTarget);
            expGetSetting((CHAR *)szTarget, AppName, Section, Key);
            break;

        case FUNC_S_INP:
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
            *szTarget = DirectNextByte();
            *(szTarget + 1) = 0;
            break;

        case FUNC_S_LEFT:                                /*If LEF$()*/
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch another session of expression*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
            if (temp1 < strlen((CHAR *)szTarget))        /*If larger than string length*/
                szTarget[temp1] = 0;                    /*Trim the length of string*/
            break;

        case FUNC_S_LSTRIM:                                /* LSTRIM$(STR$) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(pTemp);                    /*Launch a string expression*/
            /* Remove leading Chars 0x00 ~ 0x20 */
            for (temp1 = 0; *(pTemp + temp1) && *(pTemp + temp1) <= 0x20; temp1++);
            strcpy((CHAR *)szTarget, (CHAR *)pTemp + temp1);
           break;

        case FUNC_S_LTRIM:                                /* LTRIM$(STR$[, LIST$]) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch a string expression*/
            strcpy((CHAR *)pTemp, " \t\n\v\f\r");        /*Standard white-space character*/
            /* Optionally, the stripped characters can also be specified */
            if (*(*pszState - 1) == ',')
                expStringMain(pTemp);
            /* Remove leading characters */
            for (temp1 = 0; *(szTarget + temp1) && strchr((CHAR *)pTemp, *(szTarget + temp1)); temp1++);
            memmove(szTarget, szTarget + temp1, strlen((CHAR *)szTarget + temp1) + 1);
            break;

        case FUNC_S_MID:                                /*If MID$()*/
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch another session of expression*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
            if ((temp1 > strlen((CHAR *)szTarget)) || (temp1 == 0))    /*If larger than string length or zero*/
                wErrorword = SYNTAX_ERROR;
            temp1 -= 1;    /*BASIC array is based on 1, so decrease 1 to match C convention*/
            strcpy((CHAR *)szTarget, (CHAR *)(szTarget + temp1));    /*Extract the portion needed*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
            if (temp1 < strlen((CHAR *)szTarget))        /*If larger than string length*/
                szTarget[temp1] = 0;                    /*Trim the length of string*/
            break;

        case FUNC_S_NOW:                                /* NOW$()*/
            Delimitate(NULL, pszState, (BYTE *)")", 1);
            *pszState += 1;
            GetGlobalVariable(GLO_NOW, szTarget);
            break;

        case FUNC_S_RIGHT:                                /*If RIGHT$()*/
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch another session of expression*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
        //    if (bTemp > strlen((CHAR *)szTarget))        /*If larger than string length*/
        //        wErrorword = SYNTAX_ERROR;
            temp1 = strlen((CHAR *)szTarget) - temp1;    /*Get the position of the string needed*/
            if (temp1 > strlen((CHAR *)szTarget) || temp1 < 0)      
                temp1 = 0;
            strcpy((CHAR *)szTarget, (CHAR *)(szTarget + temp1));    /*Extract the portion needed*/
            break;

        case FUNC_S_RSTRIM:                                /* RSTRIM$(STR$) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch a string expression*/
            /* Remove leading Chars 0x00 ~ 0x20 */
            for (temp1 = strlen((CHAR *)szTarget); temp1 && *(pTemp + temp1 -1) <= 0x20; temp1--);
            *(szTarget + temp1) = '\0';
            break;

        case FUNC_S_RTRIM:                                /* RTRIM$(STR$[, LIST$]) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch a string expression*/
            strcpy((CHAR *)pTemp, " \t\n\v\f\r");        /*Standard white-space character*/
            /* Optionally, the stripped characters can also be specified */
            if (*(*pszState - 1) == ',')
                expStringMain(pTemp);
            /* Remove trailing characters */
            for (temp1 = strlen((CHAR *)szTarget); temp1 && strchr((CHAR *)pTemp, *(szTarget + temp1 - 1)); temp1--);
            *(szTarget + temp1) = '\0';
            break;

        case FUNC_S_SPC:                                /* SPC$() */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            temp1 = (INT)expDoubleMain();                /*Launch another session of expression*/
            if (temp1 > HUGE_LEN)                        /*If larger than string length*/
                wErrorword = OUT_OF_STRING_SPACE;
            szTarget[temp1] = 0;                        /*Add a null to the end of string*/
            while (temp1)
                szTarget[--temp1] = ' ';                /*Put ' ' in target string*/
            break;

        case FUNC_S_STR:                                /*If STR$()*/
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            PushOperator('\0');                            /*Make a tag in RPN buffer*/
            expDoubleToString(szTarget, expDoubleMain());
            break;

        case FUNC_S_STRIM:                                /* STRIM$(STR$) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(pTemp);                        /*Launch a string expression*/
            /* Remove leading Chars 0x00 ~ 0x20 */
            for (temp1 = 0; *(pTemp + temp1) && *(pTemp + temp1) <= 0x20; temp1++);
            strcpy((CHAR *)szTarget, (CHAR *)pTemp + temp1);
            /* Remove trailing Chars 0x00 ~ 0x20 */
            for (temp1 = strlen((CHAR *)szTarget); temp1 && *(szTarget + temp1 - 1) <= 0x20; temp1--);
            *(szTarget + temp1) = '\0';
            break;

        case FUNC_S_TRIM:                                /* TRIM$(STR$[, LIST$]) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch a string expression*/
            strcpy((CHAR *)pTemp, " \t\n\v\f\r");        /*Standard white-space character*/
            /* Optionally, the stripped characters can also be specified */
            if (*(*pszState - 1) == ',')
                expStringMain(pTemp);
            /* Remove leading characters */
            for (temp1 = 0; *(szTarget + temp1) && strchr((CHAR *)pTemp, *(szTarget + temp1)); temp1++);
            memmove(szTarget, szTarget + temp1, strlen((CHAR *)szTarget + temp1) + 1);
            /* Remove trailing characters */
            for (temp1 = strlen((CHAR *)szTarget); temp1 && strchr((CHAR *)pTemp, *(szTarget + temp1 - 1)); temp1--);
            *(szTarget + temp1) = '\0';
            break;

        case FUNC_S_XOR:                                /* XOR$(STR1$, STR2$) */
            Delimitate(NULL, pszState, (BYTE *)"(", 1);
            /*Take next token delimitated by the given characters*/
            expStringMain(szTarget);                    /*Launch a string expression*/
            expStringMain(pTemp);                        /*Launch a string expression*/
            temp1 = MIN(strlen((CHAR *)szTarget), strlen((CHAR *)pTemp));
            while (--temp1 >= 0)
                *(szTarget + temp1) ^= *(pTemp + temp1);
            break;

        default:
            wErrorword = ILLEGAL_FUNCTION_CALL;
    }
    free(pTemp);
    return 0;
}

/******************************************************************************
*
* Function:
*  expGetSetting
*
* Description:
*  Returns a key setting value from an application's entry in the Printer.
*
* Input:
*  Target  - Pointer to target string
*  AppName - Application or project whose key setting is requested. 
*  Section - Section in which the key setting is found. 
*  Key     - Key setting to return. 
*
******************************************************************************/
VOID expGetSetting(CHAR *Target, CHAR *AppName, CHAR *Section, CHAR *Key)
{
    BOOL TruncateEndingZero = FALSE;
    INT n;

//sysprintf("Enter expGetSetting()...\n"); // ch_20220315    

    if (strcmp(AppName, "SYSTEM") == 0)
    {
        if (strcmp(Section, "INFORMATION") == 0)
        {
            if (strcmp(Key, "DPI") == 0)
            {
                sprintf(Target, "%f", TPH_DPI);
                TruncateEndingZero = TRUE;
            }
            if (strcmp(Key, "MODEL") == 0)
                strcpy(Target, (CHAR *)ModelName);
            if (strcmp(Key, "SERIAL") == 0)
                strcpy(Target, (CHAR *)pPrintRec->SerialNumberName);
            if (strcmp(Key, "VERSION") == 0)
                strcpy(Target, (CHAR *)VerName);
            if (strcmp(Key, "CHECKSUM") == 0)
                sprintf(Target, "%08X", CalculateCheckSum());
        }
        if (strcmp(Section, "RECORD") == 0)
        {
            if (strcmp(Key, "MILAGE") == 0)
                sprintf(Target, "%d", pPrintRec->DotMilage);
            if (strcmp(Key, "CUT COUNTER") == 0)
                sprintf(Target, "%d", pPrintRec->CutCounter);
        }
    }
    if (strcmp(AppName, "TCF") == 0)
    {
        CHAR string[128];
        FLOAT value;

        if (strcmp(Section, "STRING") == 0 && GetProfileString(Key, string))
            strcpy(Target, string);
        if (strcmp(Section, "BOOLEAN") == 0 && GetProfileInt(Key, &value))
            strcpy(Target, (INT)value ? "1" : "0");
        if (strcmp(Section, "VALUE") == 0 && GetProfileInt(Key, &value))
        {
            sprintf(Target, "%f", value);
            TruncateEndingZero = TRUE;
        }
    }
    if (strcmp(AppName, "FILE") == 0)
    {
        _eFileDevice dev = NO_SELECT_DEVICE;

        if (strcmp(Section, "RAM") == 0 || strcmp(Section, "DRAM") == 0)
            dev = DRAM_DEVICE;
        if (strcmp(Section, "F") == 0 || strcmp(Section, "FLASH") == 0)
            dev = FLASH_DEVICE;
        if (strcmp(Section, "E") == 0 || strcmp(Section, "CARD") == 0)
            dev = CARD_DEVICE;

        if (dev != NO_SELECT_DEVICE)
        {
            if (strcmp(Key, "CAPACITY") == 0)
                sprintf(Target, "%d", TotalSpace(dev));
            if (strcmp(Key, "AVAILABLE") == 0)
                sprintf(Target, "%d", FreeSpace(dev));
        }
#if defined(FLASH_MCARD_MODEL) || defined(SDCARD_MODEL)
        if (dev == CARD_DEVICE)
        {
            if (strcmp(Key, "INSTALLED") == 0)
                strcpy(Target, IsCardDevice() ? "1" : "0");
        }
#endif
    }
    if (strcmp(AppName, "CONFIG") == 0)
    {
        if (strcmp(Section, "NET") == 0)
        {
#if defined(NUTNET)
            if (strcmp(Key, "MAC ADDRESS") == 0)
                sprintf(Target, "%02X-%02X-%02X-%02X-%02X-%02X",
                    pPrintCfg->confnet.cdn_mac[0], pPrintCfg->confnet.cdn_mac[1],
                    pPrintCfg->confnet.cdn_mac[2], pPrintCfg->confnet.cdn_mac[3],
                    pPrintCfg->confnet.cdn_mac[4], pPrintCfg->confnet.cdn_mac[5]);

            if (strcmp(Key, "IP ADDRESS") == 0)
                strcpy(Target, inet_ntoa(GetNetworkIP(ITEM_IP_ADDRESS)));
            if (strcmp(Key, "SUBNET MASK") == 0)
                strcpy(Target, inet_ntoa(GetNetworkIP(ITEM_SUBNET_MASK)));
            if (strcmp(Key, "DEFAULT GATEWAY") == 0)
                strcpy(Target, inet_ntoa(GetNetworkIP(ITEM_GATEWAY)));
#endif
        }
        if (strcmp(Section, "COM1") == 0)
        {
            CONST STATIC CHAR *Baud[] = { "0","1200","2400","4800","9600","19200","38400","57600","115200" };
            CONST STATIC CHAR *Parity[] = { "NONE","ODD","EVEN" };
            CONST STATIC CHAR *DataBits[] = { "7","8" };
            CONST STATIC CHAR *Stop[] = { "1","2" };

            if (strcmp(Key, "BAUD RATE") == 0)
                strcpy(Target, Baud[pPrintCfg->UartSetting.Baud]);
            if (strcmp(Key, "DATA BIT") == 0)
                strcpy(Target, DataBits[pPrintCfg->UartSetting.DataBits]);
            if (strcmp(Key, "PARITY") == 0)
                strcpy(Target, Parity[pPrintCfg->UartSetting.Parity]);
            if (strcmp(Key, "STOP BIT") == 0)
                strcpy(Target, Stop[pPrintCfg->UartSetting.Stop]);
        }
        if (strcmp(Section, "SENSOR") == 0)
        {
            CONST STATIC CHAR *Sensor[] = { "GAP","BLINE","CONTINUOUS","CONTINUOUS","CONTINUOUS" };

            if (strcmp(Key, "SENSOR TYPE") == 0)
                strcpy(Target, Sensor[pPrintCfg->SensorMode]);

            if (strcmp(Key, "CARRIAGE") == 0)
                strcpy(Target, pPrintCfg->CarriageOpen ? "1" : "0");

            if (strcmp(Key, "GAP INTENSION") == 0)
                sprintf(Target, "%u", pPrintCfg->GapInten);
            if (strcmp(Key, "BLINE INTENSION") == 0)
            {
                    debug_printf("J:%d,",pPrintCfg->BlineInten);
                sprintf(Target, "%u", pPrintCfg->BlineInten);
                SendPrintf("%d\n",pPrintCfg->BlineInten);
            }
            if (strcmp(Key, "CONTINUOUS INTENSION") == 0)
                sprintf(Target, "%u", pPrintCfg->ContinuousInten);
        }
        if (strcmp(Section, "TSPL") == 0)
        {
            CONST STATIC CHAR *PrintMode[] = { "NONE","TEAR OFF","PEEL OFF","CUT OFF" };

            if (strcmp(Key, "PRINT MODE") == 0)
                strcpy(Target, PrintMode[pPrintCfg->PrintOutMode]);

            if (strcmp(Key, "DENSITY") == 0)
            {
                sprintf(Target, "%f", pPrintCfg->fDensity);
                TruncateEndingZero = TRUE;
            }
            if (strcmp(Key, "PAPER SIZE") == 0)
                sprintf(Target, "%d", (INT)pPrintCfg->fPaperSize);
            if (strcmp(Key, "GAP SIZE") == 0)
                sprintf(Target, "%d", (INT)pPrintCfg->fGapSize);
            if (strcmp(Key, "BLINE SIZE") == 0)
                sprintf(Target, "%d", (INT)pPrintCfg->fBlineSize);

            if (strcmp(Key, "DIRECTION") == 0)
                strcpy(Target, pPrintCfg->Direction ? "1" : "0");
            if (strcmp(Key, "MIRROR") == 0)
                strcpy(Target, pPrintCfg->Mirror ? "1" : "0");
            if (strcmp(Key, "RIBBON") == 0)
                strcpy(Target, pPrintCfg->RibbonFlag ? "1" : "0");
            if (strcmp(Key, "REPRINT") == 0)
                strcpy(Target, pPrintCfg->Reprint ? "1" : "0");

            if (strcmp(Key, "CUT PIECE") == 0)
                sprintf(Target, "%u", pPrintCfg->CutterPieces);

            if (strcmp(Key, "PAPER WIDTH") == 0)
                sprintf(Target, "%u", pPrintCfg->PaperWidth);
            if (strcmp(Key, "LIMIT FEED") == 0)
                sprintf(Target, "%u", pPrintCfg->LimitFeed);

            if (strcmp(Key, "OFFSET") == 0)
                sprintf(Target, "%d", pPrintCfg->OffsetDis);
            if (strcmp(Key, "REFERENCE X") == 0)
                sprintf(Target, "%d", pPrintCfg->ReferenceX);
            if (strcmp(Key, "REFERENCE Y") == 0)
                sprintf(Target, "%d", pPrintCfg->ReferenceY);
            if (strcmp(Key, "SHIFT X") == 0)
                sprintf(Target, "%d", pPrintCfg->ShiftDisX);
            if (strcmp(Key, "SHIFT Y") == 0)
                sprintf(Target, "%d", pPrintCfg->ShiftDisY);

            if (strcmp(Key, "SPEED") == 0)
                strcpy(Target, ToSpeedString(pPrintCfg->Speed));
            if (strcmp(Key, "COUNTRY CODE") == 0)
                strcpy(Target, CountryNameTable[pPrintCfg->Country]);
            if (strcmp(Key, "CODEPAGE") == 0)
                strcpy(Target, CodePageNameTable[pPrintCfg->CodePage]);
        }
    }
    if (TruncateEndingZero)
    {
        /* Remove trailing zero */
        for (n = strlen(Target); n && *(Target + n - 1) == '0'; n--);
        for (; n && *(Target + n - 1) == '.'; n--);
        *(Target + n) = '\0';
    }

sysprintf("Leave expGetSetting() with spd = %d.\n", ToSpeedString(pPrintCfg->Speed)); // ch_20220315    
}

#endif

exputil.c   

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define EXPUTIL_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

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

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "..\ParserUtil.h"
#include "expr.h"
#include "exputil.h"
#include "VarMgr.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(TSPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC CONST LONG MonthDays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
STATIC CONST LONG YearDays[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };

STATIC CONST BYTE *aszFunction[] =
{
    "ABS",
    "ASC",
    "BARCODEPIXEL",
    "DATEADD",
    "EOF",
    "FPOS",
    "FRE",
    "GETKEY",
    "GETSENSOR",
    "INSTR",
    "INT",
    "LEN",
    "LOB",
    "LOC",
    "LOF",
    "NOW",
    "POS",
    "RND",
    "STRCOMP",
    "TEXTPIXEL",
    "VAL",

    "CHR$",
    "DATEADD$",
    "FORMAT$",
    "FREAD$",
    "GETSETTING$",
    "INP$",
    "LEFT$",
    "LSTRIM$",
    "LTRIM$",
    "MID$",
    "NOW$",
    "RIGHT$",
    "RSTRIM$",
    "RTRIM$",
    "SPC$",
    "STR$",
    "STRIM$",
    "TRIM$",
    "XOR$",
};

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/******************************************************************************
*
* Function:
* IsLeap
*
* Description:
* This function check if a year specified is a leap year.
*
* Input:
* A integer value representing years
*
* Output:
* If a year is a leap year, return TRUE; else return FALSE.
*
******************************************************************************/
STATIC BOOL IsLeap(LONG Year)
{
    if (Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0))
        return TRUE;
    return FALSE;
}

/******************************************************************************
*
* Function:
* IsNumeral
*
* Description:
* This function check whether the token is a numeral.
*
* Input:
* Pointer to the token
*
* Output:
* If the token is a numeral, return TRUE; else return FALSE.
*
******************************************************************************/
STATIC BOOL IsNumeral(BYTE *szToken)
{
    if ((*szToken == '+') || (*szToken == '-'))
    /*If the first character is a sign character*/
    {
        szToken += 1;            /*Increase the pointer*/
    }

    if (isdigit(*szToken))        /*If the next character is a digit*/
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/******************************************************************************
*
* Function:
* CheckTable
*
* Description:
* This function check the same character in the table.
*
* Input:
* 1)Pointer to the table, 2)The character to checked.
*
* Output:
* If there is a same character in the table, return 1, else return 0;
*
******************************************************************************/
STATIC BYTE CheckTable(BYTE *pTable, BYTE bChar)
{
    if (!bChar)                    /*If it is a null character, return 1*/
        return 1;

    while (*pTable)
    {
        if (*pTable == bChar)    /*If the character found in the table, return 1*/
            return 1;
        else
            pTable+=1;
    }
    return 0;                    /*If the character not found in the table, return 0*/
}

/******************************************************************************
*
* Function:
* expStringToDouble
*
* Description:
* This function convert a null-terminated string to double floating point.
*
* Input:
* Text string match following format:
* [whitespace][sign][ddd].[ddd][e|E[sign]ddd]
*
* Output:
* The converted value of the input string
*
******************************************************************************/
DOUBLE expStringToDouble(BYTE *szString)
{
    DOUBLE Value;

    /* Call ANSI C standard liberary */
    Value = atof((CHAR *)szString);
    return Value;
}

/******************************************************************************
*
* Function:
* expDoubleToString
*
* Description:
* This function convert double floating point to a null-terminated string.
*
* Input:
* 1)converted string, 2)Double floating point
*
* Output:
* Converted string length
*
******************************************************************************/
INT expDoubleToString(BYTE *szString, DOUBLE Value)
{
    INT n;

    /* Call ANSI C standard liberary */
    sprintf((CHAR *)szString, "%f", Value);
    /* Remove trailing zero */
    for (n = strlen((CHAR *)szString); n && *(szString + n - 1) == '0'; n--);
    for (; n && *(szString + n - 1) == '.'; n--);
    *(szString + n) = '\0';
    return n;
}

/******************************************************************************
*
* Function:
* expDateToDouble
*
* Description:
* This function convert date/time to double floating point.
*
* Input:
* 1)An expression representing the date/time
*
* Output:
* Converted value
*
******************************************************************************/
DOUBLE expDateToDouble(DATE Date)
{
    LONG Days = SINCE_0;
    LONG Secs = (Date.Hour * 3600) + (Date.Minute * 60) + Date.Second;
    LONG MaxDays;

    for (; Date.Month > 12; Date.Month -= 12, Date.Year += 1);
    for (; Date.Month <= 0; Date.Month += 12, Date.Year -= 1);

    MaxDays = (IsLeap(Date.Year) && Date.Month == 2) ? 29 : MonthDays[Date.Month - 1];
    if (Date.DayMonth > MaxDays)
        Date.DayMonth = MaxDays;

    Date.DayYear = YearDays[Date.Month - 1] + Date.DayMonth;
    if (IsLeap(Date.Year) && Date.Month > 2)
        Date.DayYear += 1;

    Days += (Date.Year * 365) + Date.DayYear - 1;
    Days += (Date.Year / 4) + (Date.Year / 400) - (Date.Year / 100);
    return (DOUBLE)Days + (DOUBLE)Secs / SEC_PER_DAY;
}

/******************************************************************************
*
* Function:
* expDoubleToDate
*
* Description:
* This function convert double floating point to date/time.
*
* Input:
* 1)Double floating point
*
* Output:
* Converted date/time
*
******************************************************************************/
DATE expDoubleToDate(DOUBLE Value)
{
    LONG Days = (LONG)Value;
    LONG Secs = (Value - Days) * SEC_PER_DAY;
    LONG MaxDays;
    DATE Date;

    Date.DateUse = FALSE;
    Date.TimeUse = FALSE;

    /* Check out of range */
    if (Days < SINCE_100 || Days > SINCE_9999)
        return Date;
    Days -= SINCE_100;

    Date.Second = (Secs % 60);
    Date.Minute = (Secs / 60) % 60;
    Date.Hour   = (Secs / 3600);

    Date.DayWeek = ((5 + Days) % 7) + 1;

    for (Date.Year = 100; ; Date.Year++)
    {
        MaxDays = IsLeap(Date.Year) ? 366 : 365;
        if (Days < MaxDays)
            break;
        Days -= MaxDays;
    }
    Date.DayYear = Days + 1;

    for (Date.Month = 1; ; Date.Month++)
    {
        MaxDays = (IsLeap(Date.Year) && Date.Month == 2) ? 29 : MonthDays[Date.Month - 1];
        if (Days < MaxDays)
            break;
        Days -= MaxDays;
    }
    Date.DayMonth = Days + 1;

    Date.DateUse = TRUE;
    Date.TimeUse = TRUE;
    return Date;
}

/******************************************************************************
*
* Function:
* expDateToString
*
* Description:
* This function convert date/time to a null-terminated string.
*
* Input:
* 1)converted string, 2)An expression representing the date/time
*
* Output:
* Converted string length
*
******************************************************************************/
INT expDateToString(BYTE *szString, DATE Date)
{
    LONG Hour12 = (Date.Hour % 12) ? (Date.Hour % 12) : 12;
    INT n = 0;

    if (Date.DateUse)
        n += sprintf((CHAR *)szString, "%u/%u/%04u", Date.Month, Date.DayMonth, Date.Year);
    if (Date.TimeUse)
        n += sprintf((CHAR *)szString + n, "%s%u:%02u:%02u %s", Date.DateUse ? " " : "",
            Hour12, Date.Minute, Date.Second, (Date.Hour < 12) ? "AM" : "PM");

    return n;
}

/******************************************************************************
*
* Function:
* expStringToDate
*
* Description:
* This function convert a null-terminated string to date/time.
*
* Input:
* 1)Pointer to the string
*
* Output:
* Converted date/time
*
******************************************************************************/
DATE expStringToDate(BYTE *szString)
{
    LONG DateField[3], TimeField[3], MaxDays;
    CHAR *cp = (CHAR *)szString;
    INT Dates = 0, Times = 0, Arounds = 0;
    BOOL DateTime = FALSE;
    DATE Date;

    /* default date vaule */
    Date = expDoubleToDate(0);
    Date.DateUse = FALSE;
    Date.TimeUse = FALSE;

#define GetNumber(p) \
    atol(p); for (; *p && isdigit(*p); p++); for (; *p && isspace(*p); p++);

    while (*cp)
    {
        for (; *cp && isspace(*cp); cp++);
        if (isdigit(*cp))
        {
            LONG Number = GetNumber(cp);

            DateTime = FALSE;
            if (Dates == 0 && (*cp == '/' || *cp == '-'))
            {
                for (cp += 1; *cp && isspace(*cp); cp++);
                if (!isdigit(*cp))
                    break;
                DateField[Dates++] = Number;
                DateField[Dates++] = GetNumber(cp);
                if (*cp == '/' || *cp == '-')
                {
                    for (cp += 1; *cp && isspace(*cp); cp++);
                    if (!isdigit(*cp))
                        break;
                    DateField[Dates++] = GetNumber(cp);
                }
                DateTime = TRUE;
            }
            else if (Times == 0 && (*cp == ':' || *cp == '.'))
            {
                for (cp += 1; *cp && isspace(*cp); cp++);
                if (!isdigit(*cp))
                    break;
                TimeField[Times++] = Number;
                TimeField[Times++] = GetNumber(cp);
                if (*cp == ':' || *cp == '.')
                {
                    for (cp += 1; *cp && isspace(*cp); cp++);
                    if (!isdigit(*cp))
                        break;
                    TimeField[Times++] = GetNumber(cp);
                }
                DateTime = TRUE;
            }
            else
                break;
        }
        else if (Arounds == 0 && toupper(*cp) == 'A')
        {
            Arounds = 1;    /* forenoon */
            if (toupper(*++cp) == 'M')
                cp++;
        }
        else if (Arounds == 0 && toupper(*cp) == 'P')
        {
            Arounds = 2;    /* afternoon */
            if (toupper(*++cp) == 'M')
                cp++;
        }
        else
        {
            DateTime = FALSE;
            break;
        }
    }

    if (Dates != 0)
    {
        if (Dates < 3)
            DateField[2] = (LONG)GetGlobalVariable(GLO_YEAR, _NULL);
        Date.Year = DateField[2];
        if (Date.Year < 100)
            Date.Year = (Date.Year < 30) ? (Date.Year + 2000) : (Date.Year + 1900);

        Date.Month = DateField[0];
        Date.DayMonth = DateField[1];
        if (Date.Month > 12)
        {
            Date.Month = DateField[1];
            Date.DayMonth = DateField[0];
        }

        /* Check out of range */
        if (Date.Year > 9999 || Date.Month > 12 || Date.Month == 0 || Date.DayMonth == 0)
            DateTime = FALSE;
        MaxDays = (IsLeap(Date.Year) && Date.Month == 2) ? 29 : MonthDays[Date.Month - 1];
        if (Date.DayMonth > MaxDays)
            DateTime = FALSE;

        Date.DayYear = YearDays[Date.Month - 1] + Date.DayMonth;
        if (IsLeap(Date.Year) && Date.Month > 2)
            Date.DayYear += 1;

        Date.DayWeek = Date.Year + Date.DayYear - 1;
        Date.DayWeek += (Date.Year / 4) + (Date.Year / 400) - (Date.Year / 100);
        Date.DayWeek = (Date.DayWeek % 7) + 1;
    }

    if (Times != 0)
    {
        Date.Hour = TimeField[0];
        if (Arounds)    /* is 12-hour clock */
            Date.Hour = (Date.Hour % 12) + (Arounds - 1) * 12;
        Date.Minute = TimeField[1];
        if (Times == 3)
            Date.Second = TimeField[2];

        /* Check out of range */
        if (Date.Hour > 23 || Date.Minute > 59 || Date.Second > 59)
            DateTime = FALSE;
    }

    if (DateTime == FALSE)
    {
        if (strspn((CHAR *)szString, "-123456789.0") != strlen((CHAR *)szString))
            return Date;
        return expDoubleToDate(expStringToDouble(szString));
    }

    Date.DateUse = Dates ? TRUE : FALSE;
    Date.TimeUse = Times ? TRUE : FALSE;
    return Date;
}

/******************************************************************************
*
* Function:
* CheckExpressionType
*
* Description:
* This function check expression type.
*
* Input:
* Pointer to pointer to statement
*
* Output:
* Expression type
*
******************************************************************************/
BYTE CheckExpressionType(BYTE* szState)
{
    BYTE szToken[TOKEN_LEN];    /*Token extracted from statement*/
    BYTE bOperandType, bOperatorType, bTemp1[5], bQuotes;
    WORD wTemp;

    bOperandType = 0;
    bQuotes = 0;

    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 0);
    if ((*szToken == '+') || (*szToken == '-'))
    {
        Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
    }

    while (1)
    {
        Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 0);
        if ((*szToken == '+') || (*szToken == '-'))
        {
            Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
        }
        else
        {
            switch (CheckOperandType(szState))  /*Check the type of this token*/
            {
                case VARIABLE:        /*If it is a variable*/
                    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
                    if (CheckVariableType(szToken) == STRING_TYPE)    /*If it is a string*/
                    {
                        bOperandType = STRING_TYPE;
                    }
                    else
                    {
                        bOperandType = NUMERAL;
                    }
                    break;

                case FUNCTION:        /*If it is a function*/
                    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
                    GetDimToken(NULL, &szState);
                    if (CheckVariableType(szToken) == STRING_TYPE)    /*If it is a string*/
                    {
                        bOperandType = STRING_TYPE;
                    }
                    else
                    {
                        bOperandType = NUMERAL;
                    }
                    break;

                case INTEGER_DIM:
                case FLOAT_DIM:
                case DOUBLE_DIM:
                    bOperandType = NUMERAL;
                    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
                    GetDimToken(szToken, &szState);
                    break;

                case NUMERAL:        /*If it is a numeral*/
                    bOperandType = NUMERAL;
                    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
                    break;

                case STRING_DIM:
                    bOperandType = STRING_TYPE;
                    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
                    GetDimToken(szToken, &szState);
                    break;

                case CSTRING:        /*If it is a constant string*/
                    bOperandType = STRING_TYPE;
                    wTemp = 0;    /*Used as a counter*/
                    Delimitate(szToken, &szState, (BYTE *)"\"", 1);

                    while ((bTemp1[1] = *szState) != '"')    /*Do until the end of string*/
                    {
                        if (wTemp > STRING_LEN)    /*If the max string length is reached*/
                            break;

                        bQuotes = 0;
                        if (bTemp1[1] == '\\')
                        {
                            szState += 1;
                            bTemp1[2] = *szState;
                            bQuotes += 1;
                        }
                        if (bQuotes == 1)
                        {
                            if (bTemp1[2] == '[')
                            {
                                bQuotes += 1;
                                szState += 1;
                                bTemp1[3] = *szState;
                            }
                            else
                            {
                                bQuotes -= 1;
                                *szState = bTemp1[2];
                                szState -= 1;
                            }
                        }

                        if (bQuotes == 2)
                        {
                            if (bTemp1[3] == '"')
                            {
                                bQuotes += 1;
                                szState += 1;
                                bTemp1[4] = *szState;
                                if (bTemp1[4] == 0x0D)
                                {
                                    wTemp += 3;        /*Increase target pointer*/
                                    break;
                                }
                            }
                        }
                        if (bQuotes == 3)
                        {
                            if (bTemp1[4] == ']')
                            {
                                bQuotes += 1;
                            }
                            else
                            {
                                szState -= 1;
                                break;
                            }
                        }
                        if (bQuotes == 1)
                            wTemp += 2;        /*Increase target pointer*/
                        else if (bQuotes == 2)
                            wTemp += 3;        /*Increase target pointer*/
                        else if (bQuotes == 3)
                            wTemp += 4;        /*Increase target pointer*/
                        else
                            wTemp += 1;
                        szState += 1;
                    }
                    szState += 1;    /*Skip quotation mark*/
                    break;

                case PARENTHESIS:    /*If it is a round bracket */
                    if (bOperandType)
                    {
                        Delimitate(szToken, &szState, (BYTE *)")", 1);
                    }
                    else
                    {
                        szState += 1;
                        bOperandType = CheckExpressionType(szState);
                        Delimitate(szToken, &szState, (BYTE *)")", 1);
                    }
            }
        }

        Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 1);
        if ((*szToken == '+') || (*szToken == '-') ||
            (*szToken == '*') || (*szToken == '/'))
        {
            bOperatorType = 'A';
        }
        else if ((*szToken == '>') || (*szToken == '<') || (*szToken == '='))
        {
            bOperatorType = 'L';
        }
        else if ((*szToken == ')') || (*szToken == ',') ||
            (*szToken == '\n') || (*szToken == '\r') || (*szToken == '\0'))
        {
            break;
        }
    }

    if (bOperatorType == 'L' && bOperandType != STRING_TYPE)
        return NUMERAL;
    else
        return bOperandType;
}

/******************************************************************************
*
* Function:
* CheckOperandType
*
* Description:
* This function check operand type.
*
* Input:
* Pointer to the token
*
* Output:
* Operand type
*
******************************************************************************/
BYTE CheckOperandType(BYTE* szState)
{
    BYTE szToken[TOKEN_LEN];                /*Token extracted from statement*/
    BYTE *psTemp;

    while (isspace(*szState))                    /*Skip white space*/
    {
        szState += 1;                            /*Increace pointer to string*/
    }

    Delimitate(szToken, &szState, (BYTE *)"+-\x2a/<>=(),;\r\n\"", 0);
    /*Take next token delimitated by the given characters*/
    psTemp = szState;

    if (IsNumeral(szState))                        /*If it is a numeral*/
    {
        return NUMERAL;
    }
    if (*szToken == '"')                        /*If it is a constant string*/
    {
        return CSTRING;
    }
    if ((CheckIntegerVariable(szToken)) ||        /*If it is a variable*/
        (CheckFloatVariable(szToken)) ||
        (CheckDoubleVariable(szToken)) ||
        (CheckStringVariable(szToken)) ||
        (CheckGlobalVariable(szToken)))
    {
        return VARIABLE;
    }
    if (CheckFunctionType(szToken))                /*If it is a function*/
    {
        return FUNCTION;
    }
    if (*szToken == '(')                        /*If it is a round bracket*/
    {
        return PARENTHESIS;
    }
    if (CheckIntegerDimension(&psTemp))            /*If it is a integer dimension*/
    {
        return INTEGER_DIM;
    }
    psTemp = szState;
    if (CheckFloatDimension(&psTemp))            /*If it is a float dimension*/
    {
        return FLOAT_DIM;
    }
    psTemp = szState;
    if (CheckDoubleDimension(&psTemp))            /*If it is a float dimension*/
    {
        return DOUBLE_DIM;
    }
    psTemp = szState;
    if (CheckStringDimension(&psTemp))            /*If it is a string dimension*/
    {
        return STRING_DIM;
    }

    return FAIL;
}

/******************************************************************************
*
* Function:
* CheckFunctionType
*
* Description:
* This function check function type.
*
* Input:
* Pointer to pointer to statement
*
* Output:
* Function type
*
******************************************************************************/
BYTE CheckFunctionType(BYTE *szToken)
{
    BYTE szTemp[16];
    BYTE bRetVal;

    Delimitate(szTemp, &szToken, (BYTE *)"(", 0);    /*Extract a token from statement*/

    for (bRetVal = 0; bRetVal < sizeof(aszFunction) / sizeof(BYTE *); bRetVal++)    /*Check function ID table*/
    {
        if (strcmp((CHAR *)szTemp, (CHAR *)aszFunction[bRetVal]) == 0)    /*If a function name match the token*/
            return bRetVal + 1;                        /*Return the ID number*/
    }
    return FAIL;
}

/******************************************************************************
*
* Function:
* CheckVariableType
*
* Description:
* This function check variable type.
*
* Input:
* Pointer to pointer to statement
*
* Output:
* Variable type
*
******************************************************************************/
BYTE CheckVariableType(BYTE* szToken)
{
    BYTE bTokenLen;
    INT i;

    // check counter
    if (*szToken == '@')
    {
        for (i = 1; i < strlen((CHAR *)szToken); i++)
        {
            if (!isdigit(*((CHAR *)szToken + i)))
                break;
        }
        if (i == strlen((CHAR *)szToken))
            return STRING_TYPE;

        if (CheckGlobalVariable(szToken) != 0)
            return STRING_TYPE;
    }

    bTokenLen = strlen((CHAR *)szToken);
    switch (szToken[bTokenLen - 1])
    {
        case DOUBLE_ID:            /*If the last character is '#'*/
            return DOUBLE_TYPE;

        case FLOAT_ID:            /*If the last character is '!'*/
            return FLOAT_TYPE;

        case INTEGER_ID:        /*If the last character is '%'*/
            return INTEGER_TYPE;

        case STRING_ID:            /*If the last character is '$'*/
            return STRING_TYPE;

        default:
            return DOUBLE_TYPE;    /*double is the default value*/
    }
}

/******************************************************************************
*
* Function:
* NextToken
*
* Description:
* This function extract a token from a string.
*
* Input:
* 1)Pointer to the token, 2)pointer to the string
*
* Output:
* Token length
*
******************************************************************************/
INT NextToken(BYTE *szToken, BYTE **pszString)
{
    INT iTokenLen = 0;                                        /*Initialize token length*/
    INT iBlankLen = 0;                                        /*Initialize blank length*/

    while (isspace(**pszString))                            /*Skip white space*/
    {
        *pszString += 1;                                    /*Increace pointer to string*/
        iBlankLen += 1;                                        /*Increace blank length*/
    }

    if ((**pszString == '+') || (**pszString == '-') ||        /*If the first character*/
        (**pszString == '*') || (**pszString == '/') ||        /*is a punctuate, take it*/
        (**pszString == '(') || (**pszString == ')') ||        /*as a token and return*/
        (**pszString == '<') || (**pszString == '>') ||
        (**pszString == '"') || (**pszString == ';') ||
        (**pszString == ':') || (**pszString == ',') ||
        (**pszString == '='))
    {
        if (szToken)                                        /*If szToken is valid*/
            *(szToken + iTokenLen) = **pszString;            /*Copy a character from string to token*/

        *pszString += 1;                                    /*Increace pointer to string*/
        iTokenLen += 1;                                        /*Increace pointer to token*/

        if (szToken)                                        /*If szToken is valid*/
            *(szToken + iTokenLen) = 0;                        /*Append a null character*/

        return iTokenLen + iBlankLen;                        /*Return token length*/
    }

    while ((isspace(**pszString) == 0) &&                    /*Take next character*/
        (**pszString != '+') && (**pszString != '-') &&        /*until a punctuate or*/
        (**pszString != '*') && (**pszString != '/') &&        /*white space is met*/
        (**pszString != '(') && (**pszString != ')') &&
        (**pszString != '<') && (**pszString != '>') &&
        (**pszString != '"') && (**pszString != ';') &&
        (**pszString != ':') && (**pszString != ',') &&
        (**pszString != '=') && (**pszString != '\0'))
    {
        if (szToken)                                        /*If szToken is valid*/
            *(szToken + iTokenLen) = **pszString;            /*Copy a character from string to token*/

        *pszString += 1;                                    /*Increace pointer to string*/
        iTokenLen += 1;                                        /*Increace pointer to token*/

        if (iTokenLen > TOKEN_LEN)                            /*If token is longer than the maxium*/
        {                                                    /*token length, simply return a null*/
            if (szToken)                                    /*If szToken is valid*/
                *szToken = 0;                                /*token*/
            iTokenLen = 0;
            return iTokenLen + iBlankLen;                    /*Return token length*/
        }
    }

    if (szToken)                                            /*If szToken is valid*/
        *(szToken + iTokenLen) = 0;                            /*Append a null character*/
    return iTokenLen + iBlankLen;                            /*Return token length*/
}

/******************************************************************************
*
* Function:
* Delimitate
*
* Description:
* This function extract a token from a string delimited by the given character.
*
* Input:
* 1)Pointer to the token, 2)pointer to the string, 3)character to delimit the token
*
* Output:
* Token length
*
******************************************************************************/
INT Delimitate(BYTE* szToken, BYTE** pszString, BYTE* szDelimiter, BYTE bUpdate)
{
    BYTE bTokenLen;
    BYTE* szBackup;

    bTokenLen = 0;
    szBackup = *pszString;                        /*Backup current pointer*/

    while (isspace(**pszString))                /*Skip white space*/
    {
        *pszString += 1;                        /*Increace pointer to string*/
    }

    if (CheckTable(szDelimiter, **pszString))    /*If the first character is a delimitor*/
    {
        if (szToken)                            /*If szToken is valid*/
        {
            *szToken = **pszString;                /*Copy a character from string to token*/
            *(szToken + 1) = ZERO;                /*Copy a character from string to token*/
        }

        *pszString += 1;                        /*Increace pointer to string*/

        if (!bUpdate)
        {
            *pszString = szBackup;                /*Restore string pointer*/
        }

        return 1;                                /*Return token length*/
    }

    while (!CheckTable(szDelimiter, **pszString))    /*Take next character until a delimitor is met*/
    {
        if (isspace(**pszString))                /*If it is a white space*/
        {
            break;                                /*Escape*/
        }
        if (szToken)                            /*If szToken is valid*/
        {
            *szToken = **pszString;                /*Copy a character from string to token*/
            szToken += 1;                        /*Increase pointer to token*/
        }

        *pszString += 1;                        /*Increace pointer to string*/

        bTokenLen += 1;                            /*Increase token length*/

        if (bTokenLen > TOKEN_LEN)                /*If the max token length id reached*/
        {
            return 0;
        }
    }
    if (szToken)                                /*If szToken is valid*/
        *szToken = ZERO;                        /*Append a null character*/

    if (!bUpdate)
    {
        *pszString = szBackup;                    /*Restore string pointer*/
    }

    return bTokenLen;                            /*Return token length*/
}

/******************************************************************************
*
* Function:
* GetDimToken
*
* Description:
* This function extract the next dimension token from a string.
*
* Input:
* 1)Pointer to the token, 2)pointer to the string
*
* Output:
* Token length
*
******************************************************************************/
INT GetDimToken(BYTE *szToken, BYTE **pszString)
{
    CHAR bBraceCount;
    BYTE bTokenLen;

    bTokenLen = bBraceCount = 0;

    while (**pszString)
    {
        if (**pszString == '(')
        {
            bBraceCount += 1;
        }
        else if (**pszString == ')')
        {
            bBraceCount -= 1;
            if (bBraceCount == 0)
            {
                if (szToken)
                {
                    *szToken = ')';
                    *(szToken + 1) = 0;
                }
                *pszString += 1;
                return bTokenLen;
            }
            else if (bBraceCount < 0)
                return 0;
        }
        if (szToken)
        {
            *szToken = **pszString;
            szToken += 1;
            bTokenLen += 1;
        }
        *pszString += 1;
    }
    return 0;
}

#endif

exputil.h  ///

#ifndef EXPUTIL_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define EXPUTIL_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

#define SEC_PER_DAY        (24 * 60 * 60)
#define SINCE_0            (-693958)
#define SINCE_100        (-657434)
#define SINCE_9999        (2958465)
#define SINCE_1970        (25569)

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    BOOL DateUse;
    BOOL TimeUse;
    LONG Year;
    LONG Month;
    LONG DayYear;
    LONG DayMonth;
    LONG DayWeek;
    LONG Hour;
    LONG Minute;
    LONG Second;
} DATE;

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

FLOAT expStringToFloat(BYTE *);
INT expFloatToString(FLOAT, BYTE *);
FLOAT expIntegerToFloat(INT);
INT expFloatToInteger(FLOAT);
INT expStringToInteger(BYTE *);
INT expIntegerToString(INT, BYTE *);

DOUBLE expStringToDouble(BYTE *);
INT expDoubleToString(BYTE *, DOUBLE);
DOUBLE expDateToDouble(DATE);
DATE expDoubleToDate(DOUBLE);
INT expDateToString(BYTE *, DATE);
DATE expStringToDate(BYTE *);

BYTE CheckExpressionType(BYTE *);
BYTE CheckOperandType(BYTE *);
BYTE CheckFunctionType(BYTE *);
BYTE CheckVariableType(BYTE *);
INT NextToken(BYTE *, BYTE **);
INT Delimitate(BYTE *, BYTE **, BYTE *, BYTE);
INT GetDimToken(BYTE *, BYTE **);

#endif

LZSS.c  /

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define LZSS_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "LZSS.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(TSPL)

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

#define N         4096    /* size of ring buffer */
#define F           18    /* upper limit for match_length */
#define THRESHOLD    2   /* encode string into position and length
                           if match_length is greater than this */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC _LzssAttr sLZSS;

/* ring buffer of size N, with extra F-1 bytes to facilitate string comparison */
STATIC UCHAR text_buf[N + F - 1];


STATIC CHAR LzssOut(VOID)
{
    INT i, j, k, c;

    if ( !sLZSS.size )
    {
        if ( ((sLZSS.flags >>= 1) & 256) == 0 )
        {
            c = (UCHAR)sLZSS.DataIn();
            sLZSS.flags = c | 0xff00;    /* uses higher byte cleverly */
        }                                /* to count eight */
        if ( sLZSS.flags & 1 )
        {
            c = (UCHAR)sLZSS.DataIn();
            text_buf[sLZSS.ring++] = c;
            sLZSS.ring &= (N - 1);
            return (CHAR)c;
        }
        else
        {
            i = (UCHAR)sLZSS.DataIn();
            j = (UCHAR)sLZSS.DataIn();
            i |= ((j & 0xf0) << 4);
            j = (j & 0x0f) + THRESHOLD;
            for ( k = 0 ; k <= j ; k++ )
            {
                c = text_buf[(i + k) & (N - 1)];
                sLZSS.buf[j - k] = c;
                text_buf[sLZSS.ring++] = c;
                sLZSS.ring &= (N - 1);
            }
            sLZSS.size = (j + 1);
        }
    }

    return sLZSS.buf[--sLZSS.size];
}

_LzssAttr *CreateLZSS(VOID)
{
    INT i;

    for ( i = 0 ; i < N - F ; i++ )
        text_buf[i] = ' ';

    sLZSS.DataOut = LzssOut;
    sLZSS.ring = N - F;
    sLZSS.flags = 0;
    sLZSS.size = 0;
    return     &sLZSS;
}

#endif

LZSS.h 

#ifndef LZSS_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define LZSS_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    CHAR    (*DataIn)(VOID);
    CHAR    (*DataOut)(VOID);
    INT        ring;
    UINT    flags;
    CHAR    buf[256];
    ULONG    size;
} _LzssAttr;

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

_LzssAttr *CreateLZSS(VOID);

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

RunLength.c    ///

/****************************************************************************
 * Run-length encoding compression mode
 * 
 * In run-length encoding compression mode, the data to be printed is always
 * transferred in the format (counter) + (data), where counter represents one byte of
 * information.
 * If 0 <= counter <= 127, then the data following the counter is non-compressed data, and the
 * length of the compressed data is (counter)+1 bytes.
 * If 128 <= counter <= 255, then the data following the counter will be one byte of
 * compressed data, . This single compressed byte of data is thereafter to be repeated
 * 258-(counter) times..
 * 
 ****************************************************************************/

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define RUNLENGTH_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "RunLength.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(TSPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC _RunLengthAttr sRunLen;

/******************************************************************************
 *
 * Function:
 *        RunLengthDecode
 *
 * Description: 
 *        
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
STATIC ULONG RunLengthDecode(VOID)
{
    ULONG length;
    ULONG times;
    UCHAR data;

    data = (UCHAR)sRunLen.DataIn();
    if ( data >= sRunLen.nonCompressMax )
    {
        length = times = sRunLen.CompressMin + 255 - data;
        data = (UCHAR)sRunLen.DataIn();
        while ( times )
            sRunLen.buf[--times] = (CHAR)data;
    }
    else
    {
        length = times = data + 1;
        while ( times )
            sRunLen.buf[--times] = sRunLen.DataIn();
    }
    return length;
}

/******************************************************************************
 *
 * Function:
 *        RunLengthOut
 *
 * Description: 
 *        
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
STATIC CHAR RunLengthOut(VOID)
{
    if ( !sRunLen.size )
        sRunLen.size = RunLengthDecode();

    return sRunLen.buf[--sRunLen.size];
}

/******************************************************************************
 *
 * Function:
 *        CreateRunLength
 *
 * Description:
 *        
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
_RunLengthAttr *CreateRunLength(VOID)
{
    sRunLen.DataOut = RunLengthOut;
    sRunLen.nonCompressMax = 128;
    sRunLen.CompressMin = 3;
    sRunLen.size = 0;
    return     &sRunLen;
}

#endif

RunLength.h   /

#ifndef RUNLENGTH_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define RUNLENGTH_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    CHAR    (*DataIn)(VOID);
    CHAR    (*DataOut)(VOID);
    UCHAR    nonCompressMax;
    UCHAR    CompressMin;
    CHAR    buf[256];
    ULONG    size;
} _RunLengthAttr;

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

_RunLengthAttr *CreateRunLength(VOID);

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif    

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值