📄 si_ops.c
字号:
{
pstructOpS result = OpS_New();
UINT32 strPos = 0;
UINT32 argstrLen = 0;
UINT32 argStart;
UINT32 argEnd;
WCHAR aChar;
enumArgState state = argstate_start;
pstructVar anArgVar = NULL;
BOOL isSingleQuoteString = FALSE; /* to know if the state argstate_string is contained within ' or " */
UINT32 theNewStrLen;
pstructEscapeSeq escapeSeqList = NULL;
pstructEscapeSeq lastEscEl = NULL;
pstructEscapeSeq newEscEl = NULL;
pstructEscapeSeq escEl = NULL;
UINT32 srcPos;
UINT32 dstPos;
/* the following three vars are stack allocated and will be cleaned away by the system at function exit */
WCHAR invalidStr[] = {'i','n','v','a','l','i','d', 0}; /* needed to compare with argsString to see if found */
WCHAR trueStr[] = {'t','r','u','e', 0}; /* needed to compare with argsString to see if found */
WCHAR falseStr[] = {'f','a','l','s','e', 0}; /* needed to compare with argsString to see if found */
UINT32 invalidStrLen = STRINGLENGTH( invalidStr );
UINT32 trueStrLen = STRINGLENGTH( trueStr );
UINT32 falseStrLen = STRINGLENGTH( falseStr );
if (argString != NULL) {
argstrLen = STRINGLENGTH( argString );
while ((state != argstate_error) && (state != argstate_done) && (strPos < argstrLen))
{
aChar = argString[ strPos ];
switch (state)
{
case argstate_start: /* starts here on first char after opening parathesis */
if (IsWhitespaceChar(aChar)) {
/* nothing to be done except the strpos++ */
}
else if (IsEndParathesisChar(aChar)) {
state = argstate_done;
}
else {
if (IsNumberChar(aChar)) {
state = argstate_number;
}
else if (IsSingleQuoteChar(aChar)) {
theNewStrLen = 0;
lastEscEl = NULL;
newEscEl = NULL;
isSingleQuoteString = TRUE;
state = argstate_string;
}
else if (IsDoubleQuoteChar(aChar)) {
theNewStrLen = 0;
lastEscEl = NULL;
newEscEl = NULL;
isSingleQuoteString = FALSE;
state = argstate_string;
}
else if (IsTrueStartChar(aChar)) {
state = argstate_true;
}
else if (IsFalseStartChar(aChar)) {
state = argstate_false;
}
else if (IsInvalidStartChar(aChar)) {
state = argstate_invalid;
}
else {
state = argstate_error;
}
argStart = strPos;
}
strPos++;
break;
case argstate_nextOrDone: /* waiting for comma or end paranthesis */
if (IsWhitespaceChar(aChar)) {
strPos++;
}
else if (IsCommaChar(aChar)) {
state = argstate_next;
strPos++;
}
else if (IsEndParathesisChar(aChar)) {
state = argstate_done;
}
else {
state = argstate_error;
}
break;
case argstate_next: /* waiting for start of next argument */
if (IsWhitespaceChar(aChar)) {
/* nothing to be done except the strpos++ */
}
else {
if (IsNumberChar(aChar)) {
state = argstate_number;
}
else if (IsSingleQuoteChar(aChar)) {
theNewStrLen = 0;
lastEscEl = NULL;
newEscEl = NULL;
isSingleQuoteString = TRUE;
state = argstate_string;
}
else if (IsDoubleQuoteChar(aChar)) {
theNewStrLen = 0;
lastEscEl = NULL;
newEscEl = NULL;
isSingleQuoteString = FALSE;
state = argstate_string;
}
else if (IsTrueStartChar(aChar)) {
state = argstate_true;
}
else if (IsFalseStartChar(aChar)) {
state = argstate_false;
}
else if (IsInvalidStartChar(aChar)) {
state = argstate_invalid;
}
else {
state = argstate_error;
}
argStart = strPos;
}
strPos++;
break;
case argstate_invalid: /* 'i' has been found and the rest of the 'invalid' literal should come */
/* check if the 'invalid' literal can fit in the rest of the argStr */
if ((strPos + invalidStrLen -1) > argstrLen) {
state = argstate_error;
break;
}
/* now check if the 'invalid' literal is in the text, else an error has occured */
if (COMPARESTRINGN( &(argString[argStart]), invalidStr, invalidStrLen ) == 0) {
/* literal found! */
strPos += (invalidStrLen-1); /* -1 because the first letter has already been stepped past */
/* push invalid on the OpS */
anArgVar = Var_New();
Var_AssignInvalid( anArgVar );
OpS_Push( result, &anArgVar );
state = argstate_nextOrDone;
}
else {
state = argstate_error;
}
break;
case argstate_true: /* 't' has been found and the rest of the 'true' literal should come */
/* check if the 'true' literal can fit in the rest of the argStr */
if ((strPos + trueStrLen -1) > argstrLen) {
state = argstate_error;
break;
}
/* now check if the 'true' literal is in the text, else an error has occured */
if (COMPARESTRINGN( &(argString[argStart]), trueStr, trueStrLen ) == 0) {
/* literal found! */
strPos += (trueStrLen-1); /* -1 because the first letter has already been stepped past */
/* push invalid on the OpS */
anArgVar = Var_New();
Var_AssignBool( anArgVar, TRUE );
OpS_Push( result, &anArgVar );
state = argstate_nextOrDone;
}
else {
state = argstate_error;
}
break;
case argstate_false: /* 'f' has been found and the rest of the 'false' literal should come */
/* check if the 'false' literal can fit in the rest of the argStr */
if ((strPos + falseStrLen -1) > argstrLen) {
state = argstate_error;
break;
}
/* now check if the 'false' literal is in the text, else an error has occured */
if (COMPARESTRINGN( &(argString[argStart]), falseStr, falseStrLen ) == 0) {
/* literal found! */
strPos += (falseStrLen-1); /* -1 because the first letter has already been stepped past */
/* push invalid on the OpS */
anArgVar = Var_New();
Var_AssignBool( anArgVar, FALSE );
OpS_Push( result, &anArgVar );
state = argstate_nextOrDone;
}
else {
state = argstate_error;
}
break;
case argstate_string: /* inside a string */
if ((IsSingleQuoteChar(aChar) && isSingleQuoteString) ||
(IsDoubleQuoteChar(aChar) && (!isSingleQuoteString))) {
/* has found the end of the string */
argEnd = strPos; /* the quotes are included in the argStart/argEnd */
/* create a new string var with enough room for the parameter */
anArgVar = Var_New();
Var_NewString( anArgVar, theNewStrLen );
srcPos = argStart+1; /* the start of the the string contents is the first char after the start quote */
dstPos = 0;
escEl = escapeSeqList;
while (escEl != NULL)
{
/* copy the chars up till the escape sequence */
COPYSTRINGN( &(anArgVar->val.theString[dstPos]), &(argString[srcPos]), escEl->startPos - srcPos );
dstPos += escEl->startPos - srcPos;
/* insert the real char */
anArgVar->val.theString[ dstPos ] = escEl->theChar;
dstPos++;
srcPos = escEl->endPos;
escEl = escEl->next;
}
if (srcPos < argEnd)
{ /* more of the string left, then copy the rest of the string */
COPYSTRINGN( &(anArgVar->val.theString[dstPos]), &(argString[srcPos]), argEnd - srcPos );
}
/* the string parameter is done, now push it on the OpS */
OpS_Push( result, &anArgVar );
EscSeq_Delete( &escapeSeqList );
/* clear the list of escape seq so that the next string doesn't get this already filled list */
strPos++;
state = argstate_nextOrDone;
}
else if (IsEscapeChar(aChar)) {
strPos++;
/* stepped over the "\" character */
newEscEl = GetEscapedChar( argString, &strPos, argstrLen );
if (newEscEl != NULL)
{
if (lastEscEl == NULL)
{
escapeSeqList = newEscEl;
}
else
{
lastEscEl->next = newEscEl;
}
lastEscEl = newEscEl;
theNewStrLen++;
}
else
{
state = argstate_error;
}
}
else {
/* all other chars are just a part of the string */
theNewStrLen++; /* normal char adds one to the length */
strPos++;
}
break;
case argstate_number: /* inside a integer/float */
if (IsNumberChar(aChar)) {
/* still a number */
strPos++;
}
else if ( IsWhitespaceChar(aChar) ||
IsCommaChar(aChar) ||
IsEndParathesisChar(aChar)) {
/*
the number is now ended and must now be converted
to a pstructVar and pushed on the OpS
*/
argEnd = strPos;
anArgVar = Var_New();
Var_AssignString( anArgVar, argEnd-argStart, &(argString[ argStart ]) );
if (Var_ConvertMethod(CONVERT_INT_FLOAT, anArgVar, NULL)) {
OpS_Push( result, &anArgVar );
state = argstate_nextOrDone;
}
else {
state = argstate_error;
}
}
else {
state = argstate_error;
}
/*
NOTE!!!: the strPos is not advanced,
the interpreting of the ',' or ')' or ' ' will be done in the next while run
*/
break;
}
}
}
else {
OpS_Delete( &result );
}
Var_Delete( &anArgVar );
EscSeq_Delete( &escapeSeqList ); /* to make sure this has been deallocated */
if (state == argstate_error) {
OpS_Delete( &result );
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -