// include a start-tag in to the QSgml-class void QSgml::HandleStartTag(const QString &SgmlString,QSgmlTag* &pLastTag,int &iStart,int &iEnd,int &iPos) { QString sDummy; QSgmlTag *pTag; iStart = iPos; FindEnd(SgmlString,iPos); iEnd = iPos; sDummy = SgmlString.mid(iStart + 1,iEnd - iStart - 1).trimmed(); if( SgmlString.at(iEnd - 1)=='/' ) { // this is a standalone-tag sDummy = sDummy.left( sDummy.count() - 1 ); pTag = new QSgmlTag(sDummy,QSgmlTag::eStandalone,pLastTag); pTag->StartTagPos = iStart; pTag->StartTagLength = iEnd - iStart + 1; pTag->EndTagPos = iStart; pTag->EndTagLength = iEnd - iStart + 1; pLastTag->Children.append( pTag ); } else { // this is a start-tag pTag = new QSgmlTag(sDummy,QSgmlTag::eStartTag,pLastTag); pTag->StartTagPos = iStart; pTag->StartTagLength = iEnd - iStart + 1; pTag->EndTagPos = iStart; pTag->EndTagLength = iEnd - iStart + 1; pLastTag->Children.append( pTag ); pLastTag = pTag; } }
void CPlainTextEditor::SelectEnd(void) { BeginSelection(); miEditPos = FindEnd(miEditPos); EndSelection(); ResetUpDown(); }
/** Check if one of the parameters pointed to by Iter contains Elem. * \param Iter: Iterator to function to check. * \param Elem: The element to search for. */ bool ContainsElem(std::vector<TElem>::const_iterator Iter, const TElem &Elem) { std::vector<TElem>::const_iterator End = FindEnd(Iter); for(;Iter < End; ++Iter) if(*Iter == Elem) return true; return false; }
/** Returns an iterator to the element following Iter. Jumps over parameters. * \param Iter: Iterator to find next element for. */ std::vector<TElem>::const_iterator FindEnd(std::vector<TElem>::const_iterator Iter) { unsigned Arguments = FunctionArguments(*Iter); ++Iter; for(unsigned I = 0; I < Arguments; I++) Iter = FindEnd(Iter); return Iter; }
/** Copy another function into List and replaces all arguments that matches Elem * with the elements in the range [First;Last[ * This is used as part of differentiation. * \param List: Data vector to copy elements into. * \param Iter: Points to the first part of the function to copy. * \param Elem: The element to look for. * \param First: Start of the range to replace Elem with. * \param Last: One after the last element top replace Elem with. */ void TFuncData::CopyReplace(std::vector<TElem> &List, TConstIterator Iter, const TElem &Elem, TConstIterator First, TConstIterator Last) { // DEBUG_LOG(std::wclog << L"CopyReplace: " << MakeText(Iter)); // DEBUG_LOG(for(unsigned I = 0; I < Args.size(); I++) std::wclog << L"; Arg" << I << L"=" << MakeText(Args[I].begin())); // DEBUG_LOG(std::wclog << std::endl); TConstIterator End = FindEnd(Iter); for(; Iter != End; ++Iter) if(*Iter == Elem) { List.insert(List.end(), First, Last); } else List.push_back(*Iter); }
// include a endtag in to the QSgml-class void QSgml::HandleEndTag(const QString &SgmlString,QSgmlTag* &pLastTag,int &iStart,int &iEnd,int &iPos) { QString sDummy; QSgmlTag *pTag; QSgmlTag *pDummyTag; iStart = iPos; FindEnd(SgmlString,iPos); iEnd = iPos; sDummy = SgmlString.mid(iStart + 1,iEnd - iStart - 1).trimmed(); pTag = new QSgmlTag(sDummy,QSgmlTag::eEndTag,pLastTag); // find a fitting start-tag pDummyTag = pLastTag; while( (pDummyTag->Name!=pTag->Name)&&(pDummyTag->Parent!=NULL) ) pDummyTag = pDummyTag->Parent; delete pTag; if( pDummyTag->Parent!=NULL ) // start-tag found { while( pLastTag!=pDummyTag ) // all tags in between are standalone tags { pLastTag->Type = QSgmlTag::eStandalone; MoveChildren( pLastTag,pLastTag->Parent ); pLastTag = pLastTag->Parent; } // set data in start-tag pLastTag->EndTagPos = iStart; pLastTag->EndTagLength = iEnd - iStart + 1; // tags which have no children are special (script can't be a standalone-tag) if( pLastTag->Children.count()==0 ) { pLastTag->Type = QSgmlTag::eStartEmpty; } pLastTag = pLastTag->Parent; } else { // no start-tag -> end pLastTag->Children.append( EndTag ); iPos = -1; } }
// include a doctype in to the QSgml-class void QSgml::HandleDoctype(const QString &SgmlString,QSgmlTag* &pLastTag,int &iStart,int &iEnd,int &iPos) { QString sDummy; QSgmlTag *pTag; iStart = iPos; FindEnd(SgmlString,iPos); iEnd = iPos; sDummy = SgmlString.mid(iStart + 2,iEnd - iStart - 2).trimmed(); pTag = new QSgmlTag(sDummy,QSgmlTag::eDoctype,pLastTag); pTag->StartTagPos = iStart; pTag->StartTagLength = iEnd - iStart + 1; pTag->EndTagPos = iStart; pTag->EndTagLength = iEnd - iStart + 1; pLastTag->Children.append( pTag ); }
void CPlainTextEditor::End(void) { ClearSelection(); miEditPos = FindEnd(miEditPos); ResetUpDown(); }
// Finding word bounds (what'll be converted) (Str is in OEM) BOOL FindBounds(TCHAR *Str, int Len, int Pos, int &Start, int &End) { int i=1; BOOL ret = FALSE; // If line isn't empty if( Len>Start ) { End=std::min(End,Len); // Pos between [Start, End] ? Pos=std::max(Pos,Start); Pos=std::min(End,Pos); // If current character is non letter if(!MyIsAlpha(Str[Pos])) { // Looking for letter on the left and counting radius while((Start<=Pos-i) && (!MyIsAlpha(Str[Pos-i]))) i++; // Radius int r=MAXINT; // Letter was found on the left if(Start<=Pos-i) r=i; // Storing radius i=1; // Looking for letter on the right and counting radius while((Pos+i<=End) && (!MyIsAlpha(Str[Pos+i]))) i++; // Letter was not found if(Pos+i>End) i=MAXINT; // Here r is left radius and i is right radius // If no letters was found if( std::min(r,i)!=MAXINT ) { // What radius is less? Left? if( r <= i ) { End=Pos-r+1; Start=FindStart(Str, Start, End); } else // Right! { Start=Pos+i; End=FindEnd(Str, Start, End); }; ret=TRUE; }; } else // Current character is letter! { Start=FindStart(Str, Start, Pos); End=FindEnd(Str, Pos, End); ret=TRUE; }; }; if(!ret) Start=End=-1; return ret; };
TInt CRfsScript::ParseNextCommandL( CRfsCommand* aCommand ) { const TDesC* commands[ KRfsNumberOfCommands ] = { &KRfsCommand1, &KRfsCommand2, &KRfsCommand3, &KRfsCommand4, &KRfsCommand5, &KRfsCommand6, &KRfsCommand7, &KRfsCommand8 }; TInt startIndex; TInt endIndex; FOREVER { // check if index is beyond the descriptor already if ( iIndex >= iLength ) { return KRfsEndOfScript; } // go to the beginning of the "command word" startIndex = iIndex; SkipSpace( startIndex ); // go to the end of the "command word" endIndex = startIndex; FindEnd( endIndex ); if ( endIndex - startIndex > 0 && !IsComment( startIndex ) ) { break; } // if the line is commented out, skip it iIndex = NextLine( startIndex ); } // create TPtrC to the "command word" TPtrC command( &iScript[ startIndex ], endIndex - startIndex ); TRfsCommandId commandId( ERfsCommandUnknown ); // determine the command id for ( TInt i = 0; i < KRfsNumberOfCommands ; i++ ) { if ( !command.CompareF( *( commands[ i ] ) ) ) { commandId = (TRfsCommandId)i; break; } } TInt ret( KErrGeneral ); // returns this if there is a syntax error in line if ( commandId != ERfsCommandUnknown ) { TInt numberOfParams( 0 ); TInt start = endIndex; FOREVER { TBool quotes( EFalse ); SkipSpace( start, "es ); TInt end = start; if ( FindEnd( end, quotes ) ) { if ( end - start > 0 && !IsComment( start) ) { numberOfParams++; start = end; continue; } } break; } if ( VerifyNumberOfParameters( commandId, numberOfParams ) ) { // set command information if the command parameter has been given if ( aCommand ) { TPtrC* params = new( ELeave ) TPtrC[ numberOfParams ]; // fetch parameter information for ( TInt i = 0; i < numberOfParams ; i++ ) { TInt paramStart = endIndex; TBool quotes( EFalse ); SkipSpace( paramStart, "es ); TInt paramEnd = paramStart; FindEnd( paramEnd, quotes ); TInt realStart( paramStart ); TInt realEnd( paramEnd ); if ( quotes ) { realStart++; realEnd--; } params[ i ].Set( &iScript[ realStart ], realEnd - realStart ); endIndex = paramEnd; } // aCommand gets ownership of paramStarts and paramLengths aCommand->Set( commandId, numberOfParams, params ); } iIndex = NextLine ( endIndex ); ret = KErrNone; } }
/** Saves the first derivative of the sequence starting at Iter in the back *this * \param Iter: Iterator to function to differentiate. * \param Var: Variable to differentiate with respect to. * \param Trigonemetry: Differentiate trigonometric functions as radians og degrees. * \param Level: Indicates the number os times the function has been called recursive. To prevent infinite loops. * \throw EFuncError: Thrown if differentiation fails. */ void TFuncData::AddDif(TConstIterator Iter, const TElem &Var, TTrigonometry Trigonometry, unsigned Level) { if(*Iter == Var) Data.push_back(TElem(CodeNumber, 1)); else if(Iter->Ident == CodeRand) throw EFuncError(ecNotDifAble, L"rand"); else if(IsConstant(*Iter)) Data.push_back(TElem(CodeNumber, 0.0)); else { if(!ContainsElem(Iter, Var)) { Data.push_back(TElem(CodeNumber, 0.0)); return; } switch(Iter->Ident) { case CodeIf: case CodeIfSeq: { //f(x)=if(a1,b1,a2,b2, ... , an,bn [,c]) //f'(x)=if(a1,b1',a2,b2', ... , an, bn' [,c']) Data.push_back(*Iter); //CodeIf with same number of arguments unsigned Arguments = FunctionArguments(*Iter); ++Iter; for(unsigned I = 0; I < Arguments-1; I++) { TConstIterator End = FindEnd(Iter); if(I % 2) AddDif(Iter, Var, Trigonometry, Level); else Data.insert(Data.end(), Iter, End); Iter = End; } AddDif(Iter, Var, Trigonometry, Level); break; } case CodeMin: case CodeMax: { //f(x)=min(a1,a2,a3, ... , an) f'(x)=if(a1<a2 and a1<a3 ...,a1', a2<a1 and a2<a3 ...,a2', unsigned Arguments = Iter->Arguments; Data.push_back(TElem(CodeIf, 2*Arguments-1, 0)); TConstIterator Param = Iter + 1; for(unsigned I = 0; I < Arguments-1; I++) { TConstIterator End = FindEnd(Param); for(unsigned J = 0; J < Arguments-2; J++) Data.push_back(CodeAnd); TConstIterator Param2 = Iter+1; for(unsigned J = 0; J < Arguments; J++) { if(J != I) { Data.push_back(TElem(Iter->Ident == CodeMin ? cmLess : cmGreater)); Data.insert(Data.end(), Param, End); Data.insert(Data.end(), Param2, FindEnd(Param2)); } Param2 = FindEnd(Param2); } AddDif(Param, Var, Trigonometry, Level); Param = End; } AddDif(Param, Var, Trigonometry, Level); break; } case CodeCustom: { if(Level > MaxDifLevel) throw EFuncError(ecRecursiveDif); boost::shared_ptr<TBaseCustomFunc> Func = boost::any_cast<boost::shared_ptr<TBaseCustomFunc> >(Iter->Value); if(Func) AddDif(Func->GetFuncData()->Data.begin(), Var, Trigonometry, Level + 1); else throw EFuncError(ecSymbolNotFound, Iter->Text); break; } case CodeDNorm: { std::vector<std::wstring> ArgNames; ArgNames.push_back(L"x"); ArgNames.push_back(L"x2"); ArgNames.push_back(L"x3"); TFuncData Temp(FunctionDefinition(CodeDNorm), ArgNames); TFuncData Temp2; std::vector<std::vector<TElem> > Args(3); CopyReplaceArgs(Args.front(), Iter + 1, std::vector<std::vector<TElem> >()); if(Iter->Arguments > 2) { TConstIterator Iter2 = FindEnd(Iter + 1); CopyReplaceArgs(Args[1], Iter2, std::vector<std::vector<TElem> >()); CopyReplaceArgs(Args[2], FindEnd(Iter2), std::vector<std::vector<TElem> >()); } else { Args[1].push_back(TElem(CodeNumber, 0.0)); Args[2].push_back(TElem(CodeNumber, 1.0)); } CopyReplaceArgs(Temp2.Data, Temp.Data.begin(), Args); AddDif(Temp2.Data.begin(), Var, Trigonometry, Level + 1); break; } case CodeMod: if(ContainsElem(FindEnd(Iter+1), Var)) throw EFuncError(ecNotDifAble, FunctionName(CodeMod)); AddDif(Iter+1, Var, Trigonometry, Level + 1); break; default: { if(Trigonometry == Degree) { //Sin, Cos, Tan, Csc, Sec, Cot must be multiplied with PI/180 when differentiated using degrees if((Iter->Ident >= CodeSin && Iter->Ident <= CodeTan) || (Iter->Ident >= CodeCsc && Iter->Ident <= CodeCot)) { Data.push_back(CodeMul); Data.push_back(CodeDiv); Data.push_back(CodePi); Data.push_back(180); } //ASin, ACos, ATan, ACsc, ASec, ACot must be multiplied with 180/PI when differentiated using degrees else if((Iter->Ident >= CodeASin && Iter->Ident <= CodeATan) || (Iter->Ident >= CodeACsc && Iter->Ident <= CodeACot)) { Data.push_back(CodeMul); Data.push_back(CodeDiv); Data.push_back(180); Data.push_back(CodePi); } } const TFuncData &DifData = GetDif(Iter->Ident); if(Iter->Ident == CodeIntegrate) { //f(x)=integrate(g(x,s), s, a(x), b(x)) //f'(x)=g(x,b(x))*db(x)/dx - g(x,a(x))*da(x)/dx + integrate(dg(x,s)/dx, s, a(x), b(x)) TConstIterator From = FindEnd(Iter + 1); TConstIterator To = FindEnd(From); TConstIterator End = FindEnd(To); TElem Elem = *Iter; Elem.Ident = CodeConst; if(!Iter->Text.empty()) Data.push_back(CodeAdd); Data.push_back(CodeSub); Data.push_back(CodeMul); CopyReplace(Data, Iter + 1, Elem, To, End); AddDif(To, Var, Trigonometry, Level); Data.push_back(CodeMul); CopyReplace(Data, Iter + 1, Elem, From, To); AddDif(From, Var, Trigonometry, Level); if(!Iter->Text.empty()) { //Backward compatibility: //f(x)=integrate(g(x), a(x), b(x)) //f'(x)=g(x,b(x))*db(x)/dx - g(x,a(x))*da(x)/dx Data.push_back(*Iter); AddDif(Iter + 1, Var, Trigonometry, Level); Data.insert(Data.end(), From, End); } } else if(DifData.IsEmpty()) throw EFuncError(ecNotDifAble, FunctionName(*Iter)); TConstIterator End = DifData.Data.end(); TConstIterator FirstPar = Iter; //Start of first parenthesis ++FirstPar; TConstIterator SecondPar = FindEnd(FirstPar); //Start of second parenthesis TConstIterator ThirdPar; if(FunctionArguments(*Iter) >= 2) ThirdPar = FindEnd(SecondPar); //Start of third parenthesis TConstIterator Begin = DifData.Data.begin(); if(Iter->Ident == CodeSum) //Use the original CodeSum instead of the one from DifData { Data.push_back(*Iter); Begin++; } for(TConstIterator Elem = Begin; Elem != End; ++Elem) if(Elem->Ident == CodeArgument) Data.insert(Data.end(), FirstPar, SecondPar); else if(*Elem == TElem(CodeCustom, L"dx")) AddDif(FirstPar, Var, Trigonometry, Level); else if(*Elem == TElem(CodeCustom, L"x2")) Data.insert(Data.end(), SecondPar, ThirdPar); else if(*Elem == TElem(CodeCustom, L"dx2")) AddDif(SecondPar, Var, Trigonometry, Level); else if(*Elem == TElem(CodeCustom, L"x3")) Data.insert(Data.end(), ThirdPar, FindEnd(ThirdPar)); else if(*Elem == TElem(CodeCustom, L"dx3")) AddDif(ThirdPar, Var, Trigonometry, Level); else Data.push_back(*Elem); } } } }