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; }
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; } } }
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); } }
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()); } }
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); }
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; }
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; }
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; }
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; }
const char *ADVBPatterns::GetOperatorDescription(const PATTERN& pattern, uint_t term) { const OPERATOR *oper = FindOperator(pattern, term); return oper ? oper->desc : NULL; }
const char *ADVBPatterns::GetOperatorText(const PATTERN& pattern, uint_t term) { const OPERATOR *oper = FindOperator(pattern, term); return oper ? oper->str : NULL; }