⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 si_ops.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
{
	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 + -