homework-jianmu/tests/tsim/src/simParse.c

1053 lines
28 KiB
C

/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Thi file is to parse the simScriptPos, function file and default file,
*
* syntax
*
* expression is format like:
* $var [=|<|>|==] var
* or:
* $var = var [+|-|*|/|.] var
*
* if expression
* command
*
* if expression then
* commands
* elif expression
* commands
* elif expression
* commands
* else
* commands
* endi
*
* while expression
* commands
* continue
* break
* endw
*
* switch expression
* case 1
* commands
* break
* case 2
* commands
* break
* default
* commands
* ends
*
* label:
* goto label
*
*/
#define _DEFAULT_SOURCE
#include "os.h"
#include "sim.h"
#include "simParse.h"
#include "tutil.h"
#undef TAOS_MEM_CHECK
static SCommand *cmdHashList[MAX_NUM_CMD];
static SCmdLine cmdLine[MAX_CMD_LINES];
static char parseErr[MAX_ERROR_LEN];
static char optionBuffer[MAX_OPTION_BUFFER];
static int32_t numOfLines, optionOffset;
static SLabel label, dest;
static SBlock block;
int32_t simHashCmd(char *token, int32_t tokenLen) {
int32_t i;
int32_t hash = 0;
for (i = 0; i < tokenLen; ++i) hash += token[i];
hash = hash % MAX_NUM_CMD;
return hash;
}
SCommand *simCheckCmd(char *token, int32_t tokenLen) {
int32_t hash;
SCommand *node;
hash = simHashCmd(token, tokenLen);
node = cmdHashList[hash];
while (node) {
if (node->nlen == tokenLen && strncmp(node->name, token, tokenLen) == 0) {
return node;
} else {
node = node->next;
}
}
return NULL;
}
void simAddCmdIntoHash(SCommand *pCmd) {
int32_t hash;
SCommand *node;
hash = simHashCmd(pCmd->name, (int32_t)strlen(pCmd->name));
node = cmdHashList[hash];
pCmd->next = node;
cmdHashList[hash] = pCmd;
}
void simResetParser() {
optionOffset = 4;
numOfLines = 0;
memset(cmdLine, 0, sizeof(cmdLine));
memset(optionBuffer, 0, sizeof(optionBuffer));
memset(&label, 0, sizeof(label));
memset(&block, 0, sizeof(block));
memset(&dest, 0, sizeof(dest));
}
SScript *simBuildScriptObj(char *fileName) {
int32_t i, destPos;
/* process labels */
cmdLine[numOfLines].cmdno = SIM_CMD_RETURN;
numOfLines++;
for (i = 0; i < numOfLines; ++i) {
cmdLine[i].errorJump = SQL_JUMP_FALSE;
}
for (--dest.top; dest.top >= 0; --dest.top) {
for (i = 0; i < label.top; ++i) {
if (strcmp(label.label[i], dest.label[(uint8_t)dest.top]) == 0) break;
}
if (i == label.top) {
sprintf(parseErr, "label:%s not defined", dest.label[(uint8_t)dest.top]);
return NULL;
}
destPos = dest.pos[(uint8_t)dest.top];
cmdLine[destPos].jump = label.pos[i];
if (cmdLine[destPos].cmdno == SIM_CMD_SQL) {
cmdLine[destPos].errorJump = SQL_JUMP_TRUE;
}
}
if (block.top != 0) {
sprintf(parseErr, "mismatched block");
return NULL;
}
for (i = 0; i < numOfLines; ++i) {
if (cmdLine[i].jump == 0) cmdLine[i].jump = numOfLines;
}
SScript *script = malloc(sizeof(SScript));
memset(script, 0, sizeof(SScript));
script->type = SIM_SCRIPT_TYPE_MAIN;
script->numOfLines = numOfLines;
tstrncpy(script->fileName, fileName, sizeof(script->fileName));
script->optionBuffer = malloc(optionOffset);
memcpy(script->optionBuffer, optionBuffer, optionOffset);
script->lines = malloc(sizeof(SCmdLine) * numOfLines);
memcpy(script->lines, cmdLine, sizeof(SCmdLine) * numOfLines);
return script;
}
SScript *simParseScript(char *fileName) {
FILE * fd;
int32_t tokenLen, lineNum = 0;
char buffer[MAX_LINE_LEN], name[128], *token, *rest;
SCommand *pCmd;
SScript * script;
if ((fileName[0] == '.') || (fileName[0] == '/')) {
strcpy(name, fileName);
} else {
sprintf(name, "%s/%s", tsScriptDir, fileName);
}
if ((fd = fopen(name, "r")) == NULL) {
simError("failed to open file:%s", name);
return NULL;
}
simResetParser();
while (!feof(fd)) {
if (fgets(buffer, sizeof(buffer), fd) == NULL) continue;
lineNum++;
int32_t cmdlen = (int32_t)strlen(buffer);
if (buffer[cmdlen - 1] == '\r' || buffer[cmdlen - 1] == '\n') {
buffer[cmdlen - 1] = 0;
}
rest = buffer;
for (int32_t i = 0; i < cmdlen; ++i) {
if (buffer[i] == '\r' || buffer[i] == '\n') {
buffer[i] = ' ';
}
}
again:
rest = paGetToken(rest, &token, &tokenLen);
if (tokenLen == 0) continue;
if (token[tokenLen - 1] == ':') {
strncpy(label.label[(uint8_t)label.top], token, tokenLen - 1);
label.pos[(uint8_t)label.top] = numOfLines;
label.top++;
goto again;
}
if (token[0] == '$') {
if (!simParseExpression(token, lineNum)) {
simError("script:%s line:%d %s", fileName, lineNum, parseErr);
return NULL;
}
continue;
}
if ((pCmd = simCheckCmd(token, tokenLen)) == NULL) {
token[tokenLen] = 0;
simError("script:%s line:%d invalid cmd:%s", fileName, lineNum, token);
return NULL;
}
if (!pCmd->parseCmd(rest, pCmd, lineNum)) {
simError("script:%s line:%d %s", fileName, lineNum, parseErr);
return NULL;
}
}
fclose(fd);
script = simBuildScriptObj(fileName);
if (script == NULL) simError("script:%s %s", fileName, parseErr);
return script;
}
int32_t simCheckExpression(char *exp) {
char * op1, *op2, *op, *rest;
int32_t op1Len, op2Len, opLen;
rest = paGetToken(exp, &op1, &op1Len);
if (op1Len == 0) {
sprintf(parseErr, "expression is required");
return -1;
}
rest = paGetToken(rest, &op, &opLen);
if (opLen == 0) {
sprintf(parseErr, "operator is missed");
return -1;
}
rest = paGetToken(rest, &op2, &op2Len);
if (op2Len == 0) {
sprintf(parseErr, "operand is missed");
return -1;
}
if (opLen == 1) {
if (op[0] != '=' && op[0] != '<' && op[0] != '>') {
sprintf(parseErr, "invalid operator:%s", op);
return -1;
}
if (op[0] == '=' && op1[0] != '$') {
sprintf(parseErr, "left side of assignment must be variable");
return -1;
}
} else if (opLen == 2) {
if (op[1] != '=' || (op[0] != '=' && op[0] != '<' && op[0] != '>' && op[0] != '!')) {
sprintf(parseErr, "left side of assignment must be variable");
return -1;
}
} else {
sprintf(parseErr, "invalid operator:%s", op);
return -1;
}
rest = paGetToken(rest, &op, &opLen);
if (opLen == 0) return (int32_t)(rest - exp);
/* if it is key word "then" */
if (strncmp(op, "then", 4) == 0) return (int32_t)(op - exp);
rest = paGetToken(rest, &op2, &op2Len);
if (op2Len == 0) {
sprintf(parseErr, "operand is missed");
return -1;
}
if (opLen > 1) {
sprintf(parseErr, "invalid operator:%s", op);
return -1;
}
if (op[0] == '+' || op[0] == '-' || op[0] == '*' || op[0] == '/' || op[0] == '.') {
return (int32_t)(rest - exp);
}
return -1;
}
bool simParseExpression(char *token, int32_t lineNum) {
int32_t expLen;
expLen = simCheckExpression(token);
if (expLen <= 0) return -1;
cmdLine[numOfLines].cmdno = SIM_CMD_EXP;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, token, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
bool simParseIfCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * ret;
int32_t expLen;
expLen = simCheckExpression(rest);
if (expLen <= 0) return -1;
ret = rest + expLen;
if (strncmp(ret, "then", 4) == 0) {
block.type[(uint8_t)block.top] = BLOCK_IF;
block.pos[(uint8_t)block.top] = &cmdLine[numOfLines].jump;
block.top++;
} else {
cmdLine[numOfLines].jump = numOfLines + 2;
}
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
cmdLine[numOfLines].cmdno = SIM_CMD_TEST;
cmdLine[numOfLines].lineNum = lineNum;
numOfLines++;
return true;
}
bool simParseElifCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
expLen = simCheckExpression(rest);
if (expLen <= 0) return -1;
if (block.top < 1) {
sprintf(parseErr, "no matching if");
return false;
}
if (block.type[block.top - 1] != BLOCK_IF) {
sprintf(parseErr, "no matched if block");
return false;
}
cmdLine[numOfLines].cmdno = SIM_CMD_GOTO;
block.jump[block.top - 1][(uint8_t)block.numJump[block.top - 1]] = &(cmdLine[numOfLines].jump);
block.numJump[block.top - 1]++;
numOfLines++;
*(block.pos[block.top - 1]) = numOfLines;
block.pos[block.top - 1] = &cmdLine[numOfLines].jump;
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
cmdLine[numOfLines].cmdno = SIM_CMD_TEST;
cmdLine[numOfLines].lineNum = lineNum;
numOfLines++;
return true;
}
bool simParseElseCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
if (block.top < 1) {
sprintf(parseErr, "no matching if");
return false;
}
if (block.type[block.top - 1] != BLOCK_IF) {
sprintf(parseErr, "no matched if block");
return false;
}
cmdLine[numOfLines].cmdno = SIM_CMD_GOTO;
block.jump[block.top - 1][(uint8_t)block.numJump[block.top - 1]] = &(cmdLine[numOfLines].jump);
block.numJump[block.top - 1]++;
numOfLines++;
*(block.pos[block.top - 1]) = numOfLines;
block.pos[block.top - 1] = NULL;
return true;
}
bool simParseEndiCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t i;
if (block.top < 1) {
sprintf(parseErr, "no matching if");
return false;
}
if (block.type[block.top - 1] != BLOCK_IF) {
sprintf(parseErr, "no matched if block");
return false;
}
if (block.pos[block.top - 1]) *(block.pos[block.top - 1]) = numOfLines;
for (i = 0; i < block.numJump[block.top - 1]; ++i) {
*(block.jump[block.top - 1][i]) = numOfLines;
}
block.numJump[block.top - 1] = 0;
block.top--;
return true;
}
bool simParseWhileCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
expLen = simCheckExpression(rest);
if (expLen <= 0) return false;
block.type[(uint8_t)block.top] = BLOCK_WHILE;
block.pos[(uint8_t)block.top] = &(cmdLine[numOfLines].jump);
block.back[(uint8_t)block.top] = numOfLines;
block.top++;
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
cmdLine[numOfLines].cmdno = SIM_CMD_TEST;
cmdLine[numOfLines].lineNum = lineNum;
numOfLines++;
return true;
}
bool simParseEndwCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t i;
if (block.top < 1) {
sprintf(parseErr, "no matching while");
return false;
}
if (block.type[block.top - 1] != BLOCK_WHILE) {
sprintf(parseErr, "no matched while block");
return false;
}
cmdLine[numOfLines].cmdno = SIM_CMD_GOTO;
cmdLine[numOfLines].jump = block.back[block.top - 1];
cmdLine[numOfLines].lineNum = lineNum;
numOfLines++;
*(block.pos[block.top - 1]) = numOfLines;
for (i = 0; i < block.numJump[block.top - 1]; ++i) {
*(block.jump[block.top - 1][i]) = numOfLines;
}
block.top--;
return true;
}
bool simParseSwitchCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * token;
int32_t tokenLen;
rest = paGetToken(rest, &token, &tokenLen);
if (tokenLen == 0) {
sprintf(parseErr, "switch should be followed by variable");
return false;
}
if (token[0] != '$') {
sprintf(parseErr, "switch must be followed by variable");
return false;
}
memcpy(block.sexp[(uint8_t)block.top], token, tokenLen);
block.sexpLen[(uint8_t)block.top] = tokenLen;
block.type[(uint8_t)block.top] = BLOCK_SWITCH;
block.top++;
return true;
}
bool simParseCaseCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * token;
int32_t tokenLen;
rest = paGetToken(rest, &token, &tokenLen);
if (tokenLen == 0) {
sprintf(parseErr, "case should be followed by value");
return false;
}
if (block.top < 1) {
sprintf(parseErr, "no matching switch");
return false;
}
if (block.type[block.top - 1] != BLOCK_SWITCH) {
sprintf(parseErr, "case not matched");
return false;
}
if (block.pos[block.top - 1] != NULL) {
*(block.pos[block.top - 1]) = numOfLines;
}
block.pos[block.top - 1] = &(cmdLine[numOfLines].jump);
cmdLine[numOfLines].cmdno = SIM_CMD_TEST;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, block.sexp[block.top - 1], block.sexpLen[block.top - 1]);
optionOffset += block.sexpLen[block.top - 1];
*(optionBuffer + optionOffset++) = ' ';
*(optionBuffer + optionOffset++) = '=';
*(optionBuffer + optionOffset++) = '=';
*(optionBuffer + optionOffset++) = ' ';
memcpy(optionBuffer + optionOffset, token, tokenLen);
optionOffset += tokenLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
bool simParseBreakCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
if (block.top < 1) {
sprintf(parseErr, "no blcok exists");
return false;
}
if (block.type[block.top - 1] != BLOCK_SWITCH && block.type[block.top - 1] != BLOCK_WHILE) {
sprintf(parseErr, "not in switch or while block");
return false;
}
block.jump[block.top - 1][(uint8_t)block.numJump[block.top - 1]] = &(cmdLine[numOfLines].jump);
block.numJump[block.top - 1]++;
cmdLine[numOfLines].cmdno = SIM_CMD_GOTO;
cmdLine[numOfLines].lineNum = lineNum;
numOfLines++;
return true;
}
bool simParseDefaultCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
if (block.top < 1) {
sprintf(parseErr, "no matching switch");
return false;
}
if (block.type[block.top - 1] != BLOCK_SWITCH) {
sprintf(parseErr, "default should be matched with switch");
return false;
}
if (block.pos[block.top - 1] != NULL) {
*(block.pos[block.top - 1]) = numOfLines;
}
return true;
}
bool simParseEndsCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t i;
if (block.top < 1) {
sprintf(parseErr, "no matching switch");
return false;
}
if (block.type[block.top - 1] != BLOCK_SWITCH) {
sprintf(parseErr, "ends should be matched with switch");
return false;
}
for (i = 0; i < block.numJump[block.top - 1]; ++i) {
*(block.jump[block.top - 1][i]) = numOfLines;
}
block.numJump[block.top - 1] = 0;
block.top--;
return true;
}
bool simParseContinueCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
if (block.top < 1) {
sprintf(parseErr, "no matching while");
return false;
}
if (block.type[block.top - 1] != BLOCK_WHILE) {
sprintf(parseErr, "continue should be matched with while cmd");
return false;
}
cmdLine[numOfLines].cmdno = SIM_CMD_GOTO;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].jump = block.back[block.top - 1];
numOfLines++;
return true;
}
bool simParsePrintCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
rest++;
cmdLine[numOfLines].cmdno = SIM_CMD_PRINT;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
expLen = (int32_t)strlen(rest);
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
void simCheckSqlOption(char *rest) {
int32_t valueLen;
char * value, *xpos;
xpos = strstr(rest, " -x"); // need a blank
if (xpos) {
paGetToken(xpos + 3, &value, &valueLen);
if (valueLen != 0) {
memcpy(dest.label[(uint8_t)dest.top], value, valueLen);
dest.label[(uint8_t)dest.top][valueLen] = 0;
dest.pos[(uint8_t)dest.top] = numOfLines;
dest.top++;
*xpos = 0;
}
}
}
bool simParseSqlCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
rest++;
simCheckSqlOption(rest);
cmdLine[numOfLines].cmdno = SIM_CMD_SQL;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
expLen = (int32_t)strlen(rest);
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
bool simParseSqlErrorCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
rest++;
cmdLine[numOfLines].cmdno = SIM_CMD_SQL_ERROR;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
expLen = (int32_t)strlen(rest);
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
bool simParseSqlSlowCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
simParseSqlCmd(rest, pCmd, lineNum);
cmdLine[numOfLines - 1].cmdno = SIM_CMD_SQL_SLOW;
return true;
}
bool simParseRestfulCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
simParseSqlCmd(rest, pCmd, lineNum);
cmdLine[numOfLines - 1].cmdno = SIM_CMD_RESTFUL;
return true;
}
bool simParseSystemCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
rest++;
cmdLine[numOfLines].cmdno = SIM_CMD_SYSTEM;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
expLen = (int32_t)strlen(rest);
memcpy(optionBuffer + optionOffset, rest, expLen);
optionOffset += expLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
bool simParseSystemContentCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
simParseSystemCmd(rest, pCmd, lineNum);
cmdLine[numOfLines - 1].cmdno = SIM_CMD_SYSTEM_CONTENT;
return true;
}
bool simParseSleepCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * token;
int32_t tokenLen;
cmdLine[numOfLines].cmdno = SIM_CMD_SLEEP;
cmdLine[numOfLines].lineNum = lineNum;
paGetToken(rest, &token, &tokenLen);
if (tokenLen > 0) {
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, token, tokenLen);
optionOffset += tokenLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
}
numOfLines++;
return true;
}
bool simParseReturnCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * token;
int32_t tokenLen;
cmdLine[numOfLines].cmdno = SIM_CMD_RETURN;
cmdLine[numOfLines].lineNum = lineNum;
paGetToken(rest, &token, &tokenLen);
if (tokenLen > 0) {
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, token, tokenLen);
optionOffset += tokenLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
}
numOfLines++;
return true;
}
bool simParseGotoCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * token;
int32_t tokenLen;
rest = paGetToken(rest, &token, &tokenLen);
if (tokenLen == 0) {
sprintf(parseErr, "label should be followed by goto cmd");
return false;
}
memcpy(dest.label[(uint8_t)dest.top], token, tokenLen);
dest.label[(uint8_t)dest.top][tokenLen] = 0;
dest.pos[(uint8_t)dest.top] = numOfLines;
dest.top++;
cmdLine[numOfLines].cmdno = SIM_CMD_GOTO;
cmdLine[numOfLines].lineNum = lineNum;
numOfLines++;
return true;
}
bool simParseRunCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char * token;
int32_t tokenLen;
rest = paGetToken(rest, &token, &tokenLen);
if (tokenLen == 0) {
sprintf(parseErr, "file name should be followed by run cmd");
return false;
}
cmdLine[numOfLines].cmdno = SIM_CMD_RUN;
cmdLine[numOfLines].lineNum = lineNum;
cmdLine[numOfLines].optionOffset = optionOffset;
memcpy(optionBuffer + optionOffset, token, tokenLen);
optionOffset += tokenLen + 1;
*(optionBuffer + optionOffset - 1) = 0;
numOfLines++;
return true;
}
bool simParseRunBackCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
simParseRunCmd(rest, pCmd, lineNum);
cmdLine[numOfLines - 1].cmdno = SIM_CMD_RUN_BACK;
return true;
}
void simInitsimCmdList() {
int32_t cmdno;
memset(simCmdList, 0, SIM_CMD_END * sizeof(SCommand));
/* internal command */
cmdno = SIM_CMD_EXP;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "exp");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = NULL;
simCmdList[cmdno].executeCmd = simExecuteExpCmd;
cmdno = SIM_CMD_IF;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "if");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseIfCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_ELIF;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "elif");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseElifCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_ELSE;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "else");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseElseCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_ENDI;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "endi");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseEndiCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_WHILE;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "while");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseWhileCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_ENDW;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "endw");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseEndwCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SWITCH;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "switch");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSwitchCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_CASE;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "case");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseCaseCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_DEFAULT;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "default");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseDefaultCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_BREAK;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "break");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseBreakCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_CONTINUE;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "continue");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseContinueCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_ENDS;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "ends");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseEndsCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SLEEP;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "sleep");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSleepCmd;
simCmdList[cmdno].executeCmd = simExecuteSleepCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_GOTO;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "goto");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseGotoCmd;
simCmdList[cmdno].executeCmd = simExecuteGotoCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_RUN;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "run");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseRunCmd;
simCmdList[cmdno].executeCmd = simExecuteRunCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_RUN_BACK;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "run_back");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseRunBackCmd;
simCmdList[cmdno].executeCmd = simExecuteRunBackCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SYSTEM;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "system");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSystemCmd;
simCmdList[cmdno].executeCmd = simExecuteSystemCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SYSTEM_CONTENT;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "system_content");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSystemContentCmd;
simCmdList[cmdno].executeCmd = simExecuteSystemContentCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_PRINT;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "print");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParsePrintCmd;
simCmdList[cmdno].executeCmd = simExecutePrintCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SQL;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "sql");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSqlCmd;
simCmdList[cmdno].executeCmd = simExecuteSqlCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SQL_ERROR;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "sql_error");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSqlErrorCmd;
simCmdList[cmdno].executeCmd = simExecuteSqlErrorCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_SQL_SLOW;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "sql_slow");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseSqlSlowCmd;
simCmdList[cmdno].executeCmd = simExecuteSqlSlowCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
cmdno = SIM_CMD_RESTFUL;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "restful");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseRestfulCmd;
simCmdList[cmdno].executeCmd = simExecuteRestfulCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
/* test is only an internal command */
cmdno = SIM_CMD_TEST;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "test");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = NULL;
simCmdList[cmdno].executeCmd = simExecuteTestCmd;
cmdno = SIM_CMD_RETURN;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "return");
simCmdList[cmdno].nlen = (int16_t)strlen(simCmdList[cmdno].name);
simCmdList[cmdno].parseCmd = simParseReturnCmd;
simCmdList[cmdno].executeCmd = simExecuteReturnCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
}