T168_111\appl\Parser\Tspl:第24~28

TsplFuncBas.c   、、、、、、、、、、、、、、、、



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

#define TSPLFUNCBAS_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 <stdlib.h>
#include <string.h>
#include <ctype.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 "XVarBank.h"
#include "XImgMgr.h"
#include "TsplFunc.h"
#include "Expr.h"
#include "VarMgr.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "TsplUtil.h"

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

#if defined(TSPL)

#define    GOSUB_MAX                40
#define FOR_MAX                    40
#define WHILE_MAX                40
#define IF_STACK                64            

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

typedef enum
{
    ELSE_TYPE,
    ELSEIF_TYPE,        
    ENDIF_TYPE,
    IF_ERROR_TYPE,
}_eIfType;

typedef struct
{
    WORD     UsedFlag;
    DWORD     FileAddr;
}_GosubStack;

typedef struct 
{
    WORD       UsedFlag;
    WORD    VarType;
    WORD       VarID;
    DOUBLE  End;
    DOUBLE  Step;
    DWORD    FileAddr;
}_ForStack;

typedef struct 
{
    WORD       UsedFlag;
    DWORD    FileAddr;
    BOOL    UntilFlag;
    CHAR    Exp[STRING_LEN / 2];
}_WhileStack;

/******************************************************************************
 *                                                                            *
 *             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     *
 *                                                                            *
 ******************************************************************************/

CONST _CmdEntry BasicEntry[] = 
{
    {"IF",                BAS_IF},
    {"ELSE",            BAS_ELSE},
    {"ELSEIF",            BAS_ELSEIF},
    {"ENDIF",            BAS_ENDIF},
    {"FOR",                BAS_FOR},
    {"NEXT",            BAS_NEXT},
    {"EXITFOR",            BAS_EXITFOR},
    {"WHILE",            BAS_WHILE},
    {"WEND",            BAS_WEND},
    {"DO",                BAS_DO},
    {"LOOP",            BAS_LOOP},
    {"EXITDO",            BAS_EXITDO},
    {"GOSUB",            BAS_GOSUB},
    {"RETURN",            BAS_RETURN},
    {"GOTO",            BAS_GOTO},
    {"END",                BAS_END},
    {"EOP",                BAS_EOP},
    {(CHAR *)_NULL,        _NULL}
};

/******************************************************************************
 *                                                                            *
 *    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     *
 *                                                                            *
 ******************************************************************************/

_GosubStack sGosubStack[GOSUB_MAX];
_ForStack sForStack[FOR_MAX];

#if defined(__HITACHI__)
#pragma section HeapArea
#endif

_WhileStack sWhileStack[WHILE_MAX];

#if defined(__HITACHI__)
#pragma section 
#endif

_eIfType IfStack[IF_STACK];
INT IfStackLevel;

/******************************************************************************
 *
 * Function:
 *    SendUart
 *
 * Description: 
 *        This global function Uart receive data.
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
VOID BasInitialBASIC(VOID)
{
    INT i;

    sBasicData.ErrorNumber = NO_ERROR;

    // clear gosub return stack
    for (i = 0; i < GOSUB_MAX; i++)
    {
        sGosubStack[i].UsedFlag = FALSE;
        sGosubStack[i].FileAddr = 0;
    }

    // clear for stack
    for (i = 0; i < FOR_MAX; i++)
    {
        sForStack[i].UsedFlag = FALSE;
        sForStack[i].FileAddr = 0;
        sForStack[i].Step     = 0;
        sForStack[i].End      = 0;
        sForStack[i].VarID    = 0;
    }

    // clear while stack
    for (i = 0; i < WHILE_MAX; i++)
    {
        sWhileStack[i].UsedFlag  = FALSE;
        sWhileStack[i].FileAddr  = 0;
        sWhileStack[i].UntilFlag = FALSE;
        sWhileStack[i].Exp[0]    = '\0';
    }

    IfStackLevel = 0;
}

VOID BasClearHandle(VOID)
{
    if (UseHandle_0)
        Fclose(UseHandle_0);
    if (UseHandle_1)
        Fclose(UseHandle_1);

    UseHandle_0 = _NULL;
    UseHandle_1 = _NULL;
    sBasicData.UseHandle = _NULL;
}

VOID OutBasicStatus(VOID)
{
    INT i;

    for (i = 0; i < GOSUB_MAX; i++)
    {
        SendPrintf("\r\n Gosub level:%d", i);
        SendPrintf(",UsedFlag:%d", sGosubStack[i].UsedFlag);
        SendPrintf(",FileAddr:%d", sGosubStack[i].FileAddr);
    }
    SendPrintf("\r\n IfStackLevel:%d", IfStackLevel);

    for (i = 0; i < FOR_MAX; i++)
    {
        SendPrintf("\r\n FOR level:%d", i);
        SendPrintf(",UsedFlag:%d", sForStack[i].UsedFlag);
        SendPrintf(",FileAddr:%d", sForStack[i].FileAddr);
        SendPrintf(",End:%d", sForStack[i].End);
        SendPrintf(",Step:%d", sForStack[i].Step);
    }
}

INT SearchLabel(CHAR *pString)
{
    CHAR Data;
    CHAR Label[TOKEN_LEN];
    INT Length;
    INT Status;
    INT i;

    Fseek(sBasicData.UseHandle, 0, SEEK_SET);

    Status = _ERROR;
    while (Feof(sBasicData.UseHandle) == 0)
    {
        Length = 0;
        Data = NextByte();
        while (!CheckChar(Data, "\r\n\t "))
        {
            *(Label + Length++) = Data;
            if (Length >= TOKEN_LEN)
            {
                Data = NextByte();
                while (Data != 0 && !CheckChar(Data, "\r\n"))
                    Data = NextByte();
                Length = 0;
                break;
            }
            Data = NextByte();
        }

        if (Length == 0)
            continue;

        *(Label + Length) = '\0';

        if (*Label == ':')
        {
            if (strcmp( pString, Label + 1 ) == 0)
            {
                Status = _SUCCESS;
                break;
            }
        }
        else if (*(Label + strlen(Label) - 1) == ':')
        {
            i = strlen(Label);
            *(Label + i - 1) = '\0';
            if (strcmp(pString, Label) == 0)
            {
                Status = _SUCCESS;
                break;
            }
        }
    }
    return Status;
}

BOOL CheckBasLable(CHAR *pString)
{
    if (*pString != ':' && *(pString + strlen(pString) - 1) != ':')
        return FALSE;

    return TRUE;
}

_eIfType SearchElseEndif(CHAR *pToken)
{
    CHAR Data;
    CHAR LineBuf[STRING_LEN];
    CHAR *pStr;
    INT IfLevel;

    IfLevel = 0;
    while (Feof(sBasicData.UseHandle) == 0)
    {
        RemoveSpace();
        GetToken(pToken, &Data, "\r\n\t ", STRING_LEN);
        BackByte(Data);

        if (strcmp(pToken, "ELSE") == 0 && IfLevel == 0)
            return ELSE_TYPE;

        else if (strcmp(pToken, "ELSEIF") == 0 && IfLevel == 0)
            return ELSEIF_TYPE;

        else if (strcmp(pToken, "ENDIF") == 0)
        {
            if (IfLevel == 0)
                return ENDIF_TYPE;
            else
                IfLevel -= 1;
        }
        else if (strcmp(pToken, "IF") == 0)
        {
            GetToken(LineBuf, &Data, "\r\n", sizeof(LineBuf));
            pStr = SearchLineKeyWord(LineBuf, "THEN");
            if (pStr == _NULL)
                return IF_ERROR_TYPE;
            pStr += strlen("THEN");
            while (*pStr == ' ' || *pStr == '\t')
                pStr += 1;
            if (*pStr == _NULL)
                IfLevel += 1;
        }
        else
            RemoveLine();
    }
    return IF_ERROR_TYPE;
}

INT SearchNext(VOID)
{
    CHAR Data;
    CHAR LineBuf[STRING_LEN];
    INT ForNextLevel;

    ForNextLevel = 0;
    while (Feof(sBasicData.UseHandle) == 0)
    {
        RemoveSpace();
        GetToken(LineBuf, &Data, "\r\n\t ", sizeof(LineBuf));
        BackByte(Data);

        if (strcmp(LineBuf, "NEXT") == 0)
        {
            RemoveLine();
            if (ForNextLevel == 0)
                return _SUCCESS;
            else
                ForNextLevel -= 1;
        }
        else if (strcmp(LineBuf, "FOR") == 0)
        {
            ForNextLevel += 1;
            RemoveLine();
        }
        else
            RemoveLine();
    }
    return _ERROR;
}

INT SearchWend(VOID)
{
    CHAR Data;
    CHAR LineBuf[STRING_LEN];
    INT WhileWendLevel;

    WhileWendLevel = 0;
    while (Feof(sBasicData.UseHandle) == 0)
    {
        RemoveSpace();
        GetToken(LineBuf, &Data, "\r\n\t ", sizeof(LineBuf));
        BackByte(Data);

        if (strcmp(LineBuf, "WEND") == 0)
        {
            RemoveLine();
            if (WhileWendLevel == 0)
                return _SUCCESS;
            else
                WhileWendLevel -= 1;
        }
        else if (strcmp(LineBuf, "WHILE") == 0)
        {
            WhileWendLevel += 1;
            RemoveLine();
        }
        else
            RemoveLine();
    }
    return _ERROR;
}

INT SearchLoop(VOID)
{
    CHAR Data;
    CHAR LineBuf[STRING_LEN];
    INT DoLoopLevel;

    DoLoopLevel = 0;
    while (Feof(sBasicData.UseHandle) == 0)
    {
        RemoveSpace();
        GetToken(LineBuf, &Data, "\r\n\t ", sizeof(LineBuf));
        BackByte(Data);

        if (strcmp(LineBuf, "LOOP") == 0)
        {
            RemoveLine();
            if (DoLoopLevel == 0)
                return _SUCCESS;
            else
                DoLoopLevel -= 1;
        }
        else if (strcmp(LineBuf, "DO") == 0)
        {
            DoLoopLevel += 1;
            RemoveLine();
        }
        else
            RemoveLine();
    }
    return _ERROR;
}

INT BAS_IF(VOID)
{
    CONST STATIC CHAR ThenWord[] = "THEN";
    CHAR Data;
    CHAR *pToken;
    BYTE *pStr;
    CHAR Token[STRING_LEN];
    INT Length;
    INT ChekLen;
    _eIfType Type;

    RemoveSpace();

    // check THEN
    Length = 0;
    ChekLen = sizeof(ThenWord) - 1;
    while (1)
    {
        Length += GetToken(Token + Length , &Data, "N\r\n", sizeof(Token) - Length);
        if (Data == 'N' && Length >= ChekLen)
        {
            // check "THE"
            if (strncmp((Token + Length - ChekLen + 1), ThenWord, ChekLen - 1) == 0)
            {
                *(Token + Length - ChekLen + 1) = '\0';
                break;
            }
        }
        if (Data == 'N')
        {
            *(Token + Length) = 'N';
            Length += 1;
        }
        else
            return _ERROR;
    }

    pStr = (BYTE *)Token;
    expMain(&pStr);

    if (wErrorword != NO_ERROR)
        return _ERROR;

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

    // signle line
    if (CheckChar(Data, "\r\n") != TRUE)
    {
        // get a line
        Length = GetToken(sBasicData.LineBuf, &Data, "\r\n", sizeof(sBasicData.LineBuf));
        pToken = SearchLineKeyWord(sBasicData.LineBuf, "ELSE");

        // equation is true
        if (dRetVal == 1)
        {
            if (pToken == _NULL)    // no else
                pToken = sBasicData.LineBuf + strlen(sBasicData.LineBuf);
            sBasicData.LinePtr = sBasicData.LineBuf;
        }
        // equation is false
        else
        {
            if (pToken == _NULL)    // no else
                return _SUCCESS;
            sBasicData.LinePtr = pToken + sizeof("ELSE");
            pToken = sBasicData.LineBuf + strlen(sBasicData.LineBuf);
        }
        strcpy(pToken , "\n");
sysprintf("ANB_1\n");
        AssignNextByte(&LineByte);
    }

    // multi line
    else
    {
        if (sBasicData.UseHandle == _NULL)
            return _ERROR;

        // equation is true
        if (dRetVal == 1)
        {
            IfStack[IfStackLevel] = ENDIF_TYPE;
            IfStackLevel += 1;
        }
        else
        {
            while (1)
            {
                Type = SearchElseEndif(sBasicData.LineBuf);
                if (Type == IF_ERROR_TYPE)
                    return _ERROR;
                else if (Type == ENDIF_TYPE)
                    break;
                else if (Type == ELSE_TYPE)
                {
                    IfStack[IfStackLevel] = ENDIF_TYPE;
                    IfStackLevel += 1;
                    break;
                }
                else if (Type == ELSEIF_TYPE)
                {
                    IfStack[IfStackLevel] = ELSEIF_TYPE;
                    IfStackLevel += 1;
                    strcpy(sBasicData.LineBuf + strlen(sBasicData.LineBuf) , " ");
                    sBasicData.LinePtr = sBasicData.LineBuf;
        sysprintf("ANB_2\n");
                    AssignNextByte(&LineByte);
                    break;
                }
            }
        }
    }    
    return _SUCCESS;
}

INT BAS_ELSE(VOID)
{
    _eIfType Type;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    ReturnNextByte(&FileByte);
    if (IfStackLevel && IfStack[IfStackLevel - 1] == ENDIF_TYPE)
    {
        while (1)
        {
            Type = SearchElseEndif(sBasicData.LineBuf);
            if (Type == IF_ERROR_TYPE)
                return _ERROR;
            if (Type == ENDIF_TYPE)
            {
                strcpy(sBasicData.LineBuf + strlen(sBasicData.LineBuf), "\n");
                sBasicData.LinePtr = sBasicData.LineBuf;
        sysprintf("ANB_3\n");
                AssignNextByte(&LineByte);
                break;
            }
        }
    }
    return _SUCCESS;
}

INT BAS_ELSEIF(VOID)
{
    CHAR Data;
    CHAR Token[STRING_LEN];
    BYTE *pStr;
    CHAR *pToken;
    _eIfType Type;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    GetToken(Token, &Data, "\r\n", sizeof(Token));

    if (IfStackLevel && IfStack[IfStackLevel - 1] == ENDIF_TYPE)
    {
        while (1)
        {
            Type = SearchElseEndif(sBasicData.LineBuf);
            if (Type == IF_ERROR_TYPE)
                return _ERROR;
            if (Type == ENDIF_TYPE)
            {
                strcpy(sBasicData.LineBuf + strlen(sBasicData.LineBuf), "\n");
                sBasicData.LinePtr = sBasicData.LineBuf;
        sysprintf("ANB_4\n");
                AssignNextByte(&LineByte);
                break;
            }
        }
        return _SUCCESS;
    }
    else if (IfStackLevel && IfStack[IfStackLevel - 1] == ELSEIF_TYPE)
        IfStackLevel -= 1;

    pToken = SearchLineKeyWord(Token, "THEN");
    if (Token == _NULL)
        return _ERROR;

    *pToken = '\0';
    pStr = (BYTE *)Token;

    expMain(&pStr);
    if (wErrorword != NO_ERROR)
        return _ERROR;

    // equation is true
    if (dRetVal == 1)
    {
        IfStack[IfStackLevel] = ENDIF_TYPE;
        IfStackLevel += 1;
    }
    else
    {
        while (1)
        {
            Type = SearchElseEndif(sBasicData.LineBuf);
            if (Type == IF_ERROR_TYPE)
                return _ERROR;
            else if (Type == ENDIF_TYPE)
                break;
            else if (Type == ELSE_TYPE)
            {
                IfStack[IfStackLevel] = ELSE_TYPE;
                IfStackLevel += 1;
                break;
            }
            else if (Type == ELSEIF_TYPE)
            {
                IfStack[IfStackLevel] = ELSEIF_TYPE;
                IfStackLevel += 1;
                strcpy(sBasicData.LineBuf + strlen(sBasicData.LineBuf) , " ");
                sBasicData.LinePtr = sBasicData.LineBuf;
        sysprintf("ANB_5\n");
                AssignNextByte(&LineByte);
                break;
            }
        }
    }
    return _SUCCESS;
}

INT BAS_ENDIF(VOID)
{
    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    if (IfStackLevel > 0)
    {
         IfStackLevel -= 1;
        return _SUCCESS;
    }
    else
        return _ERROR;
}

INT BAS_FOR(VOID)
{
    DOUBLE StartValue, EndValue, StepValue;
    CHAR Data;
    CHAR VarToken[STRING_LEN];
    CHAR DataToken[STRING_LEN];
    CHAR *pStart, *pCurren;
    BYTE *pStr;
    BYTE VarType;
    INT VarID;
    INT i, Num;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    RemoveSpace();
    GetToken(VarToken, &Data, "\r\n\t =", sizeof(VarToken));

    if (CheckChar(Data, "\t "))
    {
        RemoveSpace();
        Data = NextByte();
    }
    if (Data != '=')
        return _ERROR;

    VarType = CheckVariableType((BYTE *)VarToken);

    if (VarType == STRING_TYPE)
    {
        sBasicData.ErrorNumber = Add_VAR_ERROR;
        return _ERROR;
    }

    // use global variable
    if (CheckGlobalVariable((BYTE *)VarToken) != 0)
    {
        sBasicData.ErrorNumber = FOR_USE_TIME_VAR;
        return _ERROR;
    }

    RemoveSpace();
    GetToken(DataToken, &Data, "\r\n", sizeof(DataToken));

    // get start value
    pStart = DataToken;
    pCurren = SearchLineKeyWord(pStart, "TO");
    if (pCurren == _NULL)
    {
        sBasicData.ErrorNumber = ERROR_FOR;
        return _ERROR;
    }

    *pCurren = '\0';
    pStr = (BYTE *)pStart;
    expMain(&pStr);

    if (wErrorword != NO_ERROR || bExpKind != DOUBLE_TYPE)
        return _ERROR;
    StartValue = dRetVal;

    // get end value
    pStart = pCurren + sizeof("TO");
    pCurren = SearchLineKeyWord(pStart, "STEP");
    if (pCurren != _NULL)
    {
        *pCurren = '\0';
        pStr = (BYTE *)pStart;
        expMain(&pStr);

        if (wErrorword != NO_ERROR || bExpKind != DOUBLE_TYPE)
            return _ERROR;
        EndValue = dRetVal;
        pStart = pCurren + sizeof("STEP");
        pStr = (BYTE *)pStart;
        expMain(&pStr);

        if (wErrorword != NO_ERROR || bExpKind != DOUBLE_TYPE)
            return _ERROR;
        StepValue = dRetVal;
    }
    else
    {
        pStr = (BYTE *)pStart;
        expMain(&pStr);

        if (wErrorword != NO_ERROR || bExpKind != DOUBLE_TYPE)
            return _ERROR;
        EndValue = dRetVal;

        StepValue = 1;
    }

    for (i = 0; i < FOR_MAX; i++)
    {
        if (sForStack[i].UsedFlag == FALSE)
            break;
    }

    if (i == FOR_MAX)
    {
        sBasicData.ErrorNumber = STACKER_OVERFLOW;
        return _ERROR;
    }
    Num = i;

    // add Variable
    switch (VarType)
    {
        case DOUBLE_TYPE:
            if ((VarID = CheckDoubleVariable((BYTE *)VarToken)) == 0)
            {
                if ((VarID = AddDoubleVariable((BYTE *)VarToken)) == 0)
                    return _ERROR;
            }
            SetDoubleVariable(VarID, StartValue);
            break;
        case FLOAT_TYPE:
            if ((VarID = CheckFloatVariable((BYTE *)VarToken)) == 0)
            {
                if ((VarID =AddFloatVariable((BYTE *)VarToken)) == 0)
                    return _ERROR;
            }
            SetFloatVariable(VarID, (FLOAT)StartValue);
            break;
        case INTEGER_TYPE:
            if ((VarID = CheckIntegerVariable((BYTE *)VarToken)) == 0)
            {
                if ((VarID =AddIntegerVariable((BYTE *)VarToken)) == 0)
                    return _ERROR;
            }
            SetIntegerVariable(VarID, (INT)StartValue);
            break;
    }
    sprintf((CHAR *)DataToken, "%lf\0", StartValue);
    StartValue = atof((CHAR *)DataToken);

    if ((StartValue >= EndValue && StepValue <= 0) ||
        (StartValue <= EndValue && StepValue >= 0))
    {
        // set variable
        sForStack[Num].UsedFlag = TRUE;
        sForStack[Num].VarType  = VarType;
        sForStack[Num].VarID    = VarID;
        sForStack[Num].End      = EndValue;
        sForStack[Num].Step     = StepValue;
        sForStack[Num].FileAddr = Ftell(sBasicData.UseHandle);
    }
    else
    {
        if (SearchNext() != _SUCCESS)
        {
            sBasicData.ErrorNumber = EXITFOR_NOT_FOR;
            return _ERROR;
        }
    }
    return _SUCCESS;
}

INT BAS_NEXT(VOID)
{
    DOUBLE dNewData;
    CHAR DataToken[STRING_LEN];
    INT i;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search for stack
    for (i = FOR_MAX - 1; i >= 0; i--)
    {
        if (sForStack[i].UsedFlag == TRUE)
            break;
    }

    if (i < 0)
    {
        sBasicData.ErrorNumber = NEXT_NOT_FOR;
        return _ERROR;
    }

    switch (sForStack[i].VarType)
    {
        case DOUBLE_TYPE:
            dNewData = GetDoubleVariable(sForStack[i].VarID) + sForStack[i].Step;
            SetDoubleVariable(sForStack[i].VarID, dNewData);
            break;
        case FLOAT_TYPE:
            dNewData = (DOUBLE)GetFloatVariable(sForStack[i].VarID) + sForStack[i].Step;
            SetFloatVariable(sForStack[i].VarID, (FLOAT)dNewData);
            break;
        case INTEGER_TYPE:
            dNewData = (DOUBLE)GetIntegerVariable(sForStack[i].VarID) + sForStack[i].Step;
            SetIntegerVariable(sForStack[i].VarID, (LONG)dNewData);
            break;
    }

    sprintf((CHAR *)DataToken, "%lf\0", dNewData);
    dNewData = atof((CHAR *)DataToken);

    // if equation is true
    if ((dNewData >= sForStack[i].End && sForStack[i].Step <= 0) ||
        (dNewData <= sForStack[i].End && sForStack[i].Step >= 0))
        Fseek(sBasicData.UseHandle, sForStack[i].FileAddr, SEEK_SET);
    else
        sForStack[i].UsedFlag = FALSE;

    return _SUCCESS;
}

INT BAS_EXITFOR(VOID)
{
    INT i;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search fro stack
    for (i = FOR_MAX - 1; i >= 0; i--)
    {
        if (sForStack[i].UsedFlag == TRUE)
            break;
    }

    if (i < 0)
    {
        sBasicData.ErrorNumber = EXITFOR_NOT_FOR;
        return _ERROR;
    }

    if (SearchNext() == _SUCCESS)
    {
        sForStack[i].UsedFlag = FALSE;
        return _SUCCESS;
    }
    else
    {
        sBasicData.ErrorNumber = EXITFOR_NOT_FOR;
        return _ERROR;
    }
}

INT BAS_WHILE(VOID)
{
    BYTE *pToken;
    CHAR Data;
    INT i, Num;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search free whilw stack
    for (i = 0; i < WHILE_MAX; i++)
    {
        if (sWhileStack[i].UsedFlag == FALSE)
            break;
    }

    if (i == WHILE_MAX)
    {
        sBasicData.ErrorNumber = STACKER_OVERFLOW;
        return _ERROR;
    }

    Num = i;

    RemoveSpace();
    GetToken(sWhileStack[Num].Exp, &Data, "\r\n", sizeof(sWhileStack[Num].Exp));

    pToken = (BYTE *)sWhileStack[Num].Exp;
    expMain(&pToken);

    if (wErrorword != NO_ERROR)
        return _ERROR;

    if ((BYTE)dRetVal)
    {
        sWhileStack[Num].UsedFlag = TRUE;
        sWhileStack[Num].FileAddr = Ftell(sBasicData.UseHandle);
    }
    else
    {
        if (SearchWend() == _ERROR)
        {
            sBasicData.ErrorNumber = WHILE_NOT_WEND;
            return _ERROR;
        }
    }
    return _SUCCESS;
}

INT BAS_WEND(VOID)
{
    BYTE *pToken;
    INT i;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search free whilw stack
    for (i = WHILE_MAX - 1; i >= 0; i--)
    {
        if (sWhileStack[i].UsedFlag == TRUE)
            break;
    }

    if (i < 0)
    {
        sBasicData.ErrorNumber = STACKER_OVERFLOW;
        return _ERROR;
    }

    pToken = (BYTE *)sWhileStack[i].Exp;
    expMain(&pToken);

    if (wErrorword != NO_ERROR)
        return _ERROR;

    if ((BYTE)dRetVal)
        Fseek(sBasicData.UseHandle, sWhileStack[i].FileAddr, SEEK_SET);
    else
        sWhileStack[i].UsedFlag = FALSE;

    return _SUCCESS;
}

INT BAS_DO(VOID)
{
    CHAR Data;
    CHAR DataToken[STRING_LEN];
    BYTE *pToken;
    INT i, Num;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search free whilw stack
    for (i = 0; i < WHILE_MAX; i++)
    {
        if (sWhileStack[i].UsedFlag == FALSE)
            break;
    }
    if (i == WHILE_MAX)
    {
        sBasicData.ErrorNumber = STACKER_OVERFLOW;
        return _ERROR;
    }
    Num = i;

    RemoveSpace();
    GetToken(DataToken, &Data, "\r\n\t ", sizeof(DataToken));

    if (*DataToken != '\0')
    {
        if (strcmp(DataToken, "WHILE") != 0)
        {
            if (strcmp(DataToken, "UNTIL") != 0)
            {
                sBasicData.ErrorNumber = DO_NOT_LOOP;
                return _ERROR;
            }
            else
                sWhileStack[Num].UntilFlag = TRUE;
        }
        else
            sWhileStack[Num].UntilFlag = FALSE;

        GetToken(sWhileStack[Num].Exp, &Data, "\r\n", sizeof(sWhileStack[Num].Exp));

        pToken = (BYTE *)sWhileStack[Num].Exp;

        expMain(&pToken);

        if (wErrorword != NO_ERROR)
            return _ERROR;

        if (((BYTE)dRetVal && sWhileStack[Num].UntilFlag == FALSE) ||
            (!(BYTE)dRetVal && sWhileStack[Num].UntilFlag == TRUE))
        {
            sWhileStack[Num].UsedFlag = TRUE;
            sWhileStack[Num].FileAddr = Ftell(sBasicData.UseHandle);
        }
        else
        {
            if (SearchLoop() == _ERROR)
            {
                sBasicData.ErrorNumber = DO_NOT_LOOP;
                return _ERROR;
            }
        }
    }
    // no express
    else
    {
        sWhileStack[Num].Exp[0] = '\0';
        sWhileStack[Num].UsedFlag = TRUE;
        sWhileStack[Num].FileAddr = Ftell(sBasicData.UseHandle);
    }
    return _SUCCESS;
}

INT BAS_LOOP(VOID)
{
    CHAR Data;
    CHAR DataToken[STRING_LEN];
    BYTE *pToken;
    INT i;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search free whilw stack
    for (i = WHILE_MAX - 1; i >= 0; i--)
    {
        if (sWhileStack[i].UsedFlag == TRUE)
            break;
    }

    if (i < 0)
    {
        sBasicData.ErrorNumber = STACKER_OVERFLOW;
        return _ERROR;
    }

    RemoveSpace();
    GetToken(DataToken, &Data, "\r\n\t ", sizeof(DataToken));

    // goto stack point
    if (*DataToken == '\0')
    {
        if (sWhileStack[i].Exp[0] == '\0')
        {
            Fseek(sBasicData.UseHandle, sWhileStack[i].FileAddr, SEEK_SET);
            return _SUCCESS;
        }
        else
        {
            pToken = (BYTE *)sWhileStack[i].Exp;
            expMain(&pToken);

            if (wErrorword != NO_ERROR)
                return _ERROR;

            if (((BYTE)dRetVal && sWhileStack[i].UntilFlag == FALSE) ||
                (!(BYTE)dRetVal && sWhileStack[i].UntilFlag == TRUE))
                Fseek(sBasicData.UseHandle, sWhileStack[i].FileAddr, SEEK_SET);
        }
    }
    else 
    {
        if (sWhileStack[i].Exp[0] != '\0')
        {
            return _ERROR;
        }
        else
        {
            if (strcmp(DataToken, "WHILE" ) != 0)
            {
                if (strcmp(DataToken, "UNTIL" ) != 0)
                {
                    sBasicData.ErrorNumber = DO_NOT_LOOP;
                    return _ERROR;
                }
                else
                    sWhileStack[i].UntilFlag = TRUE;
            }
            else
                sWhileStack[i].UntilFlag = FALSE;

            GetToken(DataToken, &Data, "\r\n", sizeof(DataToken));

            pToken = (BYTE *)DataToken;
            expMain( &pToken );

            if (wErrorword != NO_ERROR)
                return _ERROR;

            if (((BYTE)dRetVal && sWhileStack[i].UntilFlag == FALSE) ||
                (!(BYTE)dRetVal && sWhileStack[i].UntilFlag == TRUE))
                Fseek(sBasicData.UseHandle, sWhileStack[i].FileAddr, SEEK_SET);
        }
    }
    return _SUCCESS;
}

INT BAS_EXITDO(VOID)
{
    INT i;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search fro stack
    for (i = WHILE_MAX - 1; i >= 0; i--)
    {
        if (sWhileStack[i].UsedFlag == TRUE)
            break;
    }

    if (i < 0)
    {
        sBasicData.ErrorNumber = LOOP_NOT_DO;
        return _ERROR;
    }

    if (SearchLoop() == _SUCCESS)
    {
        sWhileStack[i].UsedFlag = FALSE;
        return _SUCCESS;
    }
    else
    {
        sBasicData.ErrorNumber = LOOP_NOT_DO;
        return _ERROR;
    }
}

INT BAS_GOSUB(VOID)
{
    CHAR Label[STRING_LEN];
    INT i;

    if (!GetExpToken(LINE_END, Label, sizeof(Label)))
        return _ERROR;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search free stack
    for (i = 0; i < GOSUB_MAX; i++)
    {
        if (sGosubStack[i].UsedFlag == FALSE)
            break;
    }

    // if no free stack
    if (i == GOSUB_MAX)
    {
        sBasicData.ErrorNumber = STACKER_OVERFLOW;
        EndFile();
        return _SUCCESS;
    }

    // save address
    sGosubStack[i].UsedFlag = TRUE;
    sGosubStack[i].FileAddr = Ftell(sBasicData.UseHandle);

    if (SearchLabel(Label) == _ERROR)
    {
        sBasicData.ErrorNumber = GOTO_NOT_LABEL;
        EndFile();
        return _SUCCESS;
    }
    
    return _SUCCESS;
}

INT BAS_RETURN(VOID)
{
    INT i;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    // search save stack
    for (i = GOSUB_MAX - 1; i >= 0; i--)
    {
        if (sGosubStack[i].UsedFlag == TRUE)
            break;
    }

    // if no stack
    if (i < 0)
    {
        sBasicData.ErrorNumber = RETURN_NOT_GOSUB;
        EndFile();
        return _SUCCESS;
    }

    Fseek(sBasicData.UseHandle, sGosubStack[i].FileAddr, SEEK_SET);

    sGosubStack[i].UsedFlag = FALSE;
    sGosubStack[i].FileAddr = 0;
    return _SUCCESS;
}

INT BAS_GOTO(VOID)
{
    CHAR Label[STRING_LEN];

    if (!GetExpToken(LINE_END, Label, sizeof(Label)))
        return _ERROR;

    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    if (SearchLabel(Label) == _ERROR)
    {
        sBasicData.ErrorNumber = GOTO_NOT_LABEL;
        EndFile();
        return _SUCCESS;
    }
    IfStackLevel = 0;
    return _SUCCESS;
}

INT BAS_END(VOID)
{
    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    EndFile();
    return _SUCCESS;
}

INT BAS_EOP(VOID)
{
    if (sBasicData.UseHandle == _NULL)
        return _ERROR;

    EndFile();
    return _SUCCESS;
}

#endif



TsplFuncDrv.c  、、、、、、、、、、、、、、、、、、、、、、、

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

#define TSPLFUNCDRV_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 <stdlib.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 "XRTC.h"
#include "XFileSys.h"
#include "XCodePage.h"
#include "XFunction.h"
#include "XAppVer.h"
#include "RunLength.h"
#include "LZSS.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "..\Bsc\BscReport.h"
#include "TsplCnt.h"
#include "TsplUtil.h"
#include "TsplFunc.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     *
 *                                                                            *
 ******************************************************************************/

CONST _CmdEntry DriverEntry[] = 
{
    {"!",                FN_DRIVER_COMMAND},
    {"~",                FN_RS232_COMMAND},
    {";",                FN_REM},
    {(CHAR *)_NULL,        _NULL}
};

/******************************************************************************
 *                                                                            *
 *    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:
 *    SendUart
 *
 * Description: 
 *        This global function Uart receive data.
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
INT FN_DRIVER_COMMAND(VOID)
{
    _RunLengthAttr *psRunLen;
    _LzssAttr *psLZSS;
    _BMPAttr sBMPAttr;
    BYTE ByteL, ByteH;
    CHAR Data;
    INT Return = _SUCCESS;
    INT num = 0;
    INT i;

    Data = NextByte();

    switch ( Data )
    {
        case 'R':    // decode Run-Length
        {
            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.sCoord.iX = XCoord((SHORT)(ByteH * 0x100) + ByteL);
            sBMPAttr.sCoord.iX = (((sBMPAttr.sCoord.iX + 4) >> 3) << 3);

            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.sCoord.iY = YCoord((SHORT)(ByteH * 0x100) + ByteL);

            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.iImageWidth = ((ByteH * 0x100) + ByteL) * 8;

            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.iImageHeight = (ByteH * 0x100) + ByteL;

            sBMPAttr.iMode = NextByte();

            // reserve
            NextByte();
            NextByte();
            NextByte();

            psRunLen = CreateRunLength();

            psRunLen->nonCompressMax = NextByte();
            psRunLen->CompressMin = NextByte();

            psRunLen->DataIn = NextByte;

            sBMPAttr.psImageBuffer = &sImageBuffer;
            sBMPAttr.ReadByte = psRunLen->DataOut;

            ReloadWaitTime();
            if ((Return = BITMAP(&sBMPAttr)) == _ERROR)
                RemoveLine();

            sBMPAttr.ReadByte = NextByte;
            break;
        }
        case 'S':    // decode LZSS
        {
            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.sCoord.iX = XCoord((SHORT)(ByteH * 0x100) + ByteL);
            sBMPAttr.sCoord.iX = (((sBMPAttr.sCoord.iX + 4) >> 3) << 3);

            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.sCoord.iY = YCoord((SHORT)(ByteH * 0x100) + ByteL);

            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.iImageWidth = ((ByteH * 0x100) + ByteL) * 8;

            ByteL = NextByte();
            ByteH = NextByte();
            sBMPAttr.iImageHeight = (ByteH * 0x100) + ByteL;

            sBMPAttr.iMode = NextByte();

            // reserve
            NextByte();
            NextByte();
            NextByte();
            NextByte();
            NextByte();

            psLZSS = CreateLZSS();

            psLZSS->DataIn = NextByte;

            sBMPAttr.psImageBuffer = &sImageBuffer;
            sBMPAttr.ReadByte = psLZSS->DataOut;

            ReloadWaitTime();
            if ((Return = BITMAP(&sBMPAttr)) == _ERROR)
                RemoveLine();

            sBMPAttr.ReadByte = NextByte;
            break;
        }
        case 'J':
        {
            if (!DriverCopy) 
            {
                ClearImageBuffer(&sImageBuffer);
                ClearCounter();
                DriverCopy = 1;
            }

            sImageBuffer.iFirstLine = 0;
            sImageBuffer.iLastLine = (WORD)pPrintCfg->fPaperSize - 1;

            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);

            sImageBuffer.pDriverImgPtr += (num * sImageBuffer.iByteWidth);
            break;
        }
        case 'B':
        {      
            if (!DriverCopy) 
            {
                ClearImageBuffer(&sImageBuffer);
                ClearCounter();
                DriverCopy = 1;
            }

            sImageBuffer.iFirstLine = 0;
            sImageBuffer.iLastLine = (WORD)pPrintCfg->fPaperSize - 1;

            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);

            ReloadWaitTime();

            for (i = 0; i < num; i++)
                *( sImageBuffer.pDriverImgPtr + i) = NextByte();
            sImageBuffer.pDriverImgPtr += sImageBuffer.iByteWidth;
            break;
        }
        case 'N':
        {      
            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);
            num *= 10;
            num += (NextByte() & 0x0F);

            if (DriverCopy) 
                DriverCopy = num;
            else
                DriverCopy = 1;

            ClearImageBuffer(&sImageBuffer);
            ClearCounter();
            break;
        }
        default:
        {
            BackByte(Data);
            Return = _ERROR;
        }
    }
    return Return;
}

INT FN_RS232_COMMAND(VOID)
{
    CHAR NextData;
    
    NextData = NextByte();
    if (NextData != '!')
    {
        BackByte(NextData);
        return _ERROR;
    }

    NextData = NextByte();

    switch (NextData)
    {
        case 'T':
        {
            SendString(ModelName);
            break;
        }
        case 'I':
        {
            SendString((CHAR *)CodePageNameTable[pPrintCfg->CodePage]);
            SendString(",");
            SendString((CHAR *)CountryNameTable[pPrintCfg->Country]);
            break;
        }
        case 'F':
        {
            _FileList List;

            OpenList(&List, DRAM_DEVICE);
            while (NextFile(&List, "*.*"))
                SendPrintf("%s\r", List.FileName);
            OpenList(&List, FLASH_DEVICE);
            while (NextFile(&List, "*.*"))
                SendPrintf("%s\r", List.FileName);
            OpenList(&List, CARD_DEVICE);
            while (NextFile(&List, "*.*"))
                SendPrintf("%s\r", List.FileName);

            SendChar('\x1a');
            break;
        }
        case 'A':
        {
            SendPrintf("DRAM:%d\r", FreeSpace(DRAM_DEVICE));
            SendPrintf("FLASH:%d\r", FreeSpace(FLASH_DEVICE));
#if defined(FLASH_MCARD_MODEL)/* || defined(SDCARD_MODEL)*/
            SendPrintf("EXT.FLASH:%d\r", FreeSpace(CARD_DEVICE));
#endif
            break;
        }
        case 'C':
        {
            BYTE RTCTemp1, RTCTemp2, RTCTemp3;

            RTCTemp1 = GetRTC(RTC_SEC);

            SetRTC(RTC_SEC, 0x06);
            RTCTemp2 = GetRTC(RTC_SEC);

            SetRTC(RTC_SEC, 0x09);
            RTCTemp3 = GetRTC(RTC_SEC);

            SetRTC(RTC_SEC, RTCTemp1);

            if (RTCTemp2 == 0x06 && RTCTemp3 == 0x09)
                SendChar('1');
            else
                SendChar('0');
            break;
        }
        case '@':
        {
            SendPrintf("%d\r", pPrintRec->DotMilage / (INT)(MM_DOT * 1000));
            break;
        }
        case 'D':
        {
            HexDumpMode();
            break;
        }
        case 'Z':
        {
            ChecksumReport(NULL, TRUE, OUTPUT_RS232);
            break;
        }
        case 'E':
        {
            CtrlImmedCmd(TRUE);
            break;
        }        
        default:
        {
            BackByte(NextData);
            return _ERROR;
        }
    }
    return _SUCCESS;
}

#endif



TsplFuncFile.c  、、、、、、、、、、、、、、、、、、、、、、、、

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

#define TSPLFUNCFILE_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 <string.h>
#include <stdlib.h>
#include <ctype.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 "XAppVer.h"
#include "XFileSys.h"
#include "XRTC.h"
#include "Expr.h"
#include "Error.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "TsplUtil.h"
#include "TsplFunc.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     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    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     *
 *                                                                            *
 ******************************************************************************/


INT FN_OPEN(VOID)
{
    _FileHandle *FileHandle = _NULL;
    _eFileDevice Device;
    CHAR FileName[FILENAME_LENGTH];
    INT FileNo;
    DOUBLE Number;

    if (!GetFileDevice(&Device))
        return _ERROR;

    if (!GetExpString(COMMA_END, FileName, sizeof(FileName)))
        return _ERROR;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    FileNo = (WORD)Number;

    if (FileNo < 0 || FileNo > 1)
        return _ERROR;

    if (FileNo == 0)
        FileHandle = UseHandle_0;
    else if (FileNo == 1)
        FileHandle = UseHandle_1;

    if (FileHandle)
        Fclose(FileHandle);

    if (Device == DRAM_DEVICE)    // not specify
    {
        Device = FLASH_DEVICE;
        if (FileHandle = Fopen(DRAM_DEVICE,  FileName, "r"))
            Device = DRAM_DEVICE;
        else if (FileHandle = Fopen(FLASH_DEVICE, FileName, "r"))
            Device = FLASH_DEVICE;
        else if (FileHandle = Fopen(CARD_DEVICE,  FileName, "r"))
            Device = CARD_DEVICE;

        if (FileHandle)
            Fclose(FileHandle);
    }

    if ((FileHandle = Fopen(Device,  FileName, "a")) == _NULL)
        return _ERROR;

    Fseek(FileHandle, 0, SEEK_SET);

    if (FileNo == 0)
        UseHandle_0 = FileHandle;
    else if (FileNo == 1)
        UseHandle_1 = FileHandle;

    return _SUCCESS;
}

INT FN_CLOSE(VOID)
{
    _FileHandle *FileHandle = _NULL;
    INT FileNo;
    DOUBLE Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    FileNo = (WORD)Number;

    if (FileNo < 0 || FileNo > 1)
        return _ERROR;

    if (FileNo == 0)
        FileHandle = UseHandle_0;
    else if (FileNo == 1)
        FileHandle = UseHandle_1;

    if (FileHandle)
        Fclose(FileHandle);

    if (FileNo == 0)
        UseHandle_0 = _NULL;
    else if (FileNo == 1)
        UseHandle_1 = _NULL;

    return _SUCCESS;
}

INT FN_SEEK(VOID)
{
    _FileHandle *FileHandle = _NULL;
    INT FileNo;
    LONG FileOffset;
    DOUBLE Number;

    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    FileNo = (WORD)Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    FileOffset = (LONG)Number;

    if (FileNo < 0 || FileNo > 1)
        return _ERROR;

    if (FileNo == 0)
        FileHandle = UseHandle_0;
    else if (FileNo == 1)
        FileHandle = UseHandle_1;

    if (FileHandle == _NULL)
        return _ERROR;

    Fseek(FileHandle, FileOffset, SEEK_SET);
    return _SUCCESS;
}

INT FN_READ(VOID)
{
    _FileHandle *FileHandle = _NULL;
    CHAR Token[STRING_LEN];
    CHAR *HugeBuf;
    INT Result = _ERROR;
    INT FileNo;
    INT Type;
    DOUBLE Number;
    CHAR Data;

    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    FileNo = (WORD)Number;

    if (FileNo < 0 || FileNo > 1)
        return _ERROR;

    if (FileNo == 0)
        FileHandle = UseHandle_0;
    else if (FileNo == 1)
        FileHandle = UseHandle_1;

    if (FileHandle == _NULL)
        return _ERROR;

    if ((HugeBuf = malloc(HUGE_LEN)) == 0)
        return _ERROR;

    while (Result != _SUCCESS)
    {
        if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
            break;

        Fgets(HugeBuf, HUGE_LEN, FileHandle);
        *strchr(HugeBuf, '\r') = '\0';
        *strchr(HugeBuf, '\n') = '\0';

        // check variable type
        Type = (CheckVariableType((BYTE *)Token) == STRING_TYPE) ? EQU_STRING : EQU_EXPRESSION;
        if (!SetEquation(Type, (BYTE *)Token, (BYTE *)HugeBuf))
            break;

        RemoveSpace();
        Data = NextByte();
        if (CheckChar(Data, "\r\n"))
            Result = _SUCCESS;
        else if (!CheckChar(Data, ",;"))
            break;
    }
    free(HugeBuf);
    return Result;
}

INT FN_WRITE(VOID)
{
    _FileHandle *FileHandle = _NULL;
    CHAR Token[STRING_LEN];
    BYTE *pExp;
    DOUBLE Number;
    CHAR Data;

    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;

    if ((INT)Number == 0)
        FileHandle = UseHandle_0;
    else if ((INT)Number == 1)
        FileHandle = UseHandle_1;
    else
        return _ERROR;

    if (FileHandle == _NULL)
        return _ERROR;

    Fseek(FileHandle, 0, SEEK_END);

    while (1)
    {
        if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
            return _ERROR;

        pExp = (BYTE *)Token;
        expMain(&pExp);
        if (wErrorword != NO_ERROR)
            return _ERROR;

        Fputs((CHAR *)szRetStr, FileHandle);
        Fputc(CR_CHAR, FileHandle);
          Fputc(LF_CHAR, FileHandle);

        RemoveSpace();
        Data = NextByte();
        if (CheckChar(Data, "\r\n"))
            break;
        else if (!CheckChar(Data, ",;"))
            return _ERROR;
    }
    return _SUCCESS;
}

#endif



TsplFuncImg.c  、、、、、、、、、、、、、、、、、、、、、

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

#define TSPLFUNCIMG_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 <stdlib.h>
#include <string.h>
#include <ctype.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 "XText.h"
#include "XBarcode.h"
#include "XGraphic.h"
#include "Expr.h"
#include "Error.h"
#include "VarMgr.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "TsplCnt.h"
#include "TsplUtil.h"
#include "TsplFunc.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     *
 *                                                                            *
 ******************************************************************************/

CONST _BarcodeTable sBarcodeTab[] =
{  
    {"CODA",    PreviewCodabar, Codabar,    0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"11",      PreviewCode11,  Code11,     0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"11C",     PreviewCode11,  Code11,     1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"128",     PreviewCode128, Code128,    0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"128M",    PreviewCode128, Code128,    1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"25",      PreviewCode25,  Code25,     0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"25C",     PreviewCode25,  Code25,     1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"39",      PreviewCode39,  Code39,     2, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"39C",     PreviewCode39,  Code39,     3, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"93",      PreviewCode93,  Code93,     0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"93C",     PreviewCode93,  Code93,     1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"CPOST",   PreviewCPost,   CPost,      0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"EAN128",  PreviewEan128,  Ean128,     0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"EAN128M", PreviewEan128,  Ean128,     1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"EAN13",   PreviewEan13,   Ean13,      0, "@0", BARCODE_OCR_FONT,    WidthEan13,   TRUE},
    {"EAN13+2", PreviewEan13,   Ean13,      2, "@0", BARCODE_OCR_FONT,    WidthEan13_2, TRUE},
    {"EAN13+5", PreviewEan13,   Ean13,      5, "@0", BARCODE_OCR_FONT,    WidthEan13_5, TRUE},
    {"EAN8",    PreviewEan8,    Ean8,       0, "@0", BARCODE_OCR_FONT,    WidthEan8,    FALSE},
    {"EAN8+2",  PreviewEan8,    Ean8,       2, "@0", BARCODE_OCR_FONT,    WidthEan8_2,  FALSE},
    {"EAN8+5",  PreviewEan8,    Ean8,       5, "@0", BARCODE_OCR_FONT,    WidthEan8_5,  FALSE},
    {"MSI",     PreviewCodemsi, Codemsi,    0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"MSIC",    PreviewCodemsi, Codemsi,    1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"POST",    PreviewPost,    Post,       0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"UPCA",    PreviewUpca,    Upca,       0, "@0", BARCODE_OCR_FONT,    WidthUpca,    TRUE},
    {"UPCA+2",  PreviewUpca,    Upca,       2, "@0", BARCODE_OCR_FONT,    WidthUpca_2,  TRUE},
    {"UPCA+5",  PreviewUpca,    Upca,       5, "@0", BARCODE_OCR_FONT,    WidthUpca_5,  TRUE},
    {"UPCE",    PreviewUpce,    Upce,       0, "@0", BARCODE_OCR_FONT,    WidthUpce,    TRUE},
    {"UPCE+2",  PreviewUpce,    Upce,       2, "@0", BARCODE_OCR_FONT,    WidthUpce_2,  TRUE},
    {"UPCE+5",  PreviewUpce,    Upce,       5, "@0", BARCODE_OCR_FONT,    WidthUpce_5,  TRUE},
    {"PLESSEY", PreviewCodemsi, Codemsi,    0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"ITF14",   PreviewItf14,   Itf14,      1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"EAN14",   PreviewEan14,   Ean14,      1, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {"LOGMARS", NotBarcode,     NotBarcode, 0, "1",  BARCODE_NOAMAL_FONT, _NULL,        FALSE},
    {(CHAR *)_NULL}
};

/******************************************************************************
 *                                                                            *
 *    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:
 *    SendUart
 *
 * Description: 
 *        This global function Uart receive data.
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
INT FN_CLS(VOID)
{
    RemoveLine();
    ClearImageBuffer(&sImageBuffer);
    ClearCounter();
    return _SUCCESS;
}

INT FN_BAR(VOID)
{
    DOUBLE Number;
    _BarAttr sBarAttr;

    sBarAttr.iType = DRAW_BAR;
    sBarAttr.psImageBuffer = &sImageBuffer;

    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.sCoord.iY = (SHORT)Number;

    sBarAttr.sCoord = XYCoord(sBarAttr.sCoord);

    // get width
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.iWidth = (WORD)Number;
    
    // get height
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    sBarAttr.iHeight = (WORD)Number;

    ReloadWaitTime();
    DrawBar(&sBarAttr);
    return _SUCCESS;
}

INT FN_DIAGONAL(VOID)
{
    DOUBLE Number;
    _DiagonalAttr sDiagonalAttr;
    SHORT SrcX, SrcY, DstX, DstY;

    sDiagonalAttr.iType = DRAW_BAR;
    sDiagonalAttr.psImageBuffer = &sImageBuffer;

    // get x1
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDiagonalAttr.sCoord1.iX = (SHORT)Number;

    // get y1
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDiagonalAttr.sCoord1.iY = (SHORT)Number;

    sDiagonalAttr.sCoord1 = XYCoord(sDiagonalAttr.sCoord1);
    SrcX = sDiagonalAttr.sCoord1.iX;
    SrcY = sDiagonalAttr.sCoord1.iY;

    // get x2
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDiagonalAttr.sCoord2.iX = (SHORT)Number;

    // get y2
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDiagonalAttr.sCoord2.iY = (SHORT)Number;

    sDiagonalAttr.sCoord2 = XYCoord(sDiagonalAttr.sCoord2);
    DstX = sDiagonalAttr.sCoord2.iX;
    DstY = sDiagonalAttr.sCoord2.iY;

    // get thickness
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    sDiagonalAttr.iThickness = (WORD)Number;

    sDiagonalAttr.Direction = DIAGONAL_VERTICAL;
    if (abs(DstX - SrcX) > abs(DstY - SrcY))
        sDiagonalAttr.Direction = DIAGONAL_HORIZONTAL;

    ReloadWaitTime();
    DrawDiagonal(&sDiagonalAttr);
    return _SUCCESS;
}

INT FN_CIRCLE(VOID)
{
    DOUBLE Number;
    _CircleAttr sCircleAttr;

    sCircleAttr.iType = DRAW_BAR;
    sCircleAttr.psImageBuffer = &sImageBuffer;

    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sCircleAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sCircleAttr.sCoord.iY = (SHORT)Number;

    sCircleAttr.sCoord = XYCoord(sCircleAttr.sCoord);

    // get radius
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sCircleAttr.iRadius = (WORD)Number;

    // get thin
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    sCircleAttr.iThickness = (WORD)Number;

    sCircleAttr.sCoord.iX += sCircleAttr.iRadius / 2;
    sCircleAttr.sCoord.iY += sCircleAttr.iRadius / 2;
    sCircleAttr.iRadius /= 2;

    if (sCircleAttr.iThickness > sCircleAttr.iRadius)
        sCircleAttr.iThickness = sCircleAttr.iRadius;

    sCircleAttr.CirclePart = FULL_CIRCLE;
    ReloadWaitTime();
    DrawCircle(&sCircleAttr);
    return _SUCCESS;
}

INT FN_ERASE(VOID)
{
    DOUBLE Number;
    _BarAttr sBarAttr;

    sBarAttr.iType = DRAW_ERASE;
    sBarAttr.psImageBuffer = &sImageBuffer;

    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.sCoord.iY = (SHORT)Number;

    sBarAttr.sCoord = XYCoord(sBarAttr.sCoord);

    // get width
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.iWidth = (WORD)Number;
    
    // get height
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    sBarAttr.iHeight = (WORD)Number;

    ReloadWaitTime();
    DrawBar(&sBarAttr);
    return _SUCCESS;
}

INT FN_REVERSE(VOID)
{
    DOUBLE Number;
    _BarAttr sBarAttr;

    sBarAttr.iType = DRAW_REVERSE;
    sBarAttr.psImageBuffer = &sImageBuffer;

    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.sCoord.iY = (SHORT)Number;

    sBarAttr.sCoord = XYCoord(sBarAttr.sCoord);

    // get width
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarAttr.iWidth = (WORD)Number;
    
    // get height
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    sBarAttr.iHeight = (WORD)Number;

    ReloadWaitTime();
    DrawBar(&sBarAttr);
    return _SUCCESS;
}

INT FN_BOX(VOID)
{
    DOUBLE Number;
    _FrameAttr sFrameAttr;
    INT Width, Height;
    INT Num;
    CHAR Data;

    sFrameAttr.iType = DRAW_BAR;
    sFrameAttr.psImageBuffer = &sImageBuffer;
    
    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sFrameAttr.sCoord.iX = (WORD)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sFrameAttr.sCoord.iY = (WORD)Number;

    // get x end
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    Num = sFrameAttr.iWidth = (WORD)Number;

    if (Num < sFrameAttr.sCoord.iX)
    {
        sFrameAttr.iWidth = sFrameAttr.sCoord.iX - Num + 1;
        sFrameAttr.sCoord.iX = (SHORT)Num;
    }
    else
        sFrameAttr.iWidth = Num - sFrameAttr.sCoord.iX + 1;

    // get y end
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;

    Num = sFrameAttr.iHeight = (WORD)Number;

    if (Num < sFrameAttr.sCoord.iY)
    {                    
        sFrameAttr.iHeight = sFrameAttr.sCoord.iY - Num + 1;
        sFrameAttr.sCoord.iY = (SHORT)Num;
    }
    else
        sFrameAttr.iHeight = Num - sFrameAttr.sCoord.iY + 1;

    sFrameAttr.sCoord = XYCoord(sFrameAttr.sCoord);

    // get Thin
    if (!GetExpNumber(BACK_WITHOUT_SPACE, &Number))
        return _ERROR;
    sFrameAttr.iThickness = (WORD)Number;

    Data = NextByte();
    if (CheckChar(Data, ",;"))
    {
        // get radius
        if (!GetExpNumber(LINE_END, &Number))
            return _ERROR;
        sFrameAttr.iRadius = (INT)Number;
        Num = (sFrameAttr.iHeight) < (sFrameAttr.iWidth) 
            ? (sFrameAttr.iHeight) : (sFrameAttr.iWidth);

        if (sFrameAttr.iRadius > Num / 2)
            sFrameAttr.iRadius = Num / 2;
    }
    else
    {
        if (!CheckTokenEnd(LINE_END, Data))
            return _ERROR;
        sFrameAttr.iRadius = 0;
    }

    ReloadWaitTime();
    DrawFrame(&sFrameAttr);
    return _SUCCESS;
}

/******************************************************************************
 *
 * TSPL Commands
 *        BARCODE
 *
 * Description:
 *
 * Syntax:
 *        BARCODE x,y,"sym",height,human,rotate,narrow,wide,[align,]"content"
 *
 * Parameters:
 *        x       = x-coordinate
 *        y       = y-coordinate
 *        sym     = symbology type
 *        height  = barcode height expressed by dot
 *        human   = human readable (0 = none, 1 = align left, 2 = align center, 3 = align right)
 *        rotate  = rotation (0, 90, 180, and 270 valid)
 *        narrow  = width of narrow element in dot
 *        wide    = width of wide element in dot
 *        align   = barcode justification (1 = align left, 2 = align center, 3 = align right)
 *        content = barcode content or string expression
 *
 ******************************************************************************/
INT FN_BARCODE(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _BarCodeAttr sBarcodeAttr;
    _BarcodeTable *psBarcodeTab;
    SHORT Justification;
    CHAR FontName[FONT_NAME_MAX];
    CHAR Content[STRING_LEN];
    CHAR Name[TOKEN_LEN];
    CHAR Data;
    INT ParamType;
    INT LinkNum;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.sCoord.iY = (SHORT)Number;

    sBarcodeAttr.sCoord = XYCoord(sBarcodeAttr.sCoord);

    // get barcode name
    if (!GetExpString(COMMA_END, Name, sizeof(Name)))
        return _ERROR;
    if ((psBarcodeTab = CheckBarcodeTable(Name, sBarcodeTab)) == _NULL)
        return _ERROR;
    strcpy(FontName, psBarcodeTab->FontName);
    sBarcodeAttr.pFont = (BYTE *)FontName;

    // get height
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.iHeight = (WORD)Number;

    // get human readable
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.iHuman = (WORD)Number;

    // get rotation
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.iRotation = (WORD)Number;

    // get narrow bar
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.iNarrow = (WORD)Number;

    // get wide bar
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBarcodeAttr.iWide = (WORD)Number;

    sBarcodeAttr.FontHoriMulti = 1;
    sBarcodeAttr.FontVertMulti = 1;
    sBarcodeAttr.AboveCode = FALSE;

    if (psBarcodeTab->FontType == BARCODE_NOAMAL_FONT)
    {
#if defined(TSPL_VER_1)
        FontName[0] = '3';
#else
        if (sBarcodeAttr.iNarrow < 2)
            FontName[0] += 0;
        else if (sBarcodeAttr.iNarrow < 3)
            FontName[0] += 1;
        else if (sBarcodeAttr.iNarrow < 4)
            FontName[0] += 2;
        else
            FontName[0] += 3;
#endif
    }
    else if (psBarcodeTab->FontType == BARCODE_OCR_FONT)
    {
        if (sBarcodeAttr.iNarrow > 10)
            FontName[1] += 9;
        else
            FontName[1] += sBarcodeAttr.iNarrow - 1;
    }

#if defined(TSPL_VER_1)
    if (strcmp(Name, "POST") == 0)
        sBarcodeAttr.iHuman = 0;
#endif

    sBarcodeAttr.iCheck = psBarcodeTab->Check;
    sBarcodeAttr.eLanguage = LANG_TSPL;
    sBarcodeAttr.ePutWay = PUT_OR;

    Justification = 0;

    ParamType = GetExpParam(BACK_WITHOUT_SPACE, &sParam, Content, sizeof(Content));

    // get Justification (optional)
    if (ParamType == EXP_PARAM_NUMBER)
    {
        Data = NextByte();
        if (!CheckTokenEnd(COMMA_END, Data))
            return _ERROR;

        if (sParam.Number >= 0 && sParam.Number <= 3)
            Justification = (SHORT)sParam.Number;

        ParamType = GetExpParam(BACK_WITHOUT_SPACE, &sParam, Content, sizeof(Content));
    }
    if (ParamType != EXP_PARAM_STRING)
        return _ERROR;

    Data = NextByte();
    if (!CheckTokenEnd(LINE_END, Data))
        return _ERROR;

    if (sParam.Counter)
    {
        if (strlen(Content) >= EXPRESS_LEN)
            return _ERROR;
        if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
            return _ERROR;
        sCntLinkTbl[LinkNum].CountType = BARCODE_COUNT;
        sCntLinkTbl[LinkNum].psBarcodeTab = psBarcodeTab;
        sCntLinkTbl[LinkNum].Data.sBarcodeAttr = sBarcodeAttr;
        sCntLinkTbl[LinkNum].Justification = Justification;
        strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, Content);
        strcpy((CHAR *)sCntLinkTbl[LinkNum].FontName, FontName);
        memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
        return _SUCCESS;
     }

    if (strlen(sParam.String) >= sizeof(Content))
        return _ERROR;
    strcpy(Content, sParam.String);

    sBarcodeAttr.pExp = (BYTE *)Content;
    sBarcodeAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();

    if (Justification == 2 || Justification == 3)
    {
        SHORT Adjust = 0;

        psBarcodeTab->PreviewBarcode(&sBarcodeAttr);

        if (Justification == 2)    // align center
            Adjust = sBarcodeAttr.TotalWidth >> 1;
        if (Justification == 3)    // align right
            Adjust = sBarcodeAttr.TotalWidth;

        if (sBarcodeAttr.iRotation == 0)
            sBarcodeAttr.sCoord.iX -= Adjust;
        if (sBarcodeAttr.iRotation == 90)
            sBarcodeAttr.sCoord.iY -= Adjust;
        if (sBarcodeAttr.iRotation == 180)
            sBarcodeAttr.sCoord.iX += Adjust;
        if (sBarcodeAttr.iRotation == 270)
            sBarcodeAttr.sCoord.iY += Adjust;
    }
    

//#if defined(TSPL_VER_1)
    if ( strlen((CHAR *)sBarcodeAttr.pExp) )
//#endif
        psBarcodeTab->OutBarcode(&sBarcodeAttr);

    return _SUCCESS;
}

/******************************************************************************
 *
 * TSPL Commands
 *        TEXT
 *
 * Description:
 *
 * Syntax:
 *        TEXT x,y,"font",rotate,x-multi,y-multi,[align,]"content"
 *
 * Parameters:
 *        x       = x-coordinate
 *        y       = y-coordinate
 *        font    = font name
 *        rotate  = rotation (0, 90, 180, and 270 valid)
 *        x-multi = horizontal multiplication, up to 10x
 *        y-multi = vertical multiplication, up to 10x
 *        align   = text justification (1 = align left, 2 = align center, 3 = align right)
 *        content = text content or string expression
 *
 ******************************************************************************/
INT FN_TEXT(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _TextAttr sTextAttr;
    SHORT Justification;
    CHAR FontName[FONT_NAME_MAX];
    CHAR Content[STRING_LEN];
    CHAR Data;
    INT ParamType;
    INT LinkNum;

    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sTextAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sTextAttr.sCoord.iY = (SHORT)Number;

    sTextAttr.sCoord = XYCoord(sTextAttr.sCoord);

    // get font name
    if (!GetExpString(COMMA_END, FontName, sizeof(FontName)))
        return _ERROR;
    sTextAttr.pFont = (BYTE *)FontName;

    // get rotation
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sTextAttr.iDirection = sTextAttr.iRotation = (WORD)Number;

    // get X multiply
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sTextAttr.iHoriMulti = (WORD)Number;

    // get Y multiply
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sTextAttr.iVertMulti = (WORD)Number;

    if (sTextAttr.iVertMulti == 0)
        sTextAttr.iVertMulti = sTextAttr.iHoriMulti;
    if (sTextAttr.iHoriMulti == 0)
        sTextAttr.iHoriMulti = sTextAttr.iVertMulti;

    // old TrueTypeFont
    if (strcmp((CHAR *)sTextAttr.pFont, "ROMAN.TTF") == 0)
        sTextAttr.iHoriMulti = sTextAttr.iVertMulti;

    sTextAttr.eLanguage = LANG_TSPL;
    sTextAttr.ePutWay = PUT_OR;

    Justification = 0;

    ParamType = GetExpParam(BACK_WITHOUT_SPACE, &sParam, Content, sizeof(Content));

    // get Justification (optional)
    if (ParamType == EXP_PARAM_NUMBER)
    {
        Data = NextByte();
        if (!CheckTokenEnd(COMMA_END, Data))
            return _ERROR;

        if (sParam.Number >= 0 && sParam.Number <= 3)
            Justification = (SHORT)sParam.Number;

        ParamType = GetExpParam(BACK_WITHOUT_SPACE, &sParam, Content, sizeof(Content));
    }
    if (ParamType != EXP_PARAM_STRING)
        return _ERROR;

    Data = NextByte();
    if (!CheckTokenEnd(LINE_END, Data))
        return _ERROR;

    if (sParam.Counter)
    {
        if (strlen(Content) >= EXPRESS_LEN)
            return _ERROR;
        if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
            return _ERROR;
        sCntLinkTbl[LinkNum].CountType = TEXT_COUNT;
        sCntLinkTbl[LinkNum].Data.sTextAttr = sTextAttr;
        sCntLinkTbl[LinkNum].Justification = Justification;
        strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, Content);
        strcpy((CHAR *)sCntLinkTbl[LinkNum].FontName, FontName);
        memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
        return _SUCCESS;
     }

    if (strlen(sParam.String) >= sizeof(Content))
        return _ERROR;
    strcpy(Content, sParam.String);

    sTextAttr.ExpLength = strlen(Content);
    sTextAttr.pExp = (BYTE *)Content;
    sTextAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();

    if (Justification == 2 || Justification == 3)
    {
        SHORT Adjust = 0;

        PreviewText(&sTextAttr);

        if (Justification == 2)        // align center
            Adjust = sTextAttr.iRealWidth >> 1;
        if (Justification == 3)        // align right
            Adjust = sTextAttr.iRealWidth;

        if (sTextAttr.iRotation == 0)
            sTextAttr.sCoord.iX -= Adjust;
        if (sTextAttr.iRotation == 90)
            sTextAttr.sCoord.iY -= Adjust;
        if (sTextAttr.iRotation == 180)
            sTextAttr.sCoord.iX += Adjust;
        if (sTextAttr.iRotation == 270)
            sTextAttr.sCoord.iY += Adjust;
    }

    OutText(&sTextAttr);

    return _SUCCESS;
}

INT FN_BITMAP(VOID)
{
    DOUBLE Number;
    _BMPAttr sBMPAttr;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBMPAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBMPAttr.sCoord.iY = (SHORT)Number;

    sBMPAttr.sCoord = XYCoord(sBMPAttr.sCoord);

    // get Width
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBMPAttr.iImageWidth = (WORD)Number * 8;

    // get height
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBMPAttr.iImageHeight = (WORD)Number;

    // get mode
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    if ((WORD)Number > 3)
        return _ERROR;

    sBMPAttr.iMode = (WORD)Number;
    
    sBMPAttr.psImageBuffer = &sImageBuffer;
    sBMPAttr.ReadByte = NextByte;

    ReloadWaitTime();
    if (BITMAP(&sBMPAttr) == _ERROR)
    {
        RemoveLine();
        return _ERROR;
    }
    return _SUCCESS;
}

INT FN_PUTBMP(VOID)
{
    DOUBLE Number;
    _BMPAttr sBMPAttr;
    BYTE FileName[FILENAME_LENGTH];

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBMPAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sBMPAttr.sCoord.iY = (SHORT)Number;

    sBMPAttr.sCoord = XYCoord(sBMPAttr.sCoord);

    // get name
    if (!GetExpString(LINE_END, (CHAR *)FileName, sizeof(FileName)))
        return _ERROR;
    sBMPAttr.pbFileName = FileName;

    sBMPAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    return BMPmain(&sBMPAttr);
}

INT FN_PUTPCX(VOID)
{
    DOUBLE Number;
    _PCXAttr sPCXAttr;
    BYTE FileName[FILENAME_LENGTH];

    // get x
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPCXAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPCXAttr.sCoord.iY = (SHORT)Number;

    sPCXAttr.sCoord = XYCoord(sPCXAttr.sCoord);

    // get name
    if (!GetExpString(LINE_END, (CHAR *)&FileName, sizeof(FileName)))
        return _ERROR;
    sPCXAttr.pbFileName = FileName;

    sPCXAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    return PCXmain(&sPCXAttr);
}

/******************************************************************************
 *
 * TSPL Commands
 *        AZTEC
 *
 * Description:
 *
 * Syntax:
 *        AZTEC x,y,rotate,[size,]ecp,]flg,]menu,]multi,]rev,]"content"
 *
 * Parameters:
 *        x       = x-coordinate
 *        y       = y-coordinate
 *        rotate  = rotation (0, 90, 180, and 270 valid)
 *        size    = element module size (1 to 20), default is 6
 *        ecp     = error control (& symbol size/type) parameter
 *                  0          : default error correction level
 *                  1   to 99  : minimum error correction percentage
 *                  101 to 104 : 1 to 4-layer Compact symbol
 *                  201 to 232 : 1 to 32-layer Full-Range symbol
 *                  300        : a simple Aztec "Rune"
 *        flg     = 0 : input message is straight bytes
 *                  1 : input uses "<Esc>n" for FLG(n), "<Esc><Esc>" for "<Esc>"
 *        menu    = menu symbol (0 : no, 1 : yes), default is 0
 *        multi   = numebr of symbols (1 to 26), default is 6
 *        rev     = output to be reversed (0 : no, 1 : yes), default is 0
 *        content = barcode content or string expression
 *
 ******************************************************************************/
INT FN_AZTEC(VOID)
{
    _ExpParam sParam;
    _AztecAttr sAztecAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR Data;
    INT ParamType;
    INT Place;
    INT LinkNum;

    /* option default */
    sAztecAttr.ModuleSize   = 6;
    sAztecAttr.ErrorControl = 0;
    sAztecAttr.FlagChar     = 0;
    sAztecAttr.MenuSymbol   = 0;
    sAztecAttr.MultiSymbol  = 1;
    sAztecAttr.Reverse      = 0;

    sAztecAttr.pID     = _NULL;
    sAztecAttr.ePutWay = PUT_OR;

    Place = 0;
    while (1)
    {
        ParamType = GetExpParam(BACK_WITHOUT_SPACE, &sParam, LongData, sizeof(LongData));

        if (ParamType == EXP_PARAM_ERROR)
            return _ERROR;

        Data = NextByte();

        if (ParamType == EXP_PARAM_NUMBER)
        {
            if (!CheckTokenEnd(COMMA_END, Data))
                return _ERROR;

            Place += 1;
            switch (Place)
            {
                case 1:    /* x-coordinate */
                    sAztecAttr.sCoord.iX = (SHORT)sParam.Number;
                    break;
                case 2:    /* y-coordinate */
                    sAztecAttr.sCoord.iY = (SHORT)sParam.Number;
                    sAztecAttr.sCoord = XYCoord(sAztecAttr.sCoord);
                    break;
                case 3:    /* rotation */
                    sAztecAttr.Rotate = (WORD)sParam.Number;
                    break;
                case 4:    /* module size */
                    if (sParam.Number >= 1 && sParam.Number <= 20)
                        sAztecAttr.ModuleSize = (WORD)sParam.Number;
                    break;
                case 5:    /* error control (& symbol size/type) parameter */
                    if (sParam.Number >= 0 && sParam.Number <= 300)
                        sAztecAttr.ErrorControl = (WORD)sParam.Number;
                    break;
                case 6:    /* flag characters */
                    if (sParam.Number >= 0 && sParam.Number <= 1)
                        sAztecAttr.FlagChar = (BYTE)sParam.Number;
                    break;
                case 7:    /* menu symbol */
                    if (sParam.Number >= 0 && sParam.Number <= 1)
                        sAztecAttr.MenuSymbol = (BYTE)sParam.Number;
                    break;
                case 8:    /* number of symbols (1 to 26) */
                    if (sParam.Number >= 1 && sParam.Number <= 26)
                        sAztecAttr.MultiSymbol = (BYTE)sParam.Number;
                    break;
                case 9:    /* output reversed */
                    if (sParam.Number >= 0 && sParam.Number <= 1)
                        sAztecAttr.Reverse = (BYTE)sParam.Number;
                    break;
                default:
                    return _ERROR;
            }
        }

        if (ParamType == EXP_PARAM_STRING)
        {
            if (!CheckTokenEnd(LINE_END, Data))
                return _ERROR;

            /* simple: AZTEC x,y,rotate,"content" */
            if (Place < 3)
                return _ERROR;

            if (sParam.Counter)
            {
                if (strlen(LongData) >= EXPRESS_LEN)
                    return _ERROR;
                if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
                    return _ERROR;
                sCntLinkTbl[LinkNum].CountType = AZTEC_COUNT;
                sCntLinkTbl[LinkNum].Data.sAztecAttr = sAztecAttr;
                strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
                memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
                return _SUCCESS;
             }
            if (strlen(sParam.String) >= sizeof(LongData))
                return _ERROR;
            strcpy(LongData, sParam.String);
            break;
        }
    }

    sAztecAttr.ExpLen = strlen(LongData);
    sAztecAttr.pExp   = (BYTE *)LongData;
    sAztecAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!ImpAztec(&sAztecAttr, TRUE))
        return _ERROR;

    return _SUCCESS;
}

INT FN_DMATRIX(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _DMatrixAttr sDmatrixAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR Command;
    INT LinkNum;
    INT ParatFlag;

    sDmatrixAttr.FormatID  = 0x01;
    sDmatrixAttr.EccType   = LCN_ECCTYPE_ECC200;
    sDmatrixAttr.CtrlChr   = 0;
    sDmatrixAttr.CellWidth = 0;
    sDmatrixAttr.Xcells    = 0;
    sDmatrixAttr.Ycells    = 0;
    sDmatrixAttr.Human     = 0;
    sDmatrixAttr.Rotate    = 0;
    sDmatrixAttr.ExpLen    = 0;
    sDmatrixAttr.eLanguage = LANG_TSPL;
    sDmatrixAttr.ePutWay   = PUT_OR;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDmatrixAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDmatrixAttr.sCoord.iY = (SHORT)Number;

    sDmatrixAttr.sCoord = XYCoord(sDmatrixAttr.sCoord);

    // get width limit
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDmatrixAttr.WLimit = (WORD)Number;

    // get hieght limit
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sDmatrixAttr.HLimit = (WORD)Number;

//#if defined(TSPL_VER_1)
//    while (GetOptParam(COMMA_END, "x", (CHAR *)&Command, &Number))
//    {
//        switch (Command)
//        {
//            case 'x':
//                sDmatrixAttr.CellWidth = (WORD)Number;
//                break;
//        }
//    }
//#else
    while (1)
    {
        RemoveSpace();
        Command = NextByte();
        ParatFlag =  TRUE;
        if (isdigit(Command))
        {
            WORD XCell, YCell;

            BackByte(Command);
            GetExpNumber(COMMA_END, &Number);

            if (sDmatrixAttr.Xcells == 0)
            {
                XCell = ChkXcellDMX((BYTE)sDmatrixAttr.EccType, (WORD)Number);
                sDmatrixAttr.Xcells = XCell;
            }
            else
            {
                ChkXYcellDMX((BYTE)sDmatrixAttr.EccType, XCell, (WORD)Number, &XCell, &YCell);
                sDmatrixAttr.Ycells = YCell;
            }
        }
        else
        {
            switch (Command)
            {
                case 'x':
                    GetExpNumber(COMMA_END, &Number);
                    sDmatrixAttr.CellWidth = (WORD)Number;
                    break;
                default:
                    BackByte(Command);
                    ParatFlag = FALSE;
                    break;
            }
        }
        if (ParatFlag == FALSE)
            break;
    }
//#endif

    if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
        return _ERROR;

    if (sParam.Counter)
    {
        if (strlen(LongData) >= EXPRESS_LEN)
            return _ERROR;
        if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
            return _ERROR;
        sCntLinkTbl[LinkNum].CountType = DMATRIX_COUNT;
        sCntLinkTbl[LinkNum].Data.sDMatrixAttr = sDmatrixAttr;
        strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
        memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
        return _SUCCESS;
     }

    if (strlen(sParam.String) >= sizeof(LongData))
        return _ERROR;
    strcpy(LongData, sParam.String);

    sDmatrixAttr.ExpLen = strlen(LongData);
    sDmatrixAttr.pExp = (BYTE *)LongData;
    sDmatrixAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!Dmatrix(&sDmatrixAttr))
        return _ERROR;

    return _SUCCESS;
}

#if defined(TSPL_VER_1)

INT FN_MAXI(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _MaxiAttr sMaxiAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR Parameter[32];
    INT LinkNum;

    sMaxiAttr.eLanguage = LANG_TSPL;
    sMaxiAttr.ePutWay = PUT_OR;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sMaxiAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sMaxiAttr.sCoord.iY = (SHORT)Number;

    sMaxiAttr.sCoord = XYCoord(sMaxiAttr.sCoord);

    sMaxiAttr.iMode = MaxiCodeMode;

    if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
        return _ERROR;

    if (sMaxiAttr.iMode == 2 || sMaxiAttr.iMode == 3)
    {
        memset(Parameter, 0, sizeof(Parameter));
        strncpy(Parameter, sParam.String, 19);

        if (Parameter[3] != ',' || Parameter[7] != ',')
            return _ERROR;
        Parameter[3] = '\0';
        Parameter[7] = '\0';
        sMaxiAttr.iClass = atoi(Parameter);
        sMaxiAttr.iCountry = atoi(Parameter + 4);
    
        if (Parameter[13] == ',' && Parameter[18] == ',')    // mode 2
        {
            Parameter[13] = '\0';
            Parameter[18] = '\0';
            sMaxiAttr.iPost = atoi(Parameter + 8) * 10000 + atoi(Parameter + 14);
            sMaxiAttr.iMode = 2;
        }
        else if (Parameter[14] == ',')        // mode 3
        {
            Parameter[14] = '\0';
            strncpy((CHAR *)sMaxiAttr.abPost, Parameter + 8, 6);
            sMaxiAttr.abPost[6] = '\0';
            sMaxiAttr.iMode = 3;
        }
        else
            return _ERROR;
    }

    if (sParam.Counter)
    {
        if (strlen(LongData) >= EXPRESS_LEN)
            return _ERROR;
        if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
            return _ERROR;
        sCntLinkTbl[LinkNum].CountType = MAXI_COUNT;
        sCntLinkTbl[LinkNum].Data.sMaxiAttr = sMaxiAttr;
        strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
        memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
        return _SUCCESS;
     }

    if (strlen(sParam.String) >= sizeof(LongData))
        return _ERROR;
    strcpy(LongData, sParam.String);

    sMaxiAttr.pExp = (BYTE *)LongData;
    if (sMaxiAttr.iMode == 2)
        sMaxiAttr.pExp = (BYTE *)LongData + 19;
    if (sMaxiAttr.iMode == 3)
        sMaxiAttr.pExp = (BYTE *)LongData + 15;
    sMaxiAttr.ExpLen = strlen((CHAR *)sMaxiAttr.pExp);
    sMaxiAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!Maxi(&sMaxiAttr))
        return _ERROR;

    return _SUCCESS;
}

#else

INT FN_MAXI(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _MaxiAttr sMaxiAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR Command;
    INT LinkNum;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sMaxiAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sMaxiAttr.sCoord.iY = (SHORT)Number;

    sMaxiAttr.sCoord = XYCoord(sMaxiAttr.sCoord);

    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sMaxiAttr.iMode = (WORD)Number;

    if (sMaxiAttr.iMode == 2 || sMaxiAttr.iMode == 3)
    {
        // get class
        if (!GetExpNumber(COMMA_END, &Number))
            return _ERROR;
        sMaxiAttr.iClass = (WORD)Number;

        // get country
        if (!GetExpNumber(COMMA_END, &Number))
            return _ERROR;
        sMaxiAttr.iCountry = (WORD)Number;

        if ( sMaxiAttr.iMode == 2 )
        {
            // get post code
            if (!GetExpNumber(COMMA_END, &Number))
                return _ERROR;
            if ((LONG)Number > 99999)
                return _ERROR;
            sMaxiAttr.iPost = (LONG)Number * 10000;

            if (!GetExpNumber(COMMA_END, &Number))
                return _ERROR;
            if ((WORD)Number > 9999)
                return _ERROR;
            sMaxiAttr.iPost += (WORD)Number;
        }
        else if (!GetExpString(COMMA_END, (CHAR *)sMaxiAttr.abPost, sizeof(sMaxiAttr.abPost)))
            return _ERROR;
    }

    sMaxiAttr.ExpLen = 0;
    while (GetOptParam(COMMA_END, "L", &Command, &Number))
    {
        if (Command == 'L')
        {
            sMaxiAttr.ExpLen = (WORD)Number;
            break;
        }
    }

    if (sMaxiAttr.ExpLen != 0)
    {
        INT i;
        for (i = 0; i < sMaxiAttr.ExpLen; i++)
            *(LongData + i) = NextByte();
        *(LongData + i) = '\0';
    }
    else
    {
        if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
            return _ERROR;

        if (sParam.Counter)
        {
            if (strlen(LongData) >= EXPRESS_LEN)
                return _ERROR;
            if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
                return _ERROR;
            sCntLinkTbl[LinkNum].CountType = MAXI_COUNT;
            sCntLinkTbl[LinkNum].Data.sMaxiAttr = sMaxiAttr;
            strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
            memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
            return _SUCCESS;
         }

        if (strlen(sParam.String) >= sizeof(LongData))
            return _ERROR;
        strcpy(LongData, sParam.String);

        sMaxiAttr.ExpLen = strlen(LongData);
    }

    sMaxiAttr.pExp = (BYTE *)LongData;
    sMaxiAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!Maxi(&sMaxiAttr))
        return _ERROR;

    return _SUCCESS;
}

#endif

INT FN_PDF(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _PDFAttr sPDFAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR Command;
    INT LinkNum;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPDFAttr.sCoord.iX = (SHORT)Number;

    // get y
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPDFAttr.sCoord.iY = (SHORT)Number;

    sPDFAttr.sCoord = XYCoord(sPDFAttr.sCoord);

    // get width limit
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPDFAttr.iWLimit = (WORD)Number;
    
    // get hieght limit
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPDFAttr.iHLimit = (WORD)Number;
    
    // get rotation
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sPDFAttr.Rotate = (WORD)Number;

    if (sPDFAttr.Rotate == 90 || sPDFAttr.Rotate == 270)
    {
        SHORT Switch = sPDFAttr.iWLimit;
        sPDFAttr.iWLimit = sPDFAttr.iHLimit;
        sPDFAttr.iHLimit = Switch;
    }

    // initial other parament
    sPDFAttr.iNarrow     = 0;
    sPDFAttr.iHeight     = 0;
    sPDFAttr.iHuman      = 0;
#if defined(TSPL_VER_1)
    sPDFAttr.iEccL       = 1;
#else
    sPDFAttr.iEccL       = -1;
#endif
    sPDFAttr.iMaxRow     = 0;
    sPDFAttr.iMaxCol     = 0;
    sPDFAttr.iTruncation = 0;
    sPDFAttr.ExpLen      = 0;
    sPDFAttr.pType       = (BYTE *)"2";
    sPDFAttr.eLanguage   = LANG_TSPL;
    sPDFAttr.ePutWay     = PUT_OR;
    sPDFAttr.iCenter     = 0;

    while (GetOptParam(COMMA_END, "WHUERCTPML", &Command, &Number))
    {
        switch (Command)
        {
            case 'W':
                sPDFAttr.iNarrow = (WORD)Number;
                break;
            case 'H':
                sPDFAttr.iHeight = (WORD)Number;
                break;
            case 'U':
                // get x
                sPDFAttr.sWordCoord.iX = XCoord((SHORT)Number);

                // get y
                if (!GetExpNumber(COMMA_END, &Number))
                    return _ERROR;
                sPDFAttr.sWordCoord.iY = YCoord((SHORT)Number);

                if (!GetExpNumber(COMMA_END, &Number))
                    return _ERROR;

                sPDFAttr.iWordNum = (WORD)Number;
                sPDFAttr.iHuman = 1;
                break;
            case 'E':
                sPDFAttr.iEccL = (WORD)Number;
                break;
            case 'R':
                sPDFAttr.iMaxRow = (WORD)Number;
                break;
            case 'C':
                sPDFAttr.iMaxCol = (WORD)Number;
                break;
            case 'T':
                sPDFAttr.iTruncation = (WORD)Number;
                break;
            case 'P':
            case 'M':
                break;
            case 'L':
                sPDFAttr.ExpLen = (WORD)Number;
                break;
        }
        if (Command == 'L')
            break;
    }

    if (sPDFAttr.ExpLen != 0)
    {
        INT i;
        for (i = 0; i < sPDFAttr.ExpLen; i++)
            *(LongData + i) = NextByte();
        *(LongData + i) = '\0';
    }
    else
    {
        if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
            return _ERROR;

        if (sParam.Counter)
        {
            if (strlen(LongData) >= EXPRESS_LEN)
                return _ERROR;
            if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
                return _ERROR;
            sCntLinkTbl[LinkNum].CountType = PDF_COUNT;
            sCntLinkTbl[LinkNum].Data.sPDFAttr = sPDFAttr;
            strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
            memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
            return _SUCCESS;
         }

        if (strlen(sParam.String) >= sizeof(LongData))
            return _ERROR;
        strcpy(LongData, sParam.String);

        sPDFAttr.ExpLen = strlen(LongData);
    }

    sPDFAttr.pExp = (BYTE *)LongData;
    sPDFAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!PDF(&sPDFAttr))
        return _ERROR;

    return _SUCCESS;
}

INT FN_MPDF(VOID)
{
    CHAR Data;
    DOUBLE dData;
    BYTE bCommand;
    CHAR LongData[LONG_STR_LEN];
    _MPDFAttr sMPDFAttr;
    _ExpParam sParam;
    INT i;
    INT LinkNum;
    LONG lData;
    BOOL CounterFlag = FALSE;

    // get x 
    if (!GetExpNumber(COMMA_END, &dData))
        return _ERROR;
    sMPDFAttr.sCoord.iX = (SHORT)dData;

    // get y
    if (!GetExpNumber(COMMA_END, &dData))
        return _ERROR;
    sMPDFAttr.sCoord.iY = (SHORT)dData;

    sMPDFAttr.sCoord = XYCoord(sMPDFAttr.sCoord);

    // get rotation
    if (!GetExpNumber(COMMA_END, &dData))
        return _ERROR;
    sMPDFAttr.Rotate = (WORD)dData;

    // initial other parament
    sMPDFAttr.Ecc = 0;
    sMPDFAttr.Cell = 1;
    sMPDFAttr.Height = 10;
    sMPDFAttr.Column = 0;

    sMPDFAttr.ExpLen = 0;
    sMPDFAttr.eLanguage = LANG_TSPL;
    sMPDFAttr.ePutWay = PUT_OR;

    while (GetOptParam(COMMA_END, "WHCL", (CHAR *)&bCommand, &dData))
    {
        switch (bCommand)
        {
            case 'W':
                sMPDFAttr.Cell = (WORD)dData;
                break;
            case 'C':
                sMPDFAttr.Column = (WORD)dData;
                break;
            case 'H':
                sMPDFAttr.Height = (WORD)dData;
                break;
            case 'L':
                sMPDFAttr.ExpLen = (WORD)dData;
                break;
        }
    }

    if (sMPDFAttr.ExpLen != 0)
    {
        INT i;
        for (i = 0; i < sMPDFAttr.ExpLen; i++)
            *(LongData + i) = NextByte();
        *(LongData + i) = '\0';
    }
    else
    {
        if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
            return _ERROR;

        if (sParam.Counter)
        {
            if (strlen(LongData) >= EXPRESS_LEN)
                return _ERROR;
            if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
                return _ERROR;
            sCntLinkTbl[LinkNum].CountType = MPDF_COUNT;
            sCntLinkTbl[LinkNum].Data.sMPdfAttr = sMPDFAttr;
            strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
            memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
            return _SUCCESS;
         }

        if (strlen(sParam.String) >= sizeof(LongData))
            return _ERROR;
        strcpy(LongData, sParam.String);

        sMPDFAttr.ExpLen = strlen(LongData);
    }
    sMPDFAttr.pExp = (BYTE *)LongData;
    sMPDFAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();

    if (!MPDF(&sMPDFAttr, FALSE))
        return _ERROR;

    return _SUCCESS;
}

INT FN_QRCODE(VOID)
{
    DOUBLE Number;
    _ExpParam sParam;
    _QRCodeAttr sQRCodeAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR CharToken[2];
    CHAR Command;
    INT LinkNum;
    INT Num;

    sQRCodeAttr.iModelNum = 0x01;    
    sQRCodeAttr.MaskNum   = 0x0f;
    sQRCodeAttr.MaskNum  &= 0xfff0;
    sQRCodeAttr.MaskNum  |= 7;
    sQRCodeAttr.ExpLen    = 0;
    sQRCodeAttr.eLanguage = LANG_TSPL;
    sQRCodeAttr.ePutWay   = PUT_OR;

    // get x 
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sQRCodeAttr.sCoord.iX = (SHORT)Number;

    // get y
    if ( !GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sQRCodeAttr.sCoord.iY = (SHORT)Number;

    sQRCodeAttr.sCoord = XYCoord(sQRCodeAttr.sCoord);

    // get ECC Level
    if (!GetExpToken(COMMA_END, CharToken, sizeof(CharToken)))
        return _ERROR;

    switch (*CharToken)
    {
        case 'L':
        case 'M':
        case 'Q':
        case 'H':
            sQRCodeAttr.bErrLV = *CharToken;
            break;
        default:
            sQRCodeAttr.bErrLV = 'L';
            break;
    }

    // get Cell Witdh
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sQRCodeAttr.CellWidth = (WORD)Number;

    // get Encode mode
    if (!GetExpToken(COMMA_END, CharToken, sizeof(CharToken)))
        return _ERROR;

    switch (*CharToken)
    {
        case 'M':
        case 'A':  
            sQRCodeAttr.bModel = *CharToken;
            break;
        default:
            sQRCodeAttr.bModel = 'A';
            break;
    }

    // get rotate
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sQRCodeAttr.Rotate = (WORD)Number;
    if (sQRCodeAttr.Rotate != 0 &&
        sQRCodeAttr.Rotate != 90 &&
        sQRCodeAttr.Rotate != 180 &&
        sQRCodeAttr.Rotate != 270)
        sQRCodeAttr.Rotate = 0;

    while (GetOptParam(COMMA_END, "MS", &Command, &Number))
    {
        switch (Command)
        {
            case 'M':
                Num = (WORD)Number;
                if (Num != 1 && Num != 2)
                    Num = 1;
                sQRCodeAttr.iModelNum = (WORD)Number;
                break;
            case 'S':
                Num = (WORD)Number;
                if (Num >= 8)
                    Num = 7;
                sQRCodeAttr.MaskNum &= 0xfff0;
                sQRCodeAttr.MaskNum |= Num;
                break;
        }
    }

    if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
        return _ERROR;

    if (sParam.Counter)
    {
        if (strlen(LongData) >= EXPRESS_LEN)
            return _ERROR;
        if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
            return _ERROR;
        sCntLinkTbl[LinkNum].CountType = QRCODE_COUNT;
        sCntLinkTbl[LinkNum].Data.sQRCodeAttr = sQRCodeAttr;
        strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
        memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
        return _SUCCESS;
     }

    if (strlen(sParam.String) >= sizeof(LongData))
        return _ERROR;
    strcpy(LongData, sParam.String);

    sQRCodeAttr.ExpLen = strlen(LongData);
    sQRCodeAttr.pExp = (BYTE *)LongData;
    sQRCodeAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!QRCode(&sQRCodeAttr))
        return _ERROR;

    return _SUCCESS;
}

/******************************************************************************
 *
 * TSPL Commands
 *        RSS
 *
 * Description:
 *        Reduced Space Symbology Bar Code
 *
 * Syntax:
 *        RSS x,y,"sym",rotate,pixMult,sepHt,"content"
 *
 *        RSS x,y,"RSSEXP",rotate,pixMult,sepHt,segWidth,"content"
 *        RSS x,y,"UCC128CCA",rotate,pixMult,sepHt,linHeight,"content"
 *        RSS x,y,"UCC128CCC",rotate,pixMult,sepHt,linHeight,"content"
 *
 * Parameters:
 *        x         = x-coordinate
 *        y         = y-coordinate
 *        sym       = symbology type
 *                    RSS14     - RSS14
 *                    RSS14T    - RSS14 Truncated
 *                    RSS14S    - RSS14 Stacked
 *                    RSS14SO   - RSS14 Stacked Omnidirectional
 *                    RSSLIM    - RSS Limited
 *                    RSSEXP    - RSS Expanded
 *                    UPCA      - UPC-A
 *                    UPCE      - UPC-E
 *                    EAN13     - EAN-13
 *                    EAN8      - EAN-8
 *                    UCC128CCA - UCC/EAN-128 & CC-A/B
 *                    UCC128CCC - UCC/EAN-128 & CC-C
 *        rotate    = rotation (0, 90, 180, and 270 valid)
 *        pixMult   = pixels per X (1 to 10 valid)
 *        sepHt     = separator row height (1 and 2 valid)
 *        segWidth  = segment width of RSS expanded (even 2 to 22 valid)
 *        linHeight = UCC/EAN-128 height in X (1 to 500 valid)
 *        content   = barcode content or string expression
 *
 ******************************************************************************/
INT FN_RSS(VOID)
{
    STATIC CONST CHAR *SymName[] = 
    {
        "RSS14",
        "RSS14T",
        "RSS14S",
        "RSS14SO",
        "RSSLIM",
        "RSSEXP",
        "UPCA",
        "UPCE",
        "EAN13",
        "EAN8",
        "UCC128CCA",
        "UCC128CCC",
    };

    DOUBLE Number;
    _ExpParam sParam;
    _RSSAttr sRSSAttr;
    CHAR LongData[LONG_STR_LEN];
    CHAR Name[TOKEN_LEN];
    INT SymType;
    INT LinkNum;

    sRSSAttr.ePutWay = PUT_OR;

    /* x-coordinate */
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sRSSAttr.sCoord.iX = (SHORT)Number;

    /* y-coordinate */
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sRSSAttr.sCoord.iY = (SHORT)Number;

    sRSSAttr.sCoord = XYCoord(sRSSAttr.sCoord);

    /* symbology type */
    if (!GetExpString(COMMA_END, Name, sizeof(Name)))
        return _ERROR;
    for (SymType = 0; SymType < sizeof(SymName) / sizeof(CHAR *); SymType++)
        if (strcmp(Name, SymName[SymType]) == 0)
            break;
    if (SymType == sizeof(SymName) / sizeof(CHAR *))
        return _ERROR;
    sRSSAttr.sym = SymType + 1;

    /* rotation */
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sRSSAttr.Rotate = (SHORT)Number;

    /* pixels per X */
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sRSSAttr.pixMult = (SHORT)Number;

    /* separator row height */
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    sRSSAttr.sepHt = (SHORT)Number;

    sRSSAttr.segWidth  = 22;
    sRSSAttr.linHeight = 25;

    /* segment width of RSS expanded */
    if (SymType == 5)
    {
        if (!GetExpNumber(COMMA_END, &Number))
            return _ERROR;
        sRSSAttr.segWidth = (SHORT)Number;
    }

    /* height of UCC/EAN-128 in X */
    if (SymType == 10 || SymType == 11)
    {
        if (!GetExpNumber(COMMA_END, &Number))
            return _ERROR;
        sRSSAttr.linHeight = (SHORT)Number;
    }

    if (GetExpParam(LINE_END, &sParam, LongData, sizeof(LongData)) != EXP_PARAM_STRING)
        return _ERROR;

    if (sParam.Counter)
    {
        if (strlen(LongData) >= EXPRESS_LEN)
            return _ERROR;
        if ((LinkNum = SearchFreeCntTbl()) == COUNTER_TABLE_MAX)
            return _ERROR;
        sCntLinkTbl[LinkNum].CountType = RSS_COUNT;
        sCntLinkTbl[LinkNum].Data.sRSSAttr = sRSSAttr;
        strcpy((CHAR *)sCntLinkTbl[LinkNum].ExpData, LongData);
        memset((CHAR *)&sCntLinkTbl[LinkNum].sEraseBox, 0, sizeof(_EraseBox));
        return _SUCCESS;
     }

    if (strlen(sParam.String) >= sizeof(LongData))
        return _ERROR;
    strcpy(LongData, sParam.String);

    sRSSAttr.ExpLen = strlen(LongData);
    sRSSAttr.pExp = (BYTE *)LongData;
    sRSSAttr.psImageBuffer = &sImageBuffer;

    ReloadWaitTime();
    if (!RSS(&sRSSAttr))
        return _ERROR;

    return _SUCCESS;
}

#endif

TsplFuncSet.c  、、、、、、、、、、、、、、、、、、、、、、、、、、、、

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

#define TSPLFUNCSET_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 <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 "XADC.h"
#include "XLED.h"
#include "XLCD.h"
#include "XKey.h"
#include "XGPIO.h"
#include "XPrtEng.h"
#include "XDisplay.h"
#include "XFunction.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "VarMgr.h"
#include "TsplUtil.h"
#include "TsplFunc.h"
#include "XVarBank.h"

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

#if defined(TSPL)

#define SET_TYPE_TOTAL             (sizeof(SetTypeTable) / sizeof(CHAR *))    
#define SET_FUNC_TOTAL             (sizeof(SetFuncTable) / sizeof(CHAR *))    

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

typedef enum
{
    SET_TYPE_ON,
    SET_TYPE_OFF,
    SET_TYPE_HIGH,
    SET_TYPE_LOW,
    SET_TYPE_POS,
    SET_TYPE_NEG,
    SET_TYPE_OBVERSE,
    SET_TYPE_REVERSE,
    SET_TYPE_INSIDE,
    SET_TYPE_OUTSIDE,
    SET_TYPE_AUTO,
    SET_TYPE_MANUAL,
    SET_TYPE_MEAS,
    SET_TYPE_BATCH,
    SET_TYPE_LABEL,
    SET_TYPE_RS232,
    SET_TYPE_TPU,
    SET_TYPE_CONTINUOUS,
}_eSetType;

typedef enum
{
    SET_FUNC_ON,
    SET_FUNC_OFF,
    SET_FUNC_DEFAULT,
    SET_FUNC_MENU,
    SET_FUNC_PAUSE,
    SET_FUNC_REPRINT,
    SET_FUNC_PRINT,
    SET_FUNC_FEED,
    SET_FUNC_BACKFEED,
    SET_FUNC_FORMFEED,
    SET_FUNC_CUT,
    SET_FUNC_INPUT,
    SET_FUNC_TAKELABEL,
    SET_FUNC_IDLE,
    SET_FUNC_FAULT,
    SET_FUNC_PAPER,
    SET_FUNC_RIBBON,
    SET_FUNC_CARRIAGE,
    SET_FUNC_CUTTER,
    SET_FUNC_MEMORY,
    SET_FUNC_OVERHEAT,
}_eSetFunc;

/******************************************************************************
 *                                                                            *
 *             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     *
 *                                                                            *
 ******************************************************************************/

_CmdEntry SetEntry[] =
{
    {"COM1",            FN_SET_COM1},
    {"LED1",            FN_SET_LED1},
    {"LED2",            FN_SET_LED2},
    {"LED3",            FN_SET_LED3},
    {"KEY1",            FN_SET_KEY1},
    {"KEY2",            FN_SET_KEY2},
    {"KEY3",            FN_SET_KEY3},
    {"KEY4",            FN_SET_KEY4},
    {"KEY5",            FN_SET_KEY5},
    {"KEY6",            FN_SET_KEY6},
    {"GPI1",            FN_SET_GPI1},
    {"GPI2",            FN_SET_GPI2},
    {"GPI3",            FN_SET_GPI3},
    {"GPI4",            FN_SET_GPI4},
    {"GPO1",            FN_SET_GPO1},
    {"GPO2",            FN_SET_GPO2},
    {"GPO3",            FN_SET_GPO3},
    {"GPO4",            FN_SET_GPO4},
    {"GPO5",            FN_SET_GPO5},
    {"GPO6",            FN_SET_GPO6},
    {"GPO7",            FN_SET_GPO7},
    {"CUTTER",            FN_SET_CUTTER},
    {"PARTIAL_CUTTER",    FN_SET_PARTIAL_CUTTER},
    {"BACK",            FN_SET_BACK},
    {"PEEL",            FN_SET_PEEL},
    {"TEAR",            FN_SET_TEAR},
    {"COUNTER",            FN_SET_COUNTER},
    {"DEBUG",            FN_SET_DEBUG},
    {"SENSOR_REF",        FN_SET_SENSOR_REF},
    {"INVALID_GAP",        FN_SET_INVALID_GAP},
    {"DISPLAY_REMAIN",    FN_SET_DISPLAY_REMAIN},
    {"GAP",                FN_SET_GAP},
    {"RIBBON_I",        FN_SET_RIBBON_I},
    {"CONTRAST",        FN_SET_CONTRAST},
    {"COMMAND",            FN_SET_COMMAND},
    {"RIBBON",            FN_SET_RIBBON},
    {"ENCODER",            FN_SET_ENCODER},
    {"HEAD",            FN_SET_HEAD},
    {"NOBACK",            FN_SET_NOBACK},
    {"STRIPER",            FN_SET_TEAR},
    {"MAXICODE",        FN_SET_MAXICODE},
    {"EXTFEED",            FN_SET_EXTFEED},
    {"FEED_TIME",        FN_SET_FEED_TIME},
    {"FEED_LEN",        FN_SET_FEED_LEN},
    {"REPRINT",            FN_SET_REPRINT},
    {"PRINTKEY",        FN_SET_PRINTKEY},
    {"REPRINTKEY",        FN_SET_REPRINTKEY},
    {"VERIFIER",        FN_SET_VERIFIER},
    {"AUTORUN",            FN_SET_AUTORUN},
    {"OVERHEAT",        FN_SET_OVERHEAT},
    {"MOTOR_OVERHEAT",    FN_SET_MOTOR_OVERHEAT},
    {"FILTER",            FN_SET_INPUTFILTER},

    // proprietary command
    {"INPUTFILTER",        FN_SET_INPUTFILTER},

#if defined(DURALABEL)
    {"RFID_COMMAND",    FN_SET_RF_COMMAND},
#endif
    {(CHAR *)_NULL,        _NULL}
};

STATIC CONST CHAR *SetTypeTable[] =
{
    "ON",
    "OFF",
    "HIGH",
    "LOW",
    "POS",
    "NEG",
    "OBVERSE",
    "REVERSE",
    "INSIDE",
    "OUTSIDE",
    "AUTO",
    "MANUAL",
    "MEAS",
    "BATCH",
    "LABEL",
    "RS232",
    "TPU",
    "CONTINUOUS",
};

STATIC CONST CHAR *SetFuncTable[] =
{
    "ON",
    "OFF",
    "DEFAULT",
    "MENU",
    "PAUSE",
    "REPRINT",
    "PRINT",
    "FEED",
    "BACKFEED",
    "FORMFEED",
    "CUT",
    "INPUT",
    "TAKELABEL",
    "IDLE",
    "FAULT",
    "PAPER",
    "RIBBON",
    "CARRIAGE",
    "CUTTER",
    "MEMORY",
    "OVERHEAT",
};

/******************************************************************************
 *                                                                            *
 *    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:
 *        GetKeySetting
 *
 * Syntax:
 *        func
 *        func arg
 *
 * Parameters:
 *        func - Function name
 *        arg  - Function argument (Print quantity)
 *
 ******************************************************************************/
STATIC BOOL GetKeySetting(_KeySetting *KeySetting)
{
    DOUBLE Number;
    CHAR Token[STRING_LEN];
    CHAR Data;
    INT Func;
    INT Argument = (-1);    // not specified

#ifdef DEBUG_PRNT
sysprintf("Enter GetKeySetting()...\n"); // ch_20211210    
#endif

    // Function name
    if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
        return FALSE;

    for (Func = 0; Func < SET_FUNC_TOTAL; Func++)
    {
        if (strcmp(Token, SetFuncTable[Func]) == 0)
            break;
    }
    if (Func == SET_FUNC_TOTAL)
        return FALSE;

    RemoveSpace();
    Data = NextByte();

    // Function Argument
    if (!CheckTokenEnd(LINE_END, Data))
    {
        if (Func == SET_FUNC_PRINT)
        {
            // Quantity
            if (!GetExpNumber(LINE_END, &Number))
                return FALSE;
            if ((INT)Number < 0 || (INT)Number > 32000)
                return FALSE;
            Argument = (INT)Number;
        }
        else if (Func == SET_FUNC_INPUT)
        {
            // Input string
            if (!GetExpString(LINE_END, Token, sizeof(FUNCARG)))
                return FALSE;
        }
        else
            return FALSE;
    }
    else if (Func == SET_FUNC_INPUT)
        return FALSE;

    switch (Func)
    {
        case SET_FUNC_OFF:
            KeySetting->FuncID = KEY_FUNC_OFF;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_ON:
        case SET_FUNC_DEFAULT:
#ifdef DEBUG_PRNT            
sysprintf("GetKeySetting() : case SET_FUNC_DEFAULT\n"); // ch_20211210            
#endif
            KeySetting->FuncID = KEY_FUNC_DEFAULT;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_MENU:
            KeySetting->FuncID = KEY_FUNC_MENU;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_PAUSE:
            KeySetting->FuncID = KEY_FUNC_PAUSE;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_FEED:
            KeySetting->FuncID = KEY_FUNC_FEED;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_BACKFEED:
            KeySetting->FuncID = KEY_FUNC_BACKFEED;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_FORMFEED:
            KeySetting->FuncID = KEY_FUNC_FORMFEED;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_PRINT:
            KeySetting->FuncID = KEY_FUNC_PRINT;
            KeySetting->Argument.Number = Argument;
            if (Argument == (-1))    // not specified
                KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_CUT:
            KeySetting->FuncID = KEY_FUNC_CUT;
            KeySetting->Argument.Number = 0;
            break;
        case SET_FUNC_INPUT:
            KeySetting->FuncID = KEY_FUNC_INPUT;
            strcpy(KeySetting->Argument.String, Token);
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

/******************************************************************************
 *
 * Function:
 *        GetGPInSetting
 *
 * Syntax:
 *        OFF
 *        signal,pulse,func
 *        signal,pulse,func arg
 *
 * Parameters:
 *        signal - Signal type
 *        pulse  - Filter pulse width (Ignored for level-type signals)
 *        func   - Function name
 *        arg    - Function argument
 *
 ******************************************************************************/
STATIC BOOL GetGPInSetting(_GPISetting *InSetting)
{
    DOUBLE Number;
    CHAR Token[STRING_LEN];
    CHAR Data;
    INT Signal, Pulse, Func;
    INT Argument = (-1);    // not specified

    // Signal type
    if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
        return FALSE;

    // HIGH = High level, LOW = Low level, POS = Positive pulse, NEG = Negative pulse
    for (Signal = 0; Signal < SET_TYPE_TOTAL; Signal++)
    {
        if (strcmp(Token, SetTypeTable[Signal]) == 0)
            break;
    }
    if (Signal == SET_TYPE_TOTAL)
        return FALSE;

    RemoveSpace();
    Data = NextByte();

    // Disable the GPIO input channel
    if (Signal == SET_TYPE_OFF)
    {
        if (!CheckTokenEnd(LINE_END, Data))
            return FALSE;
        memset(InSetting, 0, sizeof(_GPISetting));
        InSetting->Signal   = GPIO_SIGNAL_OFF;
        InSetting->Pulse    = 0;
        InSetting->FuncID   = GPI_FUNC_OFF;
        return TRUE;
    }
    else if (!CheckTokenEnd(COMMA_END, Data))
        return FALSE;

    // Pulse width
    if (!GetExpNumber(COMMA_END, &Number))
        return FALSE;
    if ((INT)Number < 0 || (INT)Number > 99999999)
        return FALSE;
    Pulse = (INT)Number;

    // Function name
    if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
        return FALSE;

    for (Func = 0; Func < SET_FUNC_TOTAL; Func++)
    {
        if (strcmp(Token, SetFuncTable[Func]) == 0)
            break;
    }
    if (Func == SET_FUNC_TOTAL)
        return FALSE;

    RemoveSpace();
    Data = NextByte();

    // Function Argument
    if (!CheckTokenEnd(LINE_END, Data))
    {
        if (Func == SET_FUNC_PRINT || Func == SET_FUNC_FEED || Func == SET_FUNC_BACKFEED)
        {
            // Quantity
            if (!GetExpNumber(LINE_END, &Number))
                return FALSE;
            if ((INT)Number < 0 || (INT)Number > 32000)
                return FALSE;
            Argument = (INT)Number;
        }
        else if (Func == SET_FUNC_PAUSE || Func == SET_FUNC_REPRINT)
        {
            // ON OFF type
            if (!GetExpToken(LINE_END, Token, sizeof(Token)))
                return FALSE;

            for (Argument = 0; Argument < SET_TYPE_TOTAL; Argument++)
            {
                if (strcmp(Token, SetTypeTable[Argument]) == 0)
                    break;
            }
            if (Argument != SET_TYPE_ON && Argument != SET_TYPE_OFF)
                return FALSE;
        }
        else if (Func == SET_FUNC_INPUT)
        {
            // Input string
            if (!GetExpString(LINE_END, Token, sizeof(FUNCARG)))
                return FALSE;
        }
        else
            return FALSE;
    }

    switch (Signal)
    {
        case SET_TYPE_HIGH:
            InSetting->Signal = GPIO_SIGNAL_HIGH;
            InSetting->Pulse  = 0;    // Ignored for level-type signals
            break;
        case SET_TYPE_LOW:
            InSetting->Signal = GPIO_SIGNAL_LOW;
            InSetting->Pulse  = 0;    // Ignored for level-type signals
            break;
        case SET_TYPE_POS:
            InSetting->Signal = GPIO_SIGNAL_POS;
            InSetting->Pulse  = Pulse;
            break;
        case SET_TYPE_NEG:
            InSetting->Signal = GPIO_SIGNAL_NEG;
            InSetting->Pulse  = Pulse;
            break;
        default:
            return FALSE;
    }

    switch (Func)
    {
        case SET_FUNC_PAUSE:
            InSetting->FuncID = GPI_FUNC_PAUSE;
            InSetting->Argument.Number = 0;
            if (Argument == SET_TYPE_ON)
                InSetting->FuncID = GPI_FUNC_PAUSE_ON;
            if (Argument == SET_TYPE_OFF)
                InSetting->FuncID = GPI_FUNC_PAUSE_OFF;
            break;
        case SET_FUNC_REPRINT:
            InSetting->FuncID = GPI_FUNC_REPRINT;
            InSetting->Argument.Number = 1;
            if (Argument == SET_TYPE_ON)
                InSetting->FuncID = GPI_FUNC_REPRINT_ON;
            if (Argument == SET_TYPE_OFF)
                InSetting->FuncID = GPI_FUNC_REPRINT_OFF;
            break;
        case SET_FUNC_PRINT:
            InSetting->FuncID = GPI_FUNC_PRINT;
            InSetting->Argument.Number = Argument;
            if (Argument == (-1))
                InSetting->Argument.Number = 0;
            break;
        case SET_FUNC_FEED:
            InSetting->FuncID = GPI_FUNC_FEED;
            InSetting->Argument.Number = Argument;
            if (Argument == (-1))    // must be specified
                return FALSE;
            break;
        case SET_FUNC_BACKFEED:
            InSetting->FuncID = GPI_FUNC_BACKFEED;
            InSetting->Argument.Number = Argument;
            if (Argument == (-1))    // must be specified
                return FALSE;
            break;
        case SET_FUNC_FORMFEED:
            InSetting->FuncID = GPI_FUNC_FORMFEED;
            InSetting->Argument.Number = 0;
            break;
        case SET_FUNC_CUT:
            InSetting->FuncID = GPI_FUNC_CUT;
            InSetting->Argument.Number = 0;
            break;
        case SET_FUNC_INPUT:
            InSetting->FuncID = GPI_FUNC_INPUT;
            strcpy(InSetting->Argument.String, Token);
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

/******************************************************************************
 *
 * Function:
 *        GetGPOutSetting
 *
 * Syntax:
 *        OFF
 *        signal,delay0,pulse0,delay1,pulse1,func
 *        signal,delay0,pulse0,delay1,pulse1,func arg
 *
 * Parameters:
 *        signal - Signal type
 *        delay0 - Delay time when condition "true"
 *        pulse0 - Pulse width when condition "true" (Ignored for level-type signals)
 *        delay1 - Delay time when condition "false"
 *        pulse1 - Pulse width when condition "false" (Ignored for level-type signals)
 *        func   - Function name
 *        arg    - Function argument
 *
 ******************************************************************************/
STATIC BOOL GetGPOutSetting(_GPOSetting *OutSetting)
{
    DOUBLE Number;
    CHAR Token[STRING_LEN];
    CHAR Data;
    INT Signal, Delay0, Pulse0, Delay1, Pulse1, Func;

    // Signal type
    if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
        return FALSE;

    // HIGH = High level, LOW = Low level, POS = Positive pulse, NEG = Negative pulse
    for (Signal = 0; Signal < SET_TYPE_TOTAL; Signal++)
    {
        if (strcmp(Token, SetTypeTable[Signal]) == 0)
            break;
    }
    if (Signal == SET_TYPE_TOTAL)
        return FALSE;

    RemoveSpace();
    Data = NextByte();

    // Disable the GPIO Output channel
    if (Signal == SET_TYPE_OFF)
    {
        if (!CheckTokenEnd(LINE_END, Data))
            return FALSE;
        OutSetting->Signal     = GPIO_SIGNAL_OFF;
        OutSetting->TrueDelay  = 0;
        OutSetting->TruePulse  = 0;
        OutSetting->FalseDelay = 0;
        OutSetting->FalsePulse = 0;
        OutSetting->FuncID     = GPO_FUNC_OFF;
        return TRUE;
    }
    else if (!CheckTokenEnd(COMMA_END, Data))
        return FALSE;

    // Delay time when condition "true"
    if (!GetExpNumber(COMMA_END, &Number))
        return FALSE;
    if ((INT)Number < 0 || (INT)Number > 99999999)
        return FALSE;
    Delay0 = (INT)Number;

    // Pulse Width when condition "true"
    if (!GetExpNumber(COMMA_END, &Number))
        return FALSE;
    if ((INT)Number < 0 || (INT)Number > 99999999)
        return FALSE;
    Pulse0 = (INT)Number;

    // Delay time when condition "false"
    if (!GetExpNumber(COMMA_END, &Number))
        return FALSE;
    if ((INT)Number < 0 || (INT)Number > 99999999)
        return FALSE;
    Delay1 = (INT)Number;

    // Pulse Width when condition "false"
    if (!GetExpNumber(COMMA_END, &Number))
        return FALSE;
    if ((INT)Number < 0 || (INT)Number > 99999999)
        return FALSE;
    Pulse1 = (INT)Number;

    // Function name
    if (!GetExpToken(BACK_WITH_SPACE, Token, sizeof(Token)))
        return FALSE;

    for (Func = 0; Func < SET_FUNC_TOTAL; Func++)
    {
        if (strcmp(Token, SetFuncTable[Func]) == 0)
            break;
    }
    if (Func == SET_FUNC_TOTAL)
        return FALSE;

    RemoveSpace();
    Data = NextByte();

    // Function Argument
    if (!CheckTokenEnd(LINE_END, Data))
    {
        if (Func == SET_FUNC_FAULT)
        {
            // Fault Function
            if (!GetExpToken(LINE_END, Token, sizeof(Token)))
                return FALSE;

            for (Func = 0; Func < SET_FUNC_TOTAL; Func++)
            {
                if (strcmp(Token, SetFuncTable[Func]) == 0)
                    break;
            }
            if (Func == SET_FUNC_TOTAL)
                return FALSE;
        }
        else
            return FALSE;
    }

    switch (Signal)
    {
        case SET_TYPE_HIGH:
            OutSetting->Signal     = GPIO_SIGNAL_HIGH;
            OutSetting->TrueDelay  = Delay0;
            OutSetting->TruePulse  = 0;    // Ignored for level-type signals
            OutSetting->FalseDelay = Delay1;
            OutSetting->FalsePulse = 0;    // Ignored for level-type signals
            break;
        case SET_TYPE_LOW:
            OutSetting->Signal     = GPIO_SIGNAL_LOW;
            OutSetting->TrueDelay  = Delay0;
            OutSetting->TruePulse  = 0;    // Ignored for level-type signals
            OutSetting->FalseDelay = Delay1;
            OutSetting->FalsePulse = 0;    // Ignored for level-type signals
            break;
        case SET_TYPE_POS:
            OutSetting->Signal     = GPIO_SIGNAL_POS;
            OutSetting->TrueDelay  = Delay0;
            OutSetting->TruePulse  = Pulse0;
            OutSetting->FalseDelay = Delay1;
            OutSetting->FalsePulse = Pulse1;
            break;
        case SET_TYPE_NEG:
            OutSetting->Signal     = GPIO_SIGNAL_NEG;
            OutSetting->TrueDelay  = Delay0;
            OutSetting->TruePulse  = Pulse0;
            OutSetting->FalseDelay = Delay1;
            OutSetting->FalsePulse = Pulse1;
            break;
        default:
            return FALSE;
    }

    switch (Func)
    {
        case SET_FUNC_PAUSE:
            OutSetting->FuncID = GPO_FUNC_PAUSE;
            break;
        case SET_FUNC_REPRINT:
            OutSetting->FuncID = GPO_FUNC_REPRINT;
            break;
        case SET_FUNC_TAKELABEL:
            OutSetting->FuncID = GPO_FUNC_TAKELABEL;
            break;
        case SET_FUNC_IDLE:
            OutSetting->FuncID = GPO_FUNC_IDLE;
            break;
        case SET_FUNC_FAULT:
            OutSetting->FuncID = GPO_FUNC_FAULT;
            break;
        case SET_FUNC_PAPER:
            OutSetting->FuncID = GPO_FUNC_FAULT_PAPER;
            break;
        case SET_FUNC_RIBBON:
            OutSetting->FuncID = GPO_FUNC_FAULT_RIBBON;
            break;
        case SET_FUNC_CARRIAGE:
            OutSetting->FuncID = GPO_FUNC_FAULT_CARRIAGE;
            break;
        case SET_FUNC_CUTTER:
            OutSetting->FuncID = GPO_FUNC_FAULT_CUTTER;
            break;
        case SET_FUNC_MEMORY:
            OutSetting->FuncID = GPO_FUNC_FAULT_MEMORY;
            break;
        case SET_FUNC_OVERHEAT:
            OutSetting->FuncID = GPO_FUNC_FAULT_OVERHEAT;
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

INT FN_SET_COM1(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    LONG   BaudRate;
    SHORT  Data;
    CHAR   Parity;
    SHORT  Stop;
    
    // get baudrate
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    BaudRate = (LONG)Number;

    if (BaudRate == 12)
        BaudRate = 1200;
    else if (BaudRate == 24)
        BaudRate = 2400;
    else if (BaudRate == 48)
        BaudRate = 4800;
    else if (BaudRate == 96)
        BaudRate = 9600;
    else if (BaudRate == 19)
        BaudRate = 19200;
    else if (BaudRate == 38)
        BaudRate = 38400;
    else if (BaudRate == 56 || BaudRate == 57)
        BaudRate = 57600;
    else if (BaudRate == 115)
        BaudRate = 115200;
    else
        return _ERROR;

    // get parity
    if (!GetExpToken(COMMA_END, Token, sizeof(Token)))
        return _ERROR;
    Parity = *Token;

    if (!CheckChar(Parity,"NOE"))
        return _ERROR;

    // get data bit
    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    Data = (SHORT)Number;

    if (Data < 7 || Data > 8)
        return _ERROR;

    // get stop bit
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    Stop = (SHORT)Number;

    if (Stop < 1 || Stop > 2)
        return _ERROR;

    SetSerialPort(BaudRate, Data, Parity, Stop);
    return _SUCCESS;
}

INT FN_SET_LED1(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->LedSelect &= ~LED1_FLAG;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->LedSelect |= LED1_FLAG;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_LED2(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->LedSelect &= ~LED2_FLAG;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->LedSelect |= LED2_FLAG;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_LED3(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->LedSelect &= ~LED3_FLAG;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->LedSelect |= LED3_FLAG;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_KEY1(VOID)
{
    _KeySetting KeySetting;

#ifdef DEBUG_PRNT    
sysprintf("Enter FN_SET_KEY1()...\n"); // ch_20211210    
#endif

    if (!GetKeySetting(&KeySetting))
        return _ERROR;

#if defined(SOFT_KEY1)
    GetKey(SOFT_KEY1);    // clear key press flag
    pPrintCfg->KeySetting[SOFT_KEY1] = KeySetting;
    KeyFuncSetting(SOFT_KEY1, &pPrintCfg->KeySetting[SOFT_KEY1]);
#endif

    return _SUCCESS;
}

INT FN_SET_KEY2(VOID)
{
    _KeySetting KeySetting;

    if (!GetKeySetting(&KeySetting))
        return _ERROR;

#if defined(SOFT_KEY2)
    GetKey(SOFT_KEY2);    // clear key press flag
    pPrintCfg->KeySetting[SOFT_KEY2] = KeySetting;
    KeyFuncSetting(SOFT_KEY2, &pPrintCfg->KeySetting[SOFT_KEY2]);
#endif

    return _SUCCESS;
}

INT FN_SET_KEY3(VOID)
{
    _KeySetting KeySetting;

    if (!GetKeySetting(&KeySetting))
        return _ERROR;

#if defined(SOFT_KEY3)
    GetKey(SOFT_KEY3);    // clear key press flag
    pPrintCfg->KeySetting[SOFT_KEY3] = KeySetting;
    KeyFuncSetting(SOFT_KEY3, &pPrintCfg->KeySetting[SOFT_KEY3]);
#endif

    return _SUCCESS;
}

INT FN_SET_KEY4(VOID)
{
    _KeySetting KeySetting;

    if (!GetKeySetting(&KeySetting))
        return _ERROR;

#if defined(SOFT_KEY4)
    GetKey(SOFT_KEY4);    // clear key press flag
    pPrintCfg->KeySetting[SOFT_KEY4] = KeySetting;
    KeyFuncSetting(SOFT_KEY4, &pPrintCfg->KeySetting[SOFT_KEY4]);
#endif

    return _SUCCESS;
}

INT FN_SET_KEY5(VOID)
{
    _KeySetting KeySetting;

    if (!GetKeySetting(&KeySetting))
        return _ERROR;

#if defined(SOFT_KEY5)
    GetKey(SOFT_KEY5);    // clear key press flag
    pPrintCfg->KeySetting[SOFT_KEY5] = KeySetting;
    KeyFuncSetting(SOFT_KEY5, &pPrintCfg->KeySetting[SOFT_KEY5]);
#endif

    return _SUCCESS;
}

INT FN_SET_KEY6(VOID)
{
    _KeySetting KeySetting;

    if (!GetKeySetting(&KeySetting))
        return _ERROR;

#if defined(SOFT_KEY6)
    GetKey(SOFT_KEY6);    // clear key press flag
    pPrintCfg->KeySetting[SOFT_KEY6] = KeySetting;
    KeyFuncSetting(SOFT_KEY6, &pPrintCfg->KeySetting[SOFT_KEY6]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPI1(VOID)
{
    _GPISetting InSetting;

    if (!GetGPInSetting(&InSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPInSetting[GPI_CH1] = InSetting;
    GPInFuncSetting(GPI_CH1, &pPrintCfg->GPInSetting[GPI_CH1]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPI2(VOID)
{
    _GPISetting InSetting;

    if (!GetGPInSetting(&InSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPInSetting[GPI_CH2] = InSetting;
    GPInFuncSetting(GPI_CH2, &pPrintCfg->GPInSetting[GPI_CH2]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPI3(VOID)
{
    _GPISetting InSetting;

    if (!GetGPInSetting(&InSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPInSetting[GPI_CH3] = InSetting;
    GPInFuncSetting(GPI_CH3, &pPrintCfg->GPInSetting[GPI_CH3]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPI4(VOID)
{
    _GPISetting InSetting;

    if (!GetGPInSetting(&InSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPInSetting[GPI_CH4] = InSetting;
    GPInFuncSetting(GPI_CH4, &pPrintCfg->GPInSetting[GPI_CH4]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO1(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH1] = OutSetting;
    GPOutFuncSetting(GPO_CH1, &pPrintCfg->GPOutSetting[GPO_CH1]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO2(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH2] = OutSetting;
    GPOutFuncSetting(GPO_CH2, &pPrintCfg->GPOutSetting[GPO_CH2]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO3(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH3] = OutSetting;
    GPOutFuncSetting(GPO_CH3, &pPrintCfg->GPOutSetting[GPO_CH3]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO4(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH4] = OutSetting;
    GPOutFuncSetting(GPO_CH4, &pPrintCfg->GPOutSetting[GPO_CH4]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO5(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH5] = OutSetting;
    GPOutFuncSetting(GPO_CH5, &pPrintCfg->GPOutSetting[GPO_CH5]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO6(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH6] = OutSetting;
    GPOutFuncSetting(GPO_CH6, &pPrintCfg->GPOutSetting[GPO_CH6]);
#endif

    return _SUCCESS;
}

INT FN_SET_GPO7(VOID)
{
    _GPOSetting OutSetting;

    if (!GetGPOutSetting(&OutSetting))
        return _ERROR;

#if defined(GPIO_MODEL)
    pPrintCfg->GPOutSetting[GPO_CH7] = OutSetting;
    GPOutFuncSetting(GPO_CH7, &pPrintCfg->GPOutSetting[GPO_CH7]);
#endif

    return _SUCCESS;
}

INT FN_SET_CUTTER(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    CHAR   Data;
    INT    Type;

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

        if(ProfileLimit("NO CUTTER MODE")==1)
            return _ERROR;
            
    // check cutter type
    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (Data == *SetTypeTable[Type])
            break;
    }
    // not a string
    if (Type == SET_TYPE_TOTAL)
    {
        if (!GetExpNumber(LINE_END, &Number))
            return _ERROR;

        if ((INT)Number == 0)    /* SET CUTTER 0 when it disables the cutter */
        {
            pPrintCfg->CutterBack = TRUE;
            if (pPrintCfg->PrintOutMode == CUTTER_MODE)
            {
                pPrintCfg->PrintOutMode = OFF_MODE;
                if (pPrintCfg->TearMode)
                    pPrintCfg->PrintOutMode = TEAR_MODE;
            }
        }
        else
        {
            pPrintCfg->CutterBack = TRUE;
            pPrintCfg->CutterPieces = (INT)Number;
            pPrintCfg->PrintOutMode = CUTTER_MODE;
        }
        return _SUCCESS;
    }
    // a string
    else if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->CutterBack   = TRUE;
            pPrintCfg->CutterPieces = 1;
            pPrintCfg->PrintOutMode = CUTTER_MODE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->CutterBack = TRUE;
            if (pPrintCfg->PrintOutMode == CUTTER_MODE)
            {
                pPrintCfg->PrintOutMode = OFF_MODE;
                pPrintCfg->CutterTPU = FALSE;
                if (pPrintCfg->TearMode)
                    pPrintCfg->PrintOutMode = TEAR_MODE;
            }
            break;
        case SET_TYPE_BATCH:
            pPrintCfg->CutterBack   = TRUE;
            pPrintCfg->CutterPieces = 0;
            pPrintCfg->PrintOutMode = CUTTER_MODE;
            break;
            
        case SET_TYPE_TPU:

            if (pPrintCfg->PrintOutMode == CUTTER_MODE)
            {
                pPrintCfg->CutterTPU = TRUE;
                pPrintCfg->CutterContinuous = FALSE;
            }
            break;
        case SET_TYPE_CONTINUOUS:
            if (pPrintCfg->PrintOutMode == CUTTER_MODE)
            {
                pPrintCfg->CutterContinuous = TRUE;
                pPrintCfg->CutterTPU = FALSE;
                SendPrintf("Continuous Open\r\n");
            }
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_PARTIAL_CUTTER(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    CHAR   Data;
    INT    Type;

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

        if(ProfileLimit("NO PARTIAL CUTTER MODE")==1)
            return _ERROR;
    // check cutter type
    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (Data == *SetTypeTable[Type])
            break;
    }
    // not a string
    if (Type == SET_TYPE_TOTAL)
    {
        if (!GetExpNumber(LINE_END, &Number))
            return _ERROR;

        pPrintCfg->CutterBack   = FALSE;
        pPrintCfg->CutterPieces = (INT)Number;
        pPrintCfg->PrintOutMode = CUTTER_MODE;
        return _SUCCESS;
    }
    // a string
    else if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0 ; Type < SET_TYPE_TOTAL ; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->CutterBack   = FALSE;
            pPrintCfg->CutterPieces = 1;
            pPrintCfg->PrintOutMode = CUTTER_MODE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->CutterBack = TRUE;
            if (pPrintCfg->PrintOutMode == CUTTER_MODE)
            {
                if (pPrintCfg->TearMode)
                    pPrintCfg->PrintOutMode = TEAR_MODE;
                else
                    pPrintCfg->PrintOutMode = OFF_MODE;
            }
            break;
        case SET_TYPE_BATCH:
            pPrintCfg->CutterBack   = FALSE;
            pPrintCfg->CutterPieces = 0;
            pPrintCfg->PrintOutMode = CUTTER_MODE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_BACK(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->CutterBack = TRUE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->CutterBack = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_PEEL(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if(ProfileLimit("NO PEEL MODE")==1)
            return _ERROR;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->PrintOutMode = TEAR_MODE; //PEEL_MODE; // ch_20220108 : even if Enable PEEL_MODE, still work at TEAR_MODE because 168 no PEEL_MODE.
            break;
        case SET_TYPE_OFF:
            if (pPrintCfg->PrintOutMode == PEEL_MODE)
            {
                if (pPrintCfg->TearMode)
                    pPrintCfg->PrintOutMode = TEAR_MODE;
                else
                    pPrintCfg->PrintOutMode = OFF_MODE;
            }
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_TEAR(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->TearMode = TRUE;
            pPrintCfg->PrintOutMode = TEAR_MODE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->TearMode = FALSE;
            pPrintCfg->PrintOutMode = OFF_MODE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_COUNTER(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    INT    IDNum;

    if (!GetExpToken(SPACE_END, Token, sizeof(Token)))
        return _ERROR;
    if (*Token != '@')
        return _ERROR;
    IDNum = atoi(Token + 1);

    RemoveSpace();
    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;

    SetCounterStep(IDNum, (INT)Number);
    return _SUCCESS;
}

INT FN_SET_DEBUG(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_LABEL:
            pPrintCfg->DebugMode = DEBUG_LABEL;
            break;
        case SET_TYPE_RS232:
            pPrintCfg->DebugMode = DEBUG_RS232;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_SENSOR_REF(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_AUTO:
            pPrintCfg->AutoSensorRef = TRUE;
            break;
        case SET_TYPE_MANUAL:
            pPrintCfg->AutoSensorRef = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_INVALID_GAP(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    CHAR   Data;
    INT    Type;

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

    // check cutter type
    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (Data == *SetTypeTable[Type])
            break;
    }
    // not a string
    if (Type == SET_TYPE_TOTAL)
    {
        if (!GetExpSize(LINE_END, &Number))
            return _ERROR;

        pPrintCfg->IgnoreSize = (WORD)Number;
        return _SUCCESS;
    }
    // a string
    else if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->IgnoreSize = (5 * MM_DOT);
            break;
        case SET_TYPE_OFF:
            pPrintCfg->IgnoreSize = 0;
            break;
        default:
            return _ERROR;
    }    

    return _SUCCESS;
}

INT FN_SET_DISPLAY_REMAIN(VOID)
{
    DOUBLE Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;

#if defined(LCD_MODEL)
    SetDspRemainRate(Number);
#endif

    return _SUCCESS;
}

INT FN_SET_GAP(VOID)
{
    CHAR Token[STRING_LEN];
    CHAR Data;
    BYTE Intension;
    WORD Reference;
    DOUBLE Number;
    INT    Type;
    INT    state = _ERROR;

#ifdef DEBUG_PRNT
sysprintf("Enter FN_SET_GAP()...\n"); // ch_20211208
#endif

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

    // check type
    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (Data == *SetTypeTable[Type])
            break;
    }

    // not a string
    if (Type == SET_TYPE_TOTAL)
    {
        if (GetExpNumber(BACK_WITHOUT_SPACE, &Number))
        {
            Intension = (BYTE)Number;

            Data  = NextByte();
            if (CheckChar(Data, ",;"))
            {
                if (GetExpNumber(LINE_END, &Number))
                {
                    Reference = (WORD)Number;
                    if (Reference < AD_SCALE)
                    {
                        if (pPrintCfg->SensorMode == GAP_MODE)
                            pPrintCfg->GapRef = Reference;
                        else if (pPrintCfg->SensorMode == BLINE_MODE)
                            pPrintCfg->BlineRef = Reference;
                        else
                            pPrintCfg->ContinuousRef = Reference;
                    }
                    state = _SUCCESS;
                }
            }
            else if (CheckTokenEnd(LINE_END, Data))
                state = _SUCCESS;

            if (state == _SUCCESS)
            {
                if (pPrintCfg->SensorMode == GAP_MODE)
                {
                    if (Intension < GAP_SENSOR_SCALE)
                        pPrintCfg->GapInten = Intension;
                }
                else if (pPrintCfg->SensorMode == BLINE_MODE)
                {
                    if (Intension < BLINE_SENSOR_SCALE)
                        pPrintCfg->BlineInten = Intension;
                }
                else if (pPrintCfg->SensorMode == CONTINUE_MODE_R)
                {
                    if (Intension < BLINE_SENSOR_SCALE)
                        pPrintCfg->ContinuousInten = Intension;
                }
                else
                {
                    if (Intension < GAP_SENSOR_SCALE)
                        pPrintCfg->ContinuousInten = Intension;
                }
                InitialCalibration();
            }
        }
    }

    // a string
    else if (GetExpToken(LINE_END, Token, sizeof(Token)))
    {
        for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
        {
            if (strcmp(Token, SetTypeTable[Type]) == 0)
                break;
        }
        switch (Type)
        {
            case SET_TYPE_MEAS:
                pPrintCfg->Measure = TRUE;
                state = _SUCCESS;
                break;
            case SET_TYPE_OFF:
                pPrintCfg->Measure = FALSE;
                state = _SUCCESS;
                break;
            case SET_TYPE_OBVERSE:
                pPrintCfg->GapReverse = FALSE;
                SetGapSensorReverse(FALSE);
                state = _SUCCESS;
                break;
            case SET_TYPE_REVERSE:
                pPrintCfg->GapReverse = TRUE;
                SetGapSensorReverse(TRUE);
                state = _SUCCESS;
                break;
            default:
                break;
        }
    }

#if defined(DIVIDE_INTENSION )
    if (state == _ERROR)
        DetectSensorInten(pPrintCfg, TRUE, FALSE, 0, 0);
#endif

    return state;
}

INT FN_SET_RIBBON_I(VOID)
{
    DOUBLE Number;
    CHAR   Data;
    BYTE   Intension;
    WORD   Reference;
    INT    state = _ERROR;

    if (GetExpNumber(BACK_WITHOUT_SPACE, &Number))
    {
        Intension = (BYTE)Number;

        Data  = NextByte();
        if (CheckChar(Data, ",;"))
        {
            if (GetExpNumber(LINE_END, &Number))
            {
                Reference = (WORD)Number;
                if (Reference < AD_SCALE)
                    pPrintCfg->RibbonRef = Reference;
                state = _SUCCESS;
            }
        }
        else if (CheckTokenEnd(LINE_END, Data))
            state = _SUCCESS;

        if (state == _SUCCESS)
        {
            if (Intension < RIBBON_SENSOR_SCALE)
                pPrintCfg->RibbonInten = Intension;
        }
    }
      return state;
}

INT FN_SET_CONTRAST(VOID)
{
    DOUBLE Number;
    INT    Level;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;

    Level = (INT)Number;
    if (Level < 6)
        Level = 6;
    if (Level > 20)
        Level = 20;

    SetFactorySetting(FACTORY_DISPLAY_CONTRAST, & Level, sizeof(Level));

#if defined(LCD_MODEL)
    LcdSetContrast(Level);
#endif

      return _SUCCESS;
}

INT FN_SET_COMMAND(VOID)
{
      RemoveLine();
      return _SUCCESS;
}

INT FN_SET_RIBBON(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
#if defined(RIBBON_MODEL)
            if (pPrintCfg->RibbonFlag == FALSE)
            {
                WaitWorkJobEnd();
                CheckRibbonExists(FALSE, FALSE);
            }
            StopTryRibbonEncoder();
            pPrintCfg->RibbonFlag = TRUE;
#endif
            break;
        case SET_TYPE_OFF:
            pPrintCfg->RibbonFlag = FALSE;
            break;
        case SET_TYPE_INSIDE:
            pPrintCfg->RibbonInside = TRUE;
            break;
        case SET_TYPE_OUTSIDE:
            pPrintCfg->RibbonInside = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_ENCODER(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->RibbonEncoder = TRUE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->RibbonEncoder = FALSE;
            break;
        default:
            return _ERROR;            
    }
    return _SUCCESS;
}

INT FN_SET_HEAD(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->CarriageOpen = TRUE;
#if defined(CARRIAGE_OPEN_MODEL)
            StartCheckCarriageOpen();
#endif
            break;
        case SET_TYPE_OFF:
            pPrintCfg->CarriageOpen = FALSE;
#if defined(CARRIAGE_OPEN_MODEL)
            StopCheckCarriageOpen();
#endif
            break;
        default:
            return _ERROR;            
    }
    return _SUCCESS;
}

INT FN_SET_NOBACK(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            break;
        case SET_TYPE_OFF:
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_MAXICODE(VOID)
{
    DOUBLE Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    if (Number < 1 || Number > 6)
        return _ERROR;
    MaxiCodeMode = Number;
    return _SUCCESS;
}

INT FN_SET_EXTFEED(VOID)
{
      RemoveLine();
      return _SUCCESS;
}

INT FN_SET_FEED_TIME(VOID)
{
    DOUBLE Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;

    if (Number >= 0 && Number <= 15)
        pPrintCfg->WaitJobTime = (WORD)(Number * 1000);    // unit 1 ms

      return _SUCCESS;
}

INT FN_SET_FEED_LEN(VOID)
{
    DOUBLE Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;

    if (Number >= 0 && Number <= (TPH_DPI * 20))
        pPrintCfg->FeedLength = (WORD)Number;    // unit 1 dot

      return _SUCCESS;
}

INT FN_SET_REPRINT(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->Reprint = TRUE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->Reprint = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_PRINTKEY(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    CHAR   Data;
    INT    Type;

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

    // check type
    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (Data == *SetTypeTable[Type])
            break;
    }
    // not a string
    if (Type == SET_TYPE_TOTAL)
    {
        if (!GetExpNumber(LINE_END, &Number))
            return _ERROR;

        pPrintCfg->PrintKeyCnt = (INT)Number;
        pPrintCfg->PrintKey = TRUE;
        return _SUCCESS;
    }
    // a string
    else if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->PrintKeyCnt = 1;
            pPrintCfg->PrintKey = TRUE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->PrintKeyCnt = 0;
            pPrintCfg->PrintKey = FALSE;
            break;
        case SET_TYPE_AUTO:
            pPrintCfg->PrintKeyCnt = 0;
            pPrintCfg->PrintKey = TRUE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_REPRINTKEY(VOID)
{
    DOUBLE Number;
    CHAR   Token[STRING_LEN];
    CHAR   Data;
    INT    Type;

    RemoveSpace();
    Data = NextByte();
    BackByte(Data);

    // check type
    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (Data == *SetTypeTable[Type])
            break;
    }
    // not a string
    if (Type == SET_TYPE_TOTAL)
    {
        if (!GetExpNumber(LINE_END, &Number))
            return _ERROR;

        pPrintCfg->ReprintKeyCnt = (INT)Number;
        pPrintCfg->ReprintKey = TRUE;
        return _SUCCESS;
    }
    // a string
    else if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->ReprintKeyCnt = 0;
            pPrintCfg->ReprintKey = TRUE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->ReprintKeyCnt = 0;
            pPrintCfg->ReprintKey = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_VERIFIER(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;

    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            pPrintCfg->Verifier = TRUE;
            break;
        case SET_TYPE_OFF:
            pPrintCfg->Verifier = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

INT FN_SET_AUTORUN(VOID)
{
    CHAR FileName[FILENAME_LENGTH];

    if (!GetExpString(LINE_END, FileName, sizeof(FileName)))
        return _ERROR;

    // Check Basic File
    if (strcmp(strchr(FileName, '.'), ".BAS") != 0)
        return _ERROR;

    strcpy((CHAR *)pPrintCfg->AutoRun, FileName);
    return _SUCCESS;
}

INT FN_SET_OVERHEAT(VOID)
{
    DOUBLE Number;
    INT OverHeat, PrintHeat;

    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    OverHeat = (INT)Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    PrintHeat = (INT)Number;

    if (OverHeat >= 5 && OverHeat <= 100)
        pPrintCfg->OverHeat = OverHeat;

    if (PrintHeat >= 5 && PrintHeat <= 100)
        pPrintCfg->PrintHeat = PrintHeat;

    return _SUCCESS;
}

INT FN_SET_MOTOR_OVERHEAT(VOID)
{
    DOUBLE Number;
    INT MotorOverHeat, MotorMoveHeat;

    if (!GetExpNumber(COMMA_END, &Number))
        return _ERROR;
    MotorOverHeat = (INT)Number;

    if (!GetExpNumber(LINE_END, &Number))
        return _ERROR;
    MotorMoveHeat = (INT)Number;

    if (MotorOverHeat > 20 && MotorOverHeat <= 100)
        pPrintCfg->MotorOverHeat = MotorOverHeat;

    if (MotorMoveHeat > 20 && MotorMoveHeat <= 100)
        pPrintCfg->MotorMoveHeat = MotorMoveHeat;

    return _SUCCESS;
}

INT FN_SET_INPUTFILTER(VOID)
{
    CHAR Token[STRING_LEN];
    INT  Type;
    
    if (!GetExpToken(LINE_END, Token, sizeof(Token)))
        return _ERROR;

    for (Type = 0; Type < SET_TYPE_TOTAL; Type++)
    {
        if (strcmp(Token, SetTypeTable[Type]) == 0)
            break;
    }
    switch (Type)
    {
        case SET_TYPE_ON:
            InputFilter = TRUE;
            break;
        case SET_TYPE_OFF:
            InputFilter = FALSE;
            break;
        default:
            return _ERROR;
    }
    return _SUCCESS;
}

#endif





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值