示例#1
0
void CScriptKeyAlloc::ParseKeyLate()
{
	ADDTOCALLSTACK("CScriptKeyAlloc::ParseKeyLate");
	ASSERT(m_pszKey);
	ParseKeyEnd();
	GETNONWHITESPACE(m_pszKey);
	Str_Parse(m_pszKey, &m_pszArg);
}
示例#2
0
bool CScript::FindNextSection()
{
	ADDTOCALLSTACK("CScript::FindNextSection");
	EXC_TRY("FindNextSection");
	// RETURN: false = EOF.

	if ( m_fSectionHead )	// we have read a section already., (not at the start)
	{
		// Start from the previous line. It was the line that ended the last read.
		m_pszKey = GetKeyBuffer();
		ASSERT(m_pszKey);
		m_fSectionHead = false;
		if ( m_pszKey[0] == '[' )
			goto foundit;
	}

	for (;;)
	{
		if ( !ReadTextLine(true) )
		{
			m_lSectionData = GetPosition();
			return( false );
		}
		if ( m_pszKey[0] == '[' )
			break;
	}

foundit:
	// Parse up the section name.
	m_pszKey++;
	size_t len = strlen( m_pszKey );
	for ( size_t i = 0; i < len; i++ )
	{
		if ( m_pszKey[i] == ']' )
		{
			m_pszKey[i] = '\0';
			break;
		}
	}

	m_lSectionData = GetPosition();
	if ( IsSectionType( "EOF" ))
		return( false );

	Str_Parse( m_pszKey, &m_pszArg );
	return true;
	EXC_CATCH;
	return false;
}
示例#3
0
size_t Str_ParseCmds( TCHAR * pszCmdLine, TCHAR ** ppCmd, size_t iMax, LPCTSTR pszSep )
{
	size_t iQty = 0;
	if ( pszCmdLine != NULL && pszCmdLine[0] != '\0' )
	{
		ppCmd[0] = pszCmdLine;
		iQty++;
		while ( Str_Parse( ppCmd[iQty-1], &(ppCmd[iQty]), pszSep ))
		{
			if ( ++iQty >= iMax )
				break;
		}
	}
	for ( size_t j = iQty; j < iMax; j++ )
		ppCmd[j] = NULL;	// terminate if possible.
	return( iQty );
}
示例#4
0
bool CScriptKeyAlloc::ParseKey( LPCTSTR pszKey )
{
	ADDTOCALLSTACK("CScriptKeyAlloc::ParseKey");
	// Skip leading white space 
	if ( ! pszKey )
	{
		GetKeyBufferRaw(0);
		return false;
	}

	GETNONWHITESPACE( pszKey );

	TCHAR * pBuffer = GetKeyBufferRaw( strlen( pszKey ));
	ASSERT(pBuffer);

	size_t iLen = m_Mem.GetDataLength() - 1;
	strncpy( pBuffer, pszKey, iLen );
	pBuffer[iLen] = '\0';

	Str_Parse( pBuffer, &m_pszArg );
	return( true );
}
示例#5
0
llong CExpression::GetSingle( lpctstr & pszArgs )
{
	ADDTOCALLSTACK("CExpression::GetSingle");
	// Parse just a single expression without any operators or ranges.
	ASSERT(pszArgs);
	GETNONWHITESPACE( pszArgs );

	lpctstr orig = pszArgs;
	if (pszArgs[0]=='.')
		++pszArgs;

	if ( pszArgs[0] == '0' )	// leading '0' = hex value.
	{
		// A hex value.
		if ( pszArgs[1] == '.' )	// leading 0. means it really is decimal.
		{
			pszArgs += 2;
			goto try_dec;
		}

		lpctstr pStart = pszArgs;
		ullong val = 0;
		while (true)
		{
			tchar ch = *pszArgs;
			if ( IsDigit(ch) )
				ch -= '0';
			else
			{
				ch = static_cast<tchar>(tolower(ch));
				if ( ch > 'f' || ch < 'a' )
				{
					if ( ch == '.' && pStart[0] != '0' )	// ok i'm confused. it must be decimal.
					{
						pszArgs = pStart;
						goto try_dec;
					}
					break;
				}
				ch -= 'a' - 10;
			}
			val *= 0x10;
			val += ch;
			++pszArgs;
		}
		return (llong)val;
	}
	else if ( pszArgs[0] == '.' || IsDigit(pszArgs[0]) )
	{
		// A decminal number
try_dec:
		llong iVal = 0;
		for ( ; ; ++pszArgs )
		{
			if ( *pszArgs == '.' )
				continue;	// just skip this.
			if ( ! IsDigit(*pszArgs) )
				break;
			iVal *= 10;
			iVal += *pszArgs - '0';
		}
		return iVal;
	}
	else if ( ! _ISCSYMF(pszArgs[0]) )
	{
	#pragma region maths
		// some sort of math op ?

		switch ( pszArgs[0] )
		{
		case '{':
			++pszArgs;
			return GetRangeNumber( pszArgs );
		case '[':
		case '(': // Parse out a sub expression.
			++pszArgs;
			return GetVal( pszArgs );
		case '+':
			++pszArgs;
			break;
		case '-':
			++pszArgs;
			return -GetSingle( pszArgs );
		case '~':	// Bitwise not.
			++pszArgs;
			return ~GetSingle( pszArgs );
		case '!':	// boolean not.
			++pszArgs;
			if ( pszArgs[0] == '=' )  // odd condition such as (!=x) which is always true of course.
			{
				++pszArgs;		// so just skip it. and compare it to 0
				return GetSingle( pszArgs );
			}
			return !GetSingle( pszArgs );
		case ';':	// seperate field.
		case ',':	// seperate field.
		case '\0':
			return 0;
		}
#pragma endregion maths
	}
	else
	#pragma region intrinsics
	{
		// Symbol or intrinsinc function ?

		INTRINSIC_TYPE iIntrinsic = (INTRINSIC_TYPE) FindTableHeadSorted( pszArgs, sm_IntrinsicFunctions, CountOf(sm_IntrinsicFunctions)-1 );
		if ( iIntrinsic >= 0 )
		{
			size_t iLen = strlen(sm_IntrinsicFunctions[iIntrinsic]);
			if ( pszArgs[iLen] == '(' )
			{
				pszArgs += (iLen + 1);
				tchar * pszArgsNext;
				Str_Parse( const_cast<tchar*>(pszArgs), &(pszArgsNext), ")" );

				tchar * ppCmd[5];
				llong iResult;
				size_t iCount = 0;

				switch ( iIntrinsic )
				{
					case INTRINSIC_ID:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = RES_GET_INDEX( GetVal(pszArgs) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

                    case INTRINSIC_MAX:
                    {
                        iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
                        if ( iCount < 2 )
                            iResult = 0;
                        else
                        {
                            const int64 iVal1 = GetVal(ppCmd[0]), iVal2 = GetVal(ppCmd[1]);
                            iResult = maximum(iVal1, iVal2);
                        }
                    } break;

                    case INTRINSIC_MIN:
                    {
                        iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
                        if ( iCount < 2 )
                            iResult = 0;
                        else
                        {
                            const int64 iVal1 = GetVal(ppCmd[0]), iVal2 = GetVal(ppCmd[1]);
                            iResult = minimum(iVal1, iVal2);
                        }
                    } break;

					case INTRINSIC_LOGARITHM:
					{
						iCount = 0;
						iResult = 0;

						if ( pszArgs && *pszArgs )
						{
							llong iArgument = GetVal(pszArgs);
							if ( iArgument <= 0 )
							{
								DEBUG_ERR(( "Exp_GetVal: (x)Log(%" PRId64 ") is %s\n", iArgument, (!iArgument) ? "infinite" : "undefined" ));
							}
							else
							{
								iCount = 1;

								if ( strchr(pszArgs, ',') )
								{
									++iCount;
									SKIP_ARGSEP(pszArgs);
									if ( !strcmpi(pszArgs, "e") )
									{
										iResult = (llong)log( (double)iArgument );
									}
									else if ( !strcmpi(pszArgs, "pi") )
									{
										iResult = (llong)(log( (double)iArgument ) / log( M_PI ) );
									}
									else
									{
										llong iBase = GetVal(pszArgs);
										if ( iBase <= 0 )
										{
											DEBUG_ERR(( "Exp_GetVal: (%" PRId64 ")Log(%" PRId64 ") is %s\n", iBase, iArgument, (!iBase ? "infinite" : "undefined") ));
											iCount = 0;
										}
										else
											iResult = (llong)(log( (double)iArgument ) / log( (double)iBase ));
									}
								}
								else
									iResult = (llong)log10( (double)iArgument );
							}
						}

					} break;

					case INTRINSIC_NAPIERPOW:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)exp( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_SQRT:
					{
						iCount = 0;
						iResult = 0;

						if ( pszArgs && *pszArgs )
						{
							llong iTosquare = GetVal(pszArgs);

							if (iTosquare >= 0)
							{
								++iCount;
								iResult = (llong)sqrt( (double)iTosquare );
							}
							else
								DEBUG_ERR(( "Exp_GetVal: Sqrt of negative number (%" PRId64 ") is impossible\n", iTosquare ));
						}

					} break;

					case INTRINSIC_SIN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)sin( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCSIN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)asin( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_COS:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)cos( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCCOS:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)acos( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_TAN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)tan( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCTAN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)atan( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_StrIndexOf:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 3, "," );
						if ( iCount < 2 )
							iResult = -1;
						else
							iResult = Str_IndexOf( ppCmd[0] , ppCmd[1] , (iCount==3)?(int)GetVal(ppCmd[2]):0 );
					} break;

					case INTRINSIC_STRMATCH:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
							iResult = (Str_Match( ppCmd[0], ppCmd[1] ) == MATCH_VALID ) ? 1 : 0;
					} break;

					case INTRINSIC_STRREGEX:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
						{
							tchar * tLastError = Str_GetTemp();
							iResult = Str_RegExMatch( ppCmd[0], ppCmd[1], tLastError );
							if ( iResult == -1 )
							{
								DEBUG_ERR(( "STRREGEX bad function usage. Error: %s\n", tLastError ));
							}
						}
					} break;

					case INTRINSIC_RANDBELL:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
							iResult = Calc_GetBellCurve( (int)GetVal( ppCmd[0] ), (int)GetVal( ppCmd[1] ) );
					} break;

					case INTRINSIC_STRASCII:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = pszArgs[0];
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}
					} break;

					case INTRINSIC_RAND:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount <= 0 )
							iResult = 0;
						else
						{
							int64 val1 = GetVal( ppCmd[0] );
							if ( iCount == 2 )
							{
								int64 val2 = GetVal( ppCmd[1] );
								iResult = Calc_GetRandLLVal2( val1, val2 );
							}
							else
								iResult = Calc_GetRandLLVal(val1);
						}
					} break;

					case INTRINSIC_STRCMP:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 1;
						else
							iResult = strcmp(ppCmd[0], ppCmd[1]);
					} break;

					case INTRINSIC_STRCMPI:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 1;
						else
							iResult = strcmpi(ppCmd[0], ppCmd[1]);
					} break;

					case INTRINSIC_STRLEN:
					{
						iCount = 1;
						iResult = strlen(pszArgs);
					} break;

					case INTRINSIC_ISOBSCENE:
					{
						iCount = 1;
						iResult = g_Cfg.IsObscene( pszArgs );
					} break;
					case INTRINSIC_ISNUMBER:
					{
						iCount = 1;
						{
                            GETNONWHITESPACE( pszArgs );
                            if (*pszArgs == '-')
                                ++pszArgs;
							iResult = IsStrNumeric( pszArgs );
						}
					} break;

					case INTRINSIC_QVAL:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 5, "," );
						if ( iCount < 3 )
							iResult = 0;
						else
						{
							llong a1 = GetSingle(ppCmd[0]);
							llong a2 = GetSingle(ppCmd[1]);
							if ( a1 < a2 )			iResult = GetSingle(ppCmd[2]);
							else if ( a1 == a2 )	iResult = ( iCount < 4 ) ? 0 : GetSingle(ppCmd[3]);
							else					iResult = ( iCount < 5 ) ? 0 : GetSingle(ppCmd[4]);
						}
					} break;

					case INTRINSIC_ABS:
					{
						iCount = 1;
						iResult = llabs(GetVal(pszArgs));
					} break;

					default:
						iCount = 0;
						iResult = 0;
						break;
				}

				pszArgs = pszArgsNext;

				if ( !iCount )
				{
					DEBUG_ERR(( "Bad intrinsic function usage: Missing arguments\n" ));
					return 0;
				}
				else
					return iResult;
			}
		}

		// Must be a symbol of some sort ?
        lpctstr ptcArgsOriginal = pszArgs;
		llong llVal;
		if ( m_VarGlobals.GetParseVal_Advance( pszArgs, &llVal ) )  // VAR.
			return llVal;
        if ( m_VarResDefs.GetParseVal( ptcArgsOriginal, &llVal ) )  // RESDEF.
            return llVal;
		if ( m_VarDefs.GetParseVal( ptcArgsOriginal, &llVal ) )     // DEF.
			return llVal;
	}
#pragma endregion intrinsics

	// hard end ! Error of some sort.
	tchar szTag[ EXPRESSION_MAX_KEY_LEN ];
	size_t i = GetIdentifierString( szTag, pszArgs );
	pszArgs += i;	// skip it.
	if ( strlen(orig) > 1)
		DEBUG_ERR(("Undefined symbol '%s' ['%s']\n", szTag, orig));
	else
		DEBUG_ERR(("Undefined symbol '%s'\n", szTag));
	return 0;
}
示例#6
0
bool CScriptObj::r_WriteVal( LPCTSTR pszKey, CGString &sVal, CTextConsole * pSrc )
{
	EXC_TRY(("r_WriteVal('%s',,%x)", pszKey, pSrc));
	CScriptObj * pRef;
	if ( r_GetRef( pszKey, pRef ))
	{
		if ( pRef == NULL )	// good command but bad link.
		{
			sVal = "0";
			return true;
		}
		if ( pszKey[0] == '\0' )	// we where just testing the ref.
		{
			CObjBase *	pObj	= dynamic_cast <CObjBase *> (pRef);
			if ( pObj )
				sVal.FormatHex( (DWORD) pObj->GetUID() );
			else
				sVal.FormatVal( 1 );
			return( true );
		}
		return pRef->r_WriteVal( pszKey, sVal, pSrc );
	}

	int i = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 );
	if ( i < 0 )
	{
		// <dSOMEVAL> same as <eval <SOMEVAL>> to get dec from the val
		if (( *pszKey == 'd' ) || ( *pszKey == 'D' ))
		{
			LPCTSTR arg = pszKey + 1;
			if ( r_WriteVal(arg, sVal, pSrc) )
			{
				if ( !IsStrNumericDec(sVal) ) // dValue dec -> hex fix
				{
					sVal.FormatVal(ahextoi(sVal));
				}
				return true;
			}
		}
		// <r>, <r15>, <r3,15> are shortcuts to rand(), rand(15) and rand(3,15)
		else if (( *pszKey == 'r' ) || ( *pszKey == 'R' ))
		{
			char	*zTemp = Str_GetTemp();
			strcpy(zTemp, pszKey+1);

			if (( *zTemp ) &&  (( *zTemp < '0' ) || ( *zTemp > '9' )) )
				goto badcmd;

			TCHAR	*ppCmd[2];
			int		qty = Str_ParseCmds(zTemp, ppCmd, COUNTOF(ppCmd));
			int		min = 0, max = 1000;

			if ( qty == 1 ) max = atoi(ppCmd[0]);
			else if ( qty == 2 )
			{
				min = g_Exp.GetVal(ppCmd[0]);
				max = g_Exp.GetVal(ppCmd[1]);
			}

			if ( min > max )
			{
				int a = min;
				min = max;
				max = a;
			}
			if ( min == max )
				sVal.FormatVal(min);
			else
				sVal.FormatVal(min + Calc_GetRandVal(max - min));

			return true;
		}
badcmd:
		return false;	// Bad command.
	}

	pszKey += strlen( sm_szLoadKeys[i] );
	SKIP_SEPERATORS(pszKey);
	bool	fZero	= false;

	switch ( i )
	{
	case SSC_LISTCOL:
		// Set the alternating color.
		sVal = (CWebPageDef::sm_iListIndex&1) ? "bgcolor=\"#E8E8E8\"" : "";
		return( true );
	case SSC_OBJ:
		if ( !g_World.m_uidObj.ObjFind() ) g_World.m_uidObj = 0;
		sVal.FormatHex((DWORD)g_World.m_uidObj);
		return true;
	case SSC_NEW:
		if ( !g_World.m_uidNew.ObjFind() ) g_World.m_uidNew = 0;
		sVal.FormatHex((DWORD)g_World.m_uidNew);
		return true;
	case SSC_SRC:
		if ( pSrc == NULL )
			pRef	= NULL;
		else
		{
			pRef = pSrc->GetChar();	// if it can be converted .
			if ( ! pRef )
				pRef = dynamic_cast <CScriptObj*> (pSrc);	// if it can be converted .
		}
		if ( ! pRef )
		{
			sVal.FormatVal( 0 );
			return true;
		}
		if ( !*pszKey )
		{
			CObjBase * pObj = dynamic_cast <CObjBase*> (pRef);	// if it can be converted .
			sVal.FormatHex( pObj ? (DWORD) pObj->GetUID() : 0 );
			return true;
		}
		return pRef->r_WriteVal( pszKey, sVal, pSrc );
	case SSC_VAR0:
		fZero	= true;
	case SSC_VAR:
		// "VAR." = get/set a system wide variable.
		{
			CVarDefBase * pVar = g_Exp.m_VarGlobals.GetKey(pszKey);
			if ( pVar )
				sVal	= pVar->GetValStr();
			else if ( fZero )
				sVal	= "0";
		}
		return true;
	case SSC_DEF0:
		fZero	= true;
	case SSC_DEF:
		{
			CVarDefBase * pVar = g_Exp.m_VarDefs.GetKey(pszKey);
			if ( pVar )
				sVal	= pVar->GetValStr();
			else if ( fZero )
				sVal	= "0";
		}
		return( true );
	case SSC_EVAL:
		sVal.FormatVal( Exp_GetVal( pszKey ));
		return( true );
	case SSC_FVAL:
		{
		int	iVal		= Exp_GetVal( pszKey );
		sVal.Format( "%i.%i", iVal/10, abs(iVal%10) );
		return true;
		}
	case SSC_HVAL:
		sVal.FormatHex( Exp_GetVal( pszKey ));
		return( true );
	case SSC_QVAL:
		{	// Do a switch ? type statement <QVAL conditional ? option1 : option2>
			TCHAR * ppCmds[3];
			ppCmds[0] = const_cast<TCHAR*>(pszKey);
			Str_Parse( ppCmds[0], &(ppCmds[1]), "?" );
			Str_Parse( ppCmds[1], &(ppCmds[2]), ":" );
			sVal = ppCmds[ Exp_GetVal( ppCmds[0] ) ? 1 : 2 ];
			if ( sVal.IsEmpty())
				sVal = " ";
		}
		return( true );
	case SSC_ISEMPTY:
		sVal.FormatVal( IsStrEmpty( pszKey ) );
		return true;
	case SSC_ISNUM:
		GETNONWHITESPACE( pszKey );
		sVal.FormatVal( IsStrNumeric( pszKey ) );
		return true;
	case SSC_StrRev:
		{
			GETNONWHITESPACE( pszKey );
			sVal = pszKey;
			sVal.Reverse();
			return true;
		}
	case SSC_StrPos:
		{
			GETNONWHITESPACE( pszKey );
			int	iPos	= Exp_GetVal( pszKey );
			TCHAR	ch;
			if ( isdigit( *pszKey) && isdigit( *(pszKey+1) ) )
				ch	= (TCHAR) Exp_GetVal( pszKey );
			else
			{
				ch	= *pszKey;
				pszKey++;
			}
			
			GETNONWHITESPACE( pszKey );
			int	iLen	= strlen( pszKey );
			if ( iPos < 0 )
				iPos	= iLen + iPos;
			if ( iPos < 0 )
				iPos	= 0;
			else if ( iPos > iLen )
				iPos	= iLen;

			TCHAR *	pszPos	= strchr( pszKey + iPos, ch );
			if ( !pszPos )
				sVal.FormatVal( -1 );
			else
				sVal.FormatVal( pszPos - pszKey );
		}
		return true;
	case SSC_StrSub:
		{
			int	iPos	= Exp_GetVal( pszKey );
			int	iCnt	= Exp_GetVal( pszKey );
			SKIP_ARGSEP( pszKey );
			GETNONWHITESPACE( pszKey );

			int	iLen	= strlen( pszKey );
			if ( iPos < 0 ) iPos += iLen;
			if ( iPos > iLen || iPos < 0 ) iPos = 0;

			if ( iPos + iCnt > iLen || iCnt == 0 )
				iCnt = iLen - iPos;

			TCHAR	*buf = Str_GetTemp();
			strncpy( buf, pszKey + iPos, iCnt );
			buf[iCnt] = '\0';
			sVal = buf;
		}
		return true;
	case SSC_StrArg:
		{
			TCHAR	*buf = Str_GetTemp();
			GETNONWHITESPACE( pszKey );
			if ( *pszKey == '"' )
				pszKey++;
			int	i	= 0;
			while ( *pszKey && !isspace( *pszKey ) && *pszKey != ',' )
			{
				buf[i]	= *pszKey;
				pszKey++;
				i++;
			}
			buf[i]	= '\0';
			sVal	= buf;
		}
		return true;
	case SSC_StrEat:
		{
			GETNONWHITESPACE( pszKey );
			while ( *pszKey && !isspace( *pszKey ) && *pszKey != ',' )
				pszKey++;
			SKIP_ARGSEP( pszKey );
			sVal	= pszKey;
		}
		return true;
	case SSC_ASC:
		{
			TCHAR	*buf = Str_GetTemp();
			REMOVE_QUOTES( pszKey );
			sVal.FormatHex( *pszKey );
			sprintf( buf, sVal );
			while ( *(++pszKey) )
			{
				if ( *pszKey == '"' ) break;
				sVal.FormatHex( *pszKey );
				strcat( buf, " " );
				strcat( buf, sVal );
			}
			sVal	= buf;
		}
		return true;

	case SSC_READFILE:
		{
			if ( !IsSetOF( OF_FileCommands ) ) 
				return false;

			TCHAR	*rfArgs[1];
			FILE	*rfFD;
			TCHAR	*buf = Str_GetTemp();

			int line;

			rfArgs[0] = const_cast<TCHAR*>(pszKey);
			Str_Parse( rfArgs[0], &(rfArgs[1]), " " );

			// Remove other junk
			Str_Parse( rfArgs[1], NULL, " " );

			line = atoi( rfArgs[1] );

			sVal = "";
			if ( rfFD = fopen( rfArgs[0], "r" ))
			{
				if ( line == -1 )	// First line of the file
					fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
				else if ( line == 0 )
				{
					// Last line of the file
					while ( ! feof( rfFD ) )
						fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
				}					
				else
				{
					// Line "line" of the file
					int x;
					for ( x = 1; x <= line; x++ )
					{
						if ( feof(rfFD) )
						{
							buf[0] = 0;
							break;
						}
						fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
					}
				}
				sVal = buf;
				fclose(rfFD);
			}
		}
		return true;
	case SSC_FILELINES:
		{
			if ( !IsSetOF( OF_FileCommands ) )
				return false;
			
			TCHAR	*buf = Str_GetTemp();
			FILE	*flFD;
			int		x(0);
			GETNONWHITESPACE( pszKey );
			if ( flFD = fopen( pszKey, "r" ) )
			{
				while ( ! feof(flFD) )
				{
					fgets(buf, SCRIPT_MAX_LINE_LEN, flFD );
					x++;
				}
				fclose(flFD);
			}
			sVal.FormatVal(x);
		}
		return true;
	case SSC_SYSCMD:
	case SSC_SYSSPAWN:
		{
			if ( !IsSetOF(OF_FileCommands) )
				return false;

			GETNONWHITESPACE(pszKey);
			TCHAR	*buf = Str_GetTemp();
			TCHAR	*Arg_ppCmd[10];		// limit to 9 arguments
			strcpy(buf, pszKey);
			int iQty = Str_ParseCmds(buf, Arg_ppCmd, COUNTOF(Arg_ppCmd));
			if ( iQty < 1 )
				return false;

#ifdef WIN32
			_spawnl(
				( i == SSC_SYSCMD ) ? _P_WAIT : _P_NOWAIT,
				Arg_ppCmd[0],
				Arg_ppCmd[0],
				Arg_ppCmd[1],
				Arg_ppCmd[2],
				Arg_ppCmd[3],
				Arg_ppCmd[4],
				Arg_ppCmd[5],
				Arg_ppCmd[6],
				Arg_ppCmd[7],
				Arg_ppCmd[8],
				Arg_ppCmd[9],
				NULL
			);
#else
			g_Log.EventError("sysspawn/syscmd is not available on unix builds." DEBUG_CR);
#endif
			return true;
		}

	default:
		StringFunction( i, pszKey, sVal );
		return true;
	}
	EXC_CATCH("CScriptObj");
	return false;
}
示例#7
0
bool CScript::ReadKeyParse() // Read line from script
{
	ADDTOCALLSTACK("CScript::ReadKeyParse");
	EXC_TRY("ReadKeyParse");
	EXC_SET("read");
	if ( !ReadKey(true) )
	{
		EXC_SET("init");
		InitKey();
		return false;	// end of section.
	}

	ASSERT(m_pszKey);
	GETNONWHITESPACE( m_pszKey );
	EXC_SET("parse");
	Str_Parse( m_pszKey, &m_pszArg );

	//if ( !m_pszArg[0] || m_pszArg[1] != '=' || !strchr( ".*+-/%|&!^", m_pszArg[0] ) )
	if ( !m_pszArg[0] || ( m_pszArg[1] != '=' && m_pszArg[1] != '+' && m_pszArg[1] != '-' ) || !strchr( ".*+-/%|&!^", m_pszArg[0] ) )
		return true;

	static LPCTSTR const sm_szEvalTypes[] =
	{
		"eval",
		"floatval"
	};

	EXC_SET("parse");
	LPCTSTR	pszArgs	= m_pszArg;
	pszArgs += 2;
	GETNONWHITESPACE( pszArgs );
	TemporaryString buf;

	int iKeyIndex = (strnicmp(m_pszKey, "float.", 6) == 0) ? 1 : 0;

	if ( m_pszArg[0] == '.' )
	{
		if ( *pszArgs == '"' )
		{
			TCHAR *	pQuote	= const_cast<TCHAR*>(strchr( pszArgs+1, '"' ));
			if ( pQuote )
			{
				pszArgs++;
				*pQuote	= '\0';
			}
		}
		sprintf(buf, "<%s>%s", m_pszKey, pszArgs);
	}
	else if ( m_pszArg[0] == m_pszArg[1] && m_pszArg[1] == '+' )
	{
		if ( m_pszArg[2] != '\0' )
			return true;
		sprintf(buf, "<eval (<%s> +1)>", m_pszKey);
	}
	else if ( m_pszArg[0] == m_pszArg[1] && m_pszArg[1] == '-' )
	{
		if ( m_pszArg[2] != '\0' )
			return true;
		sprintf(buf, "<eval (<%s> -1)>", m_pszKey);
	}
	else
	{
		sprintf(buf, "<%s (<%s> %c (%s))>", sm_szEvalTypes[iKeyIndex], m_pszKey, *m_pszArg, pszArgs);
	}
	strcpy(m_pszArg, buf);

	return true;
	EXC_CATCH;
	return false;
}
示例#8
0
INT64 CExpression::GetSingle( LPCTSTR & pszArgs )
{
	ADDTOCALLSTACK("CExpression::GetSingle");
	// Parse just a single expression without any operators or ranges.
	ASSERT(pszArgs);
	GETNONWHITESPACE( pszArgs );

	LPCTSTR orig = pszArgs;
	if (pszArgs[0]=='.') pszArgs++;

	if ( pszArgs[0] == '0' )	// leading '0' = hex value.
	{
		// A hex value.
		if ( pszArgs[1] == '.' )	// leading 0. means it really is decimal.
		{
			pszArgs += 2;
			goto try_dec;
		}

		LPCTSTR pStart = pszArgs;
		ULONGLONG val = 0;
		for (;;)
		{
			TCHAR ch = *pszArgs;
			if ( IsDigit( ch ))
				ch -= '0';
			else
			{
				ch = static_cast<TCHAR>(tolower(ch));
				if ( ch > 'f' || ch <'a' )
				{
					if ( ch == '.' && pStart[0] != '0' )	// ok i'm confused. it must be decimal.
					{
						pszArgs = pStart;
						goto try_dec;
					}
					break;
				}
				ch -= 'a' - 10;
			}
			val *= 0x10;
			val += ch;
			pszArgs ++;
		}
		return( (INT64)val );
	}
	else if ( pszArgs[0] == '.' || IsDigit(pszArgs[0]))
	{
		// A decminal number
try_dec:
		INT64 iVal = 0;
		for ( ; ; pszArgs++ )
		{
			if ( *pszArgs == '.' )
				continue;	// just skip this.
			if ( ! IsDigit( *pszArgs ))
				break;
			iVal *= 10;
			iVal += *pszArgs - '0';
		}
		return( iVal );
	}
	else if ( ! _ISCSYMF(pszArgs[0]))
	{
	#pragma region maths
		// some sort of math op ?

		switch ( pszArgs[0] )
		{
		case '{':
			pszArgs ++;
			return( GetRange( pszArgs ));
		case '[':
		case '(': // Parse out a sub expression.
			pszArgs ++;
			return(GetVal( pszArgs ));
		case '+':
			pszArgs++;
			break;
		case '-':
			pszArgs++;
			return( -GetSingle( pszArgs ));
		case '~':	// Bitwise not.
			pszArgs++;
			return( ~GetSingle( pszArgs ));
		case '!':	// boolean not.
			pszArgs++;
			if ( pszArgs[0] == '=' )  // odd condition such as (!=x) which is always true of course.
			{
				pszArgs++;		// so just skip it. and compare it to 0
				return( GetSingle( pszArgs ));
			}
			return( !GetSingle( pszArgs ));
		case ';':	// seperate field.
		case ',':	// seperate field.
		case '\0':
			return( 0 );
		}
#pragma endregion maths
	}
	else
	#pragma region intrinsics
	{
		// Symbol or intrinsinc function ?

		INTRINSIC_TYPE iIntrinsic = (INTRINSIC_TYPE) FindTableHeadSorted( pszArgs, sm_IntrinsicFunctions, COUNTOF(sm_IntrinsicFunctions)-1 );
		if ( iIntrinsic >= 0 )
		{
			size_t iLen = strlen(sm_IntrinsicFunctions[iIntrinsic]);
			if ( pszArgs[iLen] == '(' )
			{
				pszArgs += (iLen + 1);
				TCHAR * pszArgsNext;
				Str_Parse( const_cast<TCHAR*>(pszArgs), &(pszArgsNext), ")" );
	
				TCHAR * ppCmd[5];
				INT64 iResult;
				size_t iCount = 0;
	
				switch ( iIntrinsic )
				{
					case INTRINSIC_ID:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = RES_GET_INDEX( GetVal( pszArgs )); // RES_GET_INDEX
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_LOGARITHM:
					{
						iCount = 0;
						iResult = 0;

						if ( pszArgs && *pszArgs )
						{
							int iArgument = static_cast<long>(GetVal(pszArgs));
							if ( iArgument <= 0 )
							{
								DEBUG_ERR(( "Exp_GetVal: (x)Log(%d) is %s\n", iArgument, (!iArgument) ? "infinite" : "undefined" ));
							}
							else
							{
								iCount = 1;

								if ( strchr(pszArgs, ',') )
								{
									iCount++; SKIP_ARGSEP(pszArgs);
									if ( !strcmpi(pszArgs, "e") )
									{
										iResult = static_cast<INT64>(log(static_cast<double>(iArgument)));
									}
									else if ( !strcmpi(pszArgs, "pi") )
									{
										iResult = static_cast<INT64>(log(static_cast<double>(iArgument)) / log(M_PI));
									}
									else
									{
										INT64 iBase = GetVal(pszArgs);
										if ( iBase <= 0 )
										{
											DEBUG_ERR(( "Exp_GetVal: (%lld)Log(%d) is %s\n", iBase, iArgument, (!iBase) ? "infinite" : "undefined" ));
											iCount = 0;
										}
										else
										{
											iResult = static_cast<INT64>(log(static_cast<double>(iArgument)) / log(static_cast<double>(iBase)));
										}
									}
								}
								else
								{
									iResult = static_cast<INT64>(log10(static_cast<double>(iArgument)));
								}							
							}
						}

					} break;

					case INTRINSIC_NAPIERPOW:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(exp(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_SQRT:
					{
						iCount = 0;
						iResult = 0;

						if ( pszArgs && *pszArgs )
						{
							int iTosquare = static_cast<long>(GetVal(pszArgs));

							if (iTosquare >= 0)
							{
								iCount++;
								iResult = static_cast<INT64>(sqrt(static_cast<double>(iTosquare)));
							}
							else
							{
								DEBUG_ERR(( "Exp_GetVal: Sqrt of negative number (%d) is impossible\n", iTosquare ));
							}
						}

					} break;

					case INTRINSIC_SIN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(sin(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCSIN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(asin(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_COS:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(cos(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCCOS:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(acos(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_TAN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(tan(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCTAN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = static_cast<INT64>(atan(static_cast<double>(GetVal(pszArgs))));
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_StrIndexOf:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 3, "," );
						if ( iCount < 2 )
							iResult = -1;
						else
							iResult = Str_IndexOf(ppCmd[0],ppCmd[1],(iCount==3)?static_cast<long>(GetVal(ppCmd[2])):0);
					} break;

					case INTRINSIC_STRMATCH:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
							iResult = (Str_Match( ppCmd[0], ppCmd[1] ) == MATCH_VALID ) ? 1 : 0;
					} break;

					case INTRINSIC_STRREGEX:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
						{
							TCHAR * tLastError = Str_GetTemp();
							iResult = Str_RegExMatch( ppCmd[0], ppCmd[1], tLastError );
							if ( iResult == -1 )
							{
								DEBUG_ERR(( "STRREGEX bad function usage. Error: %s\n", tLastError ));
							}
						}
					} break;

					case INTRINSIC_RANDBELL:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
							iResult = Calc_GetBellCurve( static_cast<long>(GetVal( ppCmd[0] )), static_cast<long>(GetVal( ppCmd[1] )));
					} break;

					case INTRINSIC_STRASCII:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = pszArgs[0];
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}
					} break;

					case INTRINSIC_RAND:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 2, "," );
						if ( iCount <= 0 )
							iResult = 0;
						else
						{
							INT64 val1 = GetVal( ppCmd[0] );
							if ( iCount == 2 )
							{
								INT64 val2 = GetVal( ppCmd[1] );
								iResult = Calc_GetRandLLVal2( val1, val2 );
							}
							else
								iResult = Calc_GetRandLLVal(val1);
						}
					} break;

					case INTRINSIC_STRCMP:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 1;
						else
							iResult = strcmp(ppCmd[0], ppCmd[1]);
					} break;

					case INTRINSIC_STRCMPI:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 1;
						else
							iResult = strcmpi(ppCmd[0], ppCmd[1]);
					} break;

					case INTRINSIC_STRLEN:
					{
						iCount = 1;
						iResult = strlen(pszArgs);
					} break;

					case INTRINSIC_ISOBSCENE:
					{
						iCount = 1;
						iResult = g_Cfg.IsObscene( pszArgs );
					} break;
					case INTRINSIC_ISNUMBER:
					{
						iCount = 1;
						{
							char z[64];
							LTOA(atol(pszArgs), z, 10);
							iResult = strcmp(pszArgs, z) ? 0 : 1;
						}
					} break;

					case INTRINSIC_QVAL:
					{
						iCount = Str_ParseCmds( const_cast<TCHAR*>(pszArgs), ppCmd, 5, "," );
						if ( iCount < 3 )
							iResult = 0;
						else
						{
							INT64 a1 = GetSingle(ppCmd[0]);
							INT64 a2 = GetSingle(ppCmd[1]);
							if ( a1 < a2 ) iResult = GetSingle(ppCmd[2]);
							else if ( a1 == a2 ) iResult = ( iCount < 4 ) ? 0 : GetSingle(ppCmd[3]);
							else iResult = ( iCount < 5 ) ? 0 : GetSingle(ppCmd[4]);
						}
					} break;

					case INTRINSIC_ABS:
					{
						iCount = 1;
						iResult = llabs(GetVal(pszArgs));
					} break;

					default:
						iCount = 0;
						iResult = 0;
						break;
				}

				pszArgs = pszArgsNext;

				if ( ! iCount )
				{
					DEBUG_ERR(( "Bad intrinsic function usage: Missing arguments\n" ));
					return 0;
				}
				else
				{
					return iResult;
				}
			}
		}

		// Must be a symbol of some sort ?
		long long lVal;
		if ( m_VarGlobals.GetParseVal( pszArgs, &lVal ) )
			return(lVal);
		if ( m_VarDefs.GetParseVal( pszArgs, &lVal ) )
			return(lVal);
	}
#pragma endregion intrinsics

	// hard end ! Error of some sort.
	TCHAR szTag[ EXPRESSION_MAX_KEY_LEN ];
	size_t i = GetIdentifierString( szTag, pszArgs );
	pszArgs += i;	// skip it.
	if (strlen(orig)> 1)
		DEBUG_ERR(("Undefined symbol '%s' ['%s']\n", szTag, orig));
	else
		DEBUG_ERR(("Undefined symbol '%s'\n", szTag));
	return( 0 );
}