Beispiel #1
0
bool FParser::spec_if()
{
	int endtoken;
	svalue_t eval;
	
	
	if((endtoken = FindOperator(0, NumTokens-1, ")")) == -1)
    {
		script_error("parse error in if statement\n");
		return false;
    }
	
	// 2 to skip past the 'if' and '('
	EvaluateExpression(eval, 2, endtoken-1);
	bool ifresult = !!intvalue(eval);
	
	if(Section && BraceType == bracket_open && endtoken == NumTokens-1)
    {
		// {} braces
		if(!ifresult)       // skip to end of section
			Rover = Script->SectionEnd(Section) + 1;
    }
	else if(ifresult) // if() without {} braces
	{
		// nothing to do ?
		if(endtoken != NumTokens-1)
			EvaluateExpression(eval, endtoken+1, NumTokens-1);
	}
	
	return ifresult;
}
Beispiel #2
0
 void ParseSymbols()
 {
     StartToken();
     
     switch (Previous())
     {
         case '/':
             if (Current() == '/')
             {
                 ParseLineComment();
                 break;
             }
             else if (Current() == '*')
             {
                 ParseBlockComment();
                 break;
             }
             
             // Yes. No break. This is deliberate.
             
         default:
         {
             String4 tinySource = {};
             tinySource.Append(Previous());
             lastSourceToken.tokenType = TokenType::Reserved;
             lastSourceToken.tokenIndex = FindOperator(tinySource);
             
             for (int i = index; i < length && IsSymbol(source[i]); ++i)
             {
                 tinySource.Append(source[i]);
                 auto tokenIndex = FindOperator(tinySource);
                 
                 if (tokenIndex != -1)
                 {
                     lastSourceToken.tokenIndex = tokenIndex;
                     lastSourceToken.length = i - index + 2;
                 }
             }
             
             int offset = lastSourceToken.length - 1;
             index += offset;
             position.column += offset;
             
             break;
         }
     }
 }
Beispiel #3
0
void FParser::spec_for()
{
	svalue_t eval;
	int start;
	int comma1, comma2;     // token numbers of the seperating commas
	
	if(!Section)
    {
		script_error("need {} delimiters for for()\n");
		return;
    }
	
	// is a valid section
	
	start = 2;     // skip "for" and "(": start on third token(2)
	
	// find the seperating commas first
	
	if( (comma1 = FindOperator(start, NumTokens-1, ",")) == -1
		|| (comma2 = FindOperator(comma1+1, NumTokens-1, ",")) == -1)
    {
		script_error("incorrect arguments to for()\n");  // haleyjd:
		return;                                          // said if()
    }
	
	// are we looping back from a previous loop?
	if(Section == PrevSection)
    {
		// do the loop 'action' (third argument)
		EvaluateExpression(eval, comma2+1, NumTokens-2);
		
		// check if we should run the loop again (second argument)
		EvaluateExpression(eval, comma1+1, comma2-1);
		if(!intvalue(eval))
		{
			// stop looping
			Rover = Script->SectionEnd(Section) + 1;
		}
    }
	else
    {
		// first time: starting the loop
		// just evaluate the starting expression (first arg)
		EvaluateExpression(eval, start, comma1-1);
    }
}
Beispiel #4
0
void FParser::EvaluateExpression(svalue_t &result, int start, int stop)
{
	int i, n;
	
	// possible pointless brackets
	if(TokenType[start] == operator_ && TokenType[stop] == operator_)
		PointlessBrackets(&start, &stop);

	if(start == stop)       // only 1 thing to evaluate
    {
		SimpleEvaluate(result, start);
		return;
    }
	
	// go through each operator in order of precedence
	for(i=0; i<num_operators; i++)
    {
		// check backwards for the token. it has to be
		// done backwards for left-to-right reading: eg so
		// 5-3-2 is (5-3)-2 not 5-(3-2)
		
		if (operators[i].direction==forward)
		{
			n = FindOperatorBackwards(start, stop, operators[i].string);
		}
		else
		{
			n = FindOperator(start, stop, operators[i].string);
		}

		if( n != -1)
		{
			// call the operator function and evaluate this chunk of tokens
			(this->*operators[i].handler)(result, start, n, stop);
			return;
		}
    }
	
	if(TokenType[start] == function)
	{
		EvaluateFunction(result, start, stop);
		return;
	}
	
	// error ?
	{        
		FString tempstr;
		
		for(i=start; i<=stop; i++) tempstr << Tokens[i] << ' ';
		script_error("couldnt evaluate expression: %s\n",tempstr.GetChars());
	}
}
Beispiel #5
0
void FParser::ParseVarLine(int newvar_type, DFsScript *newvar_script, int start)
{
	int starttoken = start, endtoken;
	
	while(1)
    {
		endtoken = FindOperator(starttoken, NumTokens-1, ",");
		if(endtoken == -1) break;
		CreateVariable(newvar_type, newvar_script, starttoken, endtoken-1);
		starttoken = endtoken+1;  //start next after end of this one
    }
	// dont forget the last one
	CreateVariable(newvar_type, newvar_script, starttoken, NumTokens-1);
}
Beispiel #6
0
void FParser::spec_while()
{
	int endtoken;
	svalue_t eval;
	
	if(!Section)
    {
		script_error("no {} section given for loop\n");
		return;
    }
	
	if( (endtoken = FindOperator(0, NumTokens-1, ")")) == -1)
    {
		script_error("parse error in loop statement\n");
		return;
    }
	
	EvaluateExpression(eval, 2, endtoken-1);
	
	// skip if no longer valid
	if(!intvalue(eval)) Rover = Script->SectionEnd(Section) + 1;
}
nsresult nsEudoraFilters::AddTerm(const char* pHeader, const char* pVerb, const char* pValue, bool booleanAnd, bool negateVerb)
{
  nsresult rv;

  nsMsgSearchAttribValue attrib = FindHeader(pHeader);
  nsMsgSearchOpValue     op = FindOperator(pVerb);
  nsAutoCString          arbitraryHeader;
  nsAutoString           unicodeHeader, unicodeVerb, unicodeValue;
  nsAutoString           filterTitle;

  NS_CopyNativeToUnicode(nsCString(pHeader), unicodeHeader);
  NS_CopyNativeToUnicode(nsCString(pVerb), unicodeVerb);
  NS_CopyNativeToUnicode(nsCString(pValue), unicodeValue);

  filterTitle = NS_LITERAL_STRING("- ");
  filterTitle += unicodeHeader;
  filterTitle += NS_LITERAL_STRING(" ");
  filterTitle += unicodeVerb;
  filterTitle += NS_LITERAL_STRING(" ");
  filterTitle += unicodeValue;
  filterTitle += NS_LITERAL_STRING(": ");

  if (op < 0)
  {
    m_errorLog += filterTitle;
    m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_VERB, pVerb);
    m_errorLog += NS_LITERAL_STRING("\n");
    return NS_ERROR_INVALID_ARG;
  }

  if (!pHeader || !*pHeader)
  {
    m_errorLog += filterTitle;
    m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_EMPTY_HEADER);
    m_errorLog += NS_LITERAL_STRING("\n");
    return NS_ERROR_INVALID_ARG;
  }

  if (negateVerb)
  {
    switch (op)
    {
      case nsMsgSearchOp::Contains:
      case nsMsgSearchOp::Is:
      case nsMsgSearchOp::IsInAB:
        op++;
        break;
      case nsMsgSearchOp::DoesntContain:
      case nsMsgSearchOp::Isnt:
      case nsMsgSearchOp::IsntInAB:
        op--;
        break;
      default:
        m_errorLog += filterTitle;
        m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_NEGATE_VERB, unicodeVerb.get());
        m_errorLog += NS_LITERAL_STRING("\n");
        return NS_ERROR_INVALID_ARG;
    }
  }

  if (attrib < 0)
  {
    // Can't handle other Eudora meta-headers (Any Header, Personality, Junk Score)
    if (*pHeader == *LDAQ)
    {
      m_errorLog += filterTitle;
      m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_META_HEADER, unicodeHeader.get());
      m_errorLog += NS_LITERAL_STRING("\n");
      return NS_ERROR_INVALID_ARG;
    }

    // Arbitrary headers for filters don't like the colon at the end
    arbitraryHeader = pHeader;
    int32_t index = arbitraryHeader.FindChar(':');
    if (index >= 0)
      arbitraryHeader.SetLength(index);

    int32_t headerIndex = AddCustomHeader(arbitraryHeader.get());
    NS_ENSURE_TRUE(headerIndex >= 0, NS_ERROR_FAILURE);

    attrib = nsMsgSearchAttrib::OtherHeader + 1 + headerIndex;
  }

  uint32_t numFilters;
  rv = m_pFilterArray->GetLength(&numFilters);
  NS_ENSURE_SUCCESS(rv, rv);
  for (uint32_t filterIndex = 0; filterIndex < numFilters; filterIndex++)
  {
    nsCOMPtr<nsIMsgFilter> filter = do_QueryElementAt(m_pFilterArray, filterIndex, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsISupportsArray> terms;
    rv = filter->GetSearchTerms(getter_AddRefs(terms));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIMsgSearchTerm> term;
    if (booleanAnd)
    {
      term = do_QueryElementAt(terms, 0, &rv);
      if (NS_SUCCEEDED(rv) && term)
      {
        term->SetBooleanAnd(true);
        term = nullptr;
      }
    }

    rv = filter->CreateTerm(getter_AddRefs(term));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIMsgSearchValue> value;
    rv = term->GetValue(getter_AddRefs(value));
    NS_ENSURE_SUCCESS(rv, rv);

    value->SetAttrib(attrib);
    value->SetStr(unicodeValue);
    term->SetAttrib(attrib);
    term->SetOp(op);
    term->SetBooleanAnd(booleanAnd);
    if (!arbitraryHeader.IsEmpty())
      term->SetArbitraryHeader(arbitraryHeader);
    term->SetValue(value);
    filter->AppendTerm(term);
  }

  return NS_OK;
}
Beispiel #8
0
GridTheme* GridThemeParser::ParseThemeColorRule(const MdfModel::GridColorRule *pRule)
{
    GridTheme *pTheme = NULL;
    GridBucket *pBucket = NULL;

    MdfModel::MdfString sLeftType;
    MdfModel::MdfString sLeftBandName;
    MdfModel::MdfString sLeftOperator;
    double              dLeftValue = GridBucket::sm_MinDouble;

    MdfModel::MdfString sRightType;
    MdfModel::MdfString sRightBandName;
    MdfModel::MdfString sRightOperator;
    double              dRightValue = GridBucket::sm_MaxDouble;

    // Clear all the stacks.
    m_typeBracketStack.clear();
    m_bandNameBracketStack.clear();
    m_valueBracketStack.clear();

    try
    {
        const MdfModel::MdfString &filter = pRule->GetFilter();
        bool bTwo = false;
        size_t i = 0;
        //size_t nLength = filter.length();

        i = FindType(sLeftType, filter, i);
        i = FindBandName(sLeftBandName, filter, i);
        i = FindOperator(sLeftOperator, filter, i);
        i = FindValue(dLeftValue, filter, i);

        try
        {
            i = Find(L"And", filter, i);
            bTwo = true;
            i = FindType(sRightType, filter, i);
            i = FindBandName(sRightBandName, filter, i);
            i = FindOperator(sRightOperator, filter, i);
            i = FindValue(dRightValue, filter, i);
        }
        catch (std::exception &)
        {
            // Only one filter.
            bTwo = false;
        }

        if (bTwo)
        {
            // TODO: Perform case insenstive compare, and verify on Linux
            if (_wcsicmp(sLeftType.c_str(), sRightType.c_str()) != 0
                || _wcsicmp(sLeftBandName.c_str(), sRightBandName.c_str()) != 0)
            {
                // Unmatch Type or Band Name
                throw std::exception();
            }
        }

        pTheme  = new GridTheme;
        pBucket = new GridBucket;
        pTheme->SetBandName(sLeftBandName);
        pTheme->SetType(sLeftType);

        // Make sure the color is a kind of GridColorExplicit.
        const MdfModel::GridColorExplicit *pColorExplicit = dynamic_cast<const MdfModel::GridColorExplicit*>(pRule->GetGridColor());
        if (NULL == pColorExplicit) // Not theme style
        {
            // Wrong Color Type
            throw std::exception();
        }
        std::wstringstream ss(pColorExplicit->GetExplicitColor());
        Color color;
        ss >> color;
        if (!ss)
        {
            // Wrong Color Value
            throw std::exception();
        }
        pBucket->SetColor(color);

        if (!bTwo)
        {
            if (sLeftOperator == L"<")
            {
                pBucket->SetRange(GridBucket::sm_MinDouble, false, dLeftValue, false);
            }
            else if (sLeftOperator == L"<=")
            {
                pBucket->SetRange(GridBucket::sm_MinDouble, false, dLeftValue, true);
            }
            else if (sLeftOperator == L">")
            {
                pBucket->SetRange(dLeftValue, false, GridBucket::sm_MaxDouble, false);
            }
            else if (sLeftOperator == L">=")
            {
                pBucket->SetRange(dLeftValue, true, GridBucket::sm_MaxDouble, false);
            }
            else if (sLeftOperator == L"=")
            {
                pBucket->SetRange(dLeftValue, true, dLeftValue, true);
            }
            else
            {
                // Wrong Operator
                throw std::exception();
            }
        }
        else
        {
            int nCompResult = CompareDoubles(dLeftValue, dRightValue);
            if (nCompResult == 0)  // left == right
            {
                if ((sLeftOperator == L"<=" && sRightOperator == L">=")
                    || (sLeftOperator == L">=" && sRightOperator == L"<="))
                {
                    pBucket->SetRange(dLeftValue, true, dLeftValue, true);
                }
                else
                {
                    // Wrong operator
                    throw std::exception();
                }
            }
            else if (nCompResult < 0) // left < right
            {
                if ((sLeftOperator == L">" || sLeftOperator == L">=")
                    &&(sRightOperator == L"<" || sRightOperator == L"<="))
                {
                    pBucket->SetRange(dLeftValue, sLeftOperator == L">=", dRightValue, sRightOperator == L"<=");
                }
                else
                {
                    // Wrong operator
                    throw std::exception();
                }
            }
            else if (nCompResult > 0) // left > right
            {
                if ((sLeftOperator == L"<" || sLeftOperator == L"<=")
                    &&(sRightOperator == L">" || sRightOperator == L">="))
                {
                    pBucket->SetRange(dRightValue, sRightOperator == L">=", dLeftValue, sLeftOperator == L"<=");
                }
                else
                {
                    // Wrong operator
                    throw std::exception();
                }
            }
        }
        if (!pTheme->AdoptBucket(pBucket))
        {
            // Faild to Adopt Bucket
            throw std::exception();
        }
    }
    catch (std::exception &)
    {
        delete pTheme;
        pTheme = NULL;

        delete pBucket;
        pBucket = NULL;
    }
    return pTheme;
}
Beispiel #9
0
void FParser::OPstructure(svalue_t &result, int start, int n, int stop)
{
	DFsVariable *func = NULL;
	
	// the arguments need to be built locally in case of
	// function returns as function arguments eg
	// print("here is a random number: ", rnd() );
	
	int argc;
	svalue_t argv[MAXARGS];
	
	// all the functions are stored in the global script
	if( !(func = Level->FraggleScriptThinker->GlobalScript->VariableForName (Tokens[n+1]))  )
	{
		script_error("no such function: '%s'\n",Tokens[n+1]);
	}
	
	else if(func->type != svt_function)
	{
		script_error("'%s' not a function\n", Tokens[n+1]);
	}
	
	// build the argument list
	
	// add the left part as first arg
	
	EvaluateExpression(argv[0], start, n-1);
	argc = 1; // start on second argv
	
	if(stop != n+1)         // can be a.b not a.b()
    {
		int startpoint, endpoint;
		
		// ignore the function name and first bracket
		endpoint = n + 3;
		
		while(endpoint < stop)
		{
			startpoint = endpoint;
			endpoint = FindOperator(startpoint, stop-1, ",");
			
			// check for -1: no more ','s 
			if(endpoint == -1)
			{               // evaluate the last expression
				endpoint = stop;
			}
			if(endpoint-1 < startpoint)
				break;
			
			EvaluateExpression(argv[argc], startpoint, endpoint-1);
			endpoint++;    // skip the ','
			argc++;
		}
    }
	
	// store the arguments in the global arglist
	t_argc = argc;
	t_argv = argv;
	t_func = func->Name;
	
	// haleyjd: return values can propagate to void functions, so
	// t_return needs to be cleared now
	
	t_return.type = svt_int;
	t_return.value.i = 0;
	
	// now run the function
	(this->*func->value.handler)();
	
	// return the returned value
	result = t_return;
}
Beispiel #10
0
void FParser::EvaluateFunction(svalue_t &result, int start, int stop)
{
	DFsVariable *func = NULL;
	int startpoint, endpoint;
	
	// the arguments need to be built locally in case of
	// function returns as function arguments eg
	// print("here is a random number: ", rnd() );
	
	int argc;
	svalue_t argv[MAXARGS];
	
	if(TokenType[start] != function || TokenType[stop] != operator_
		|| Tokens[stop][0] != ')' )
	{
		script_error("misplaced closing paren\n");
	}
	
	// all the functions are stored in the global script
	else if( !(func = Level->FraggleScriptThinker->GlobalScript->VariableForName (Tokens[start]))  )
	{
		script_error("no such function: '%s'\n",Tokens[start]);
	}
	
	else if(func->type != svt_function && func->type != svt_linespec)
	{
		script_error("'%s' not a function\n", Tokens[start]);
	}
	
	// build the argument list
	// use a C command-line style system rather than
	// a system using a fixed length list
	
	argc = 0;
	endpoint = start + 2;   // ignore the function name and first bracket
	
	while(endpoint < stop)
    {
		startpoint = endpoint;
		endpoint = FindOperator(startpoint, stop-1, ",");
		
		// check for -1: no more ','s 
		if(endpoint == -1)
		{               // evaluate the last expression
			endpoint = stop;
		}
		if(endpoint-1 < startpoint)
			break;
		
		EvaluateExpression(argv[argc], startpoint, endpoint-1);
		endpoint++;    // skip the ','
		argc++;
    }
	
	// store the arguments in the global arglist
	t_argc = argc;
	t_argv = argv;
	
	// haleyjd: return values can propagate to void functions, so
	// t_return needs to be cleared now
	
	t_return.type = svt_int;
	t_return.value.i = 0;
	
	// now run the function
	if (func->type == svt_function)
	{
		(this->*func->value.handler)();
	}
	else
	{
		RunLineSpecial(func->value.ls);
	}
	
	// return the returned value
	result = t_return;
}
Beispiel #11
0
const char *ADVBPatterns::GetOperatorDescription(const PATTERN& pattern, uint_t term)
{
	const OPERATOR *oper = FindOperator(pattern, term);

	return oper ? oper->desc : NULL;
}
Beispiel #12
0
const char *ADVBPatterns::GetOperatorText(const PATTERN& pattern, uint_t term)
{
	const OPERATOR *oper = FindOperator(pattern, term);

	return oper ? oper->str : NULL;
}