Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Jonas Raoni Soares Silva http://jsfromhell.com

« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS 

Fast Sequential Search/Replace Engine supporting wildcards, backward search, whole words, etc... //Pascal Class

A quite fast unit to search/replace strings sequentially (while Seeker.Search() do...) in files/strings done mostly with pointers to improve speed. It's able to search backward, count end of lines, check case-sensitiveness, match whole words and handle wildcards (* and ?),

The search method was divided into 4 specialized methods, again to improve speed. The right method is choosed according to the options that were setted (wildcard, search backward, etc...)

This is an old code that doesn't match my current skills, anyway it has some cool techniques that I really enjoyed :)

   1  
   2  //
   3  //    TNotesSeeker - classe de buscas do Notes.
   4  //
   5  //    Notes, http://notes.codigolivre.org.br
   6  //    Copyright (C) 2003-2004, Equipe do Notes.
   7  //
   8  //    This program is free software; you can redistribute it and/or modify
   9  //    it under the terms of the GNU General Public License as published by
  10  //    the Free Software Foundation; either version 2 of the License, or
  11  //    (at your option) any later version.
  12  //
  13  //    This program is distributed in the hope that it will be useful,
  14  //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16  //    GNU General Public License for more details.
  17  //
  18  //    You should have received a copy of the GNU General Public License
  19  //    along with this program; if not, write to the Free Software
  20  //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21  //
  22  //    **************************************************************
  23  //    Revision #0
  24  //      Version  : 1.0.0
  25  //      Date     : 2003-11-30 22:00:00 GMT -3:00
  26  //      Reviewer : Jonas Raoni Soares Silva
  27  //      Changes  : Criada a classe.
  28  //    **************************************************************
  29  //    Revision #1
  30  //      Version  : 1.0.1
  31  //      Date     : 2004-09-09 03:30:00 GMT -3:00
  32  //      Reviewer : Jonas Raoni Soares Silva
  33  //      Changes  : Acho q acabaram-se os bugs... Será??? :]
  34  //    **************************************************************
  35  
  36  (*
  37  @abstract(NotesSeeker - classe de buscas do Notes.)
  38  @author(Jonas Raoni Soares Silva <jonblackjack@bol.com.br>)
  39  @created(30 Nov 2003)
  40  *)
  41  
  42  unit NotesSeeker;
  43  
  44  interface
  45  
  46  uses
  47    SysUtils, Classes;
  48  
  49  type
  50  
  51  {
  52    @code(ENotesSeekerException) -
  53      Notificar erros na classe TNotesSeeker de forma
  54      profissional, facilitando a interceptação e/ou log de
  55      erros
  56  }
  57    ENotesSeekerException = class ( Exception )
  58    public
  59      constructor Create(const Msg: string);
  60      constructor CreateFmt(const Msg: string; const Args: array of const);
  61    end;
  62  
  63    {Opões de pesquisa: <BR>
  64     @code(nsHandleEOL) - se você precisar buscar por quebras de linhas, você precisa setar esta opção.<BR>
  65     @code(nsCaseSensitive) - diferenciar maiúsculas de minúsculas.<BR>
  66     @code(nsWholeWords) - retorna apenas palavras inteiras.<BR>
  67     @code(nsBackward) - busca de traz para frente. <BR>
  68     @code(nsHandleWildCard) - usa coringas * e ? na pesquisa.}
  69    TNotesSeekerOption = ( nsHandleEOL, nsCaseSensitive, nsWholeWords, nsBackward, nsHandleWildCard );
  70    { Set de @link(TNotesSeekerOption).}
  71    TNotesSeekerOptions = set of TNotesSeekerOption;
  72  
  73    TSearchFunction = function: Boolean of object;
  74  
  75  {
  76    @code(TNotesSeeker) -
  77      Permite fazer buscas em strings com várias opções
  78  }
  79    TNotesSeeker = class(TObject)
  80    private
  81      Jump, LineJump: Cardinal;
  82      FList: TList;
  83    protected
  84      FMatches, FStartAt, FEOLLen, FSearchLen, FCurCol,
  85      FCurLine, FMatchLen, FMatchLine, FMatchCol: Cardinal;
  86  
  87      FBufferEnd, FBuffer, FBufferBegin, FBufferBackup,
  88      FEOL, FSearchBegin, FSearch, FSearchEnd: PChar;
  89  
  90      FOptions: TNotesSeekerOptions;
  91  
  92      FContextRightLenght, FContextLeftLenght: Cardinal;
  93  
  94      FKeepText: Boolean;
  95  
  96      function GetText: string;
  97      function GetReplacedText: string;
  98      function GetContext: string;
  99      function GetSearchStr: string;
 100      function GetRemainingText: string;
 101      function GetCurByte: Cardinal;
 102      function GetEOL: string;
 103  
 104      procedure SetOptions(const Value: TNotesSeekerOptions);
 105      procedure SetText( const Value: string);
 106      procedure SetSearchStr(const Value: string);
 107      procedure SetEOL(const Value: string);
 108  
 109      procedure FreeBuffer;
 110      procedure FreeEOL;
 111      procedure FreeSearchStr;
 112  
 113      {Search Engines}
 114      function SearchForward: Boolean;
 115      function SearchForwardWithWildCard: Boolean;
 116      function SearchBackward: Boolean;
 117      function SearchBackwardWithWildCard: Boolean;
 118  
 119    public
 120      { Efetua a busca: se o termo procurado for encontrado, retorna true, caso contrário retorna false }
 121      Search: TSearchFunction;
 122  
 123      { Método construtor }
 124      constructor Create; virtual;
 125      { Método destruidor }
 126      destructor Destroy; override;
 127  
 128      { Armazena o tamanho do "match", quando a opção wildcard estiver desligada esta será igual ao tamanho da própria string procurada }
 129      property MatchLength: Cardinal read FMatchLen;
 130      { Quando HandleEOL fizer parte das opções, armazenará a linha onde a string procurada foi encontrada }
 131      property CurLine: Cardinal read FMatchLine;
 132      { Armazenará a coluna onde a string procurada foi encontrada, se HandleEOL não estiver nas opções, armazenará a mesma coisa que a propriedade CurByte }
 133      property CurCol: Cardinal read FMatchCol;
 134      { Armazena a posição ou byte "absoluto" onde a string foi encontrada }
 135      property CurByte: Cardinal read GetCurByte;
 136      { Especifica a posição/byte inicial onde a busca deverá começar }
 137      property StartAt: Cardinal read FStartAt write FStartAt;
 138      { Retorna o contexto onde a string procurada foi encontrada }
 139      property Context: string read GetContext;
 140      { Especifica a quantidade de caracteres que deverão fazer parte do contexto encontrado ao lado esquerdo da string procurada }
 141      property ContextLeftLenght: Cardinal read FContextLeftLenght write FContextLeftLenght;
 142      { Especifica a quantidade de caracteres que deverão fazer parte do contexto encontrado ao lado direito da string procurada }
 143      property ContextRightLenght: Cardinal read FContextRightLenght write FContextRightLenght;
 144      { Armazena o número de strings que coincidiram com a busca até o presente momento }
 145      property Matches: Cardinal read FMatches;
 146      { Permite alterar a sequência de caracteres que demarcam o fim de uma linha }
 147      property EOL: string read GetEOL write SetEOL;
 148      { Armazena as opções atualmente habilitadas para a busca, podendo ser alterada a qualquer momento }
 149      property Options: TNotesSeekerOptions read FOptions write SetOptions;
 150      { Termo a ser procurado no texto }
 151      property SearchStr: string read GetSearchStr write SetSearchStr;
 152      { Texto onde a busca será efetuada }
 153      property Text: string read GetText write SetText;
 154      { Texto restante ao término da busca }
 155      property RemainingText: string read GetRemainingText;
 156      { Especifica se a classe deverá manter uma cópia do texto setado inicialmente }
 157      property KeepText: Boolean read FKeepText write FKeepText;
 158      { Retorna o texto com os replaces, caso KeepText seja falso, essa propriedade se torna sinônimo da propriedade Text }
 159      property ReplacedText: string read GetReplacedText;
 160  
 161      { Prepara tudo para uma nova busca }
 162      procedure StartSearch;
 163      { Carrega o texto da busca a partir de um arquivo }
 164      procedure LoadFromFile( const AFilename: string );
 165      { Carrega o texto da busca a partir de um stream }
 166      procedure LoadFromStream( const AStream: TStream );
 167      { Carrega o texto da busca a partir de um buffer }
 168      procedure LoadFromBuffer( const ABuffer: PChar );
 169      { Efetua a substituição da string encontrada pela string contida em "S" }
 170      procedure Replace( const S: String );
 171      { Modo prático para setar as opções }
 172      procedure EnableOptions( const CaseSensitive: Boolean = true; const WholeWords: Boolean = false; const HandleEOL: Boolean = true; const HandleWildCard: Boolean = false; const Backward: Boolean = false );
 173  
 174    end;
 175  
 176    { Compara Str1 e Str2 de trás pra frente, se as duas forem iguais retorna true, caso contrário false }
 177    function StrLRComp( S1, S2: PChar; const S2Begin: PChar ): Boolean;
 178    { Converte para maiúsculo (ANSI) -> VALEUUUUU TIO RUSSÃO hahaha, o que tem no delphi "aplica a alteração"
 179      Idéia de manter tabela com tudo maiúsculo arrancada de "QStrings 6.07.424 Copyright (C) 2000, 2003 Andrew Dryazgov [ andrewdr@newmail.ru ]" }
 180    function AnsiUpCase(Ch: Char): Char;
 181  
 182  const
 183    { Caracteres que definem delimitadores de palavra, usada quando a opção WholeWords está ativa }
 184    WhiteSpaces: set of Char = [' ',#9,#13,#10,'!','"','#','$','%','&','''','(',')','*','+','-','/',':',';','<','=','>','?','@','[','\',']','^','`','{','|','}','~'];
 185  
 186  const
 187    //fiz algumas alterações hehe, o tiozaum russo devia tá começano a ficar cego enqto fazia isso :)
 188    ToUpperChars: array[0..255] of Char =
 189      (#$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0A,#$0B,#$0C,#$0D,#$0E,#$0F,
 190       #$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1A,#$1B,#$1C,#$1D,#$1E,#$1F,
 191       #$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2A,#$2B,#$2C,#$2D,#$2E,#$2F,
 192       #$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3A,#$3B,#$3C,#$3D,#$3E,#$3F,
 193       #$40,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4A,#$4B,#$4C,#$4D,#$4E,#$4F,
 194       #$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5A,#$5B,#$5C,#$5D,#$5E,#$5F,
 195       #$60,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4A,#$4B,#$4C,#$4D,#$4E,#$4F,
 196       #$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5A,#$7B,#$7C,#$7D,#$7E,#$7F,
 197       #$80,#$81,#$82,#$81,#$84,#$85,#$86,#$87,#$88,#$89,#$8A,#$8B,#$8C,#$8D,#$8E,#$8F,
 198       #$90,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$8A,#$9B,#$8C,#$9D,#$9E,#$9F,
 199       #$A0,#$A1,#$A1,#$A3,#$A4,#$A5,#$A6,#$A7,#$A8,#$A9,#$AA,#$AB,#$AC,#$AD,#$AE,#$AF,
 200       #$B0,#$B1,#$B2,#$B2,#$A5,#$B5,#$B6,#$B7,#$A8,#$B9,#$BA,#$BB,#$BC,#$BD,#$BE,#$BF,
 201       #$C0,#$C1,#$C2,#$C3,#$C4,#$C5,#$C6,#$C7,#$C8,#$C9,#$CA,#$CB,#$CC,#$CD,#$CE,#$CF,
 202       #$D0,#$D1,#$D2,#$D3,#$D4,#$D5,#$D6,#$D7,#$D8,#$D9,#$DA,#$DB,#$DC,#$DD,#$DE,#$DF,
 203       #$C0,#$C1,#$C2,#$C3,#$C4,#$C5,#$C6,#$C7,#$C8,#$C9,#$CA,#$CB,#$CC,#$CD,#$CE,#$CF,
 204       #$D0,#$D1,#$D2,#$D3,#$D4,#$D5,#$D6,#$F7,#$D8,#$D9,#$DA,#$DB,#$DC,#$DD,#$DE,#$9F);
 205  
 206  implementation
 207  
 208  function StrLRComp( S1, S2: PChar; const S2Begin: PChar ): Boolean;
 209  begin
 210    while ( S2 <> S2Begin ) and ( S1^ = S2^ ) do begin
 211      dec( S1 );
 212      dec( S2 );
 213    end;
 214    Result := ( S1^ = S2^ ) and ( S2 = S2Begin );
 215  end;
 216  
 217  function AnsiUpCase(Ch: Char): Char;
 218  begin
 219    Result := ToUpperChars[ ord( ch ) ];
 220  end;
 221  
 222  
 223  { class : TNotesSeeker }
 224  
 225  { TNotesSeeker : protected }
 226  
 227  function TNotesSeeker.GetText: string;
 228  begin
 229    if Assigned( FBufferBackup ) then
 230      Result := StrPas( FBufferBackup )
 231    else
 232      Result := ReplacedText;
 233  end;
 234  
 235  function TNotesSeeker.GetReplacedText: string;
 236  begin
 237    Result := StrPas( FBufferBegin );
 238  end;
 239  
 240  function TNotesSeeker.GetContext: string;
 241  var
 242    BeginAt, EndAt: PChar;
 243  begin
 244    if not ( nsBackward in FOptions ) then begin
 245      BeginAt := FBuffer - FMatchLen - FContextLeftLenght;
 246      EndAt := FBuffer+FContextRightLenght;
 247    end
 248    else begin
 249      BeginAt := FBuffer+1-FContextLeftLenght;
 250      EndAt := FBuffer+1+FMatchLen+FContextRightLenght;
 251    end;
 252    if BeginAt > EndAt then
 253      raise ENotesSeekerException.CreateFmt('GetContext::Range Error "BeginAt(%d) > EndAt(%d)"', [Integer(BeginAt), Integer(EndAt)]);
 254    if BeginAt < FBufferBegin then
 255      BeginAt := FBufferBegin;
 256    if EndAt > FBufferEnd then
 257      EndAt := FBufferEnd;
 258  
 259    SetString( Result, BeginAt, EndAt-BeginAt );
 260  end;
 261  
 262  function TNotesSeeker.GetSearchStr: string;
 263  begin
 264    Result := StrPas( FSearchBegin );
 265  end;
 266  
 267  function TNotesSeeker.GetRemainingText: string;
 268  begin
 269    Result := '';
 270    if not ( nsBackward in FOptions ) then
 271      Result := StrPas( FBuffer )
 272    else if FBuffer-FBufferBegin > -1 then
 273      SetString( Result, FBufferBegin, FBuffer-FBufferBegin+1 );
 274  end;
 275  
 276  function TNotesSeeker.GetCurByte: Cardinal;
 277  begin
 278    if nsBackward in FOptions then
 279      Result := FBufferEnd-1 - FBuffer - FMatchLen
 280    else
 281      Result := FBuffer - FMatchLen - FBufferBegin;
 282  end;
 283  
 284  function TNotesSeeker.GetEOL: string;
 285  begin
 286    Result := StrPas( FEOL );
 287  end;
 288  
 289  procedure TNotesSeeker.SetOptions(const Value: TNotesSeekerOptions);
 290  begin
 291    FOptions := Value;
 292    if nsBackward in Value then
 293      if nsHandleWildCard in Value then
 294        Search := SearchBackwardWithWildCard
 295      else
 296        Search := SearchBackward
 297    else if nsHandleWildCard in Value then
 298      Search := SearchForwardWithWildCard
 299    else
 300      Search := SearchForward;
 301  end;
 302  
 303  procedure TNotesSeeker.SetText( const Value: string );
 304  begin
 305    LoadFromBuffer( PChar( Value ) );
 306  end;
 307  
 308  procedure TNotesSeeker.SetSearchStr(const Value: string);
 309  begin
 310    FreeSearchStr;
 311    FSearchLen := Length( Value );
 312    GetMem( FSearchBegin, FSearchLen+1 );
 313    StrCopy( FSearchBegin, PChar( Value ) );
 314    FSearch := FSearchBegin;
 315    FSearchEnd := StrEnd( FSearchBegin );
 316  end;
 317  
 318  procedure TNotesSeeker.SetEOL(const Value: string);
 319  begin
 320    FreeEOL;
 321    FEOLLen := Length( Value );
 322    GetMem( FEOL, FEOLLen+1 );
 323    StrCopy( FEOL, PChar( Value ) );
 324  end;
 325  
 326  
 327  procedure TNotesSeeker.FreeBuffer;
 328  begin
 329    if Assigned( FBufferBegin ) then begin
 330      FBufferEnd := nil;
 331      FBuffer := nil;
 332      FreeMem( FBufferBegin );
 333    end;
 334    if Assigned( FBufferBackup ) then begin
 335      FreeMem( FBufferBackup );
 336      FBufferBackup := nil;
 337    end;
 338  end;
 339  
 340  procedure TNotesSeeker.FreeEOL;
 341  begin
 342    if Assigned( FEOL ) then begin
 343      FreeMem( FEOL );
 344      FEOL := nil;
 345    end;
 346  end;
 347  
 348  procedure TNotesSeeker.FreeSearchStr;
 349  begin
 350    if Assigned( FSearchBegin ) then begin
 351      FreeMem( FSearchBegin );
 352      FSearchBegin := nil;
 353      FSearch := nil;
 354      FSearchEnd := nil;
 355    end;
 356  end;
 357  
 358  
 359  
 360  { TNotesSeeker : public }
 361  
 362  constructor TNotesSeeker.Create;
 363  begin
 364    EOL := #13#10;
 365    FContextLeftLenght := 10;
 366    FContextRightLenght := 20;
 367    Search := SearchForward;
 368  end;
 369  
 370  destructor TNotesSeeker.Destroy;
 371  begin
 372    FreeBuffer;
 373    FreeSearchStr;
 374    FreeEOL;
 375    inherited Destroy;
 376  end;
 377  
 378  procedure TNotesSeeker.LoadFromBuffer( const ABuffer: PChar );
 379  begin
 380    FreeBuffer;
 381    GetMem( FBufferBegin, StrLen( ABuffer )+1 );
 382    FBuffer := StrCopy( FBufferBegin, ABuffer );
 383    FBufferEnd :=  StrEnd( FBufferBegin );
 384    if FKeepText then begin
 385      GetMem( FBufferBackup, StrLen( FBufferBegin )+1 );
 386      StrCopy( FBufferBackup, FBufferBegin );
 387    end;  
 388  end;
 389  
 390  procedure TNotesSeeker.LoadFromFile(const AFilename: string);
 391  var
 392    FS: TFileStream;
 393  begin
 394    if not FileExists( AFilename ) then
 395      raise ENotesSeekerException.CreateFmt( 'LoadFromFile::Arquivo "%s" não encontrado', [AFilename] );
 396    FS := TFileStream.Create( AFilename, fmOpenRead );
 397    try
 398      LoadFromStream( FS );
 399    finally
 400      FS.Free;
 401    end;
 402  end;
 403  
 404  procedure TNotesSeeker.LoadFromStream(const AStream: TStream);
 405  var
 406    Size: Int64;
 407  begin
 408    FreeBuffer;
 409    Size := AStream.Size;
 410    GetMem( FBuffer, Size+1 );
 411    Size := AStream.Read( FBuffer^, Size );
 412    ( FBuffer+Size )^ := #0;
 413    FBufferEnd := (FBuffer+Size);
 414    FBufferBegin := FBuffer;
 415    if FKeepText then begin
 416      GetMem( FBufferBackup, StrLen( FBufferBegin )+1 );
 417      StrCopy( FBufferBackup, FBufferBegin );
 418    end;  
 419  end;
 420  
 421  procedure TNotesSeeker.StartSearch;
 422  begin
 423    FMatches := 0;
 424    FCurLine := 0;
 425    FCurCol := 0;
 426  
 427    if FSearchLen = 0 then
 428      raise ENotesSeekerException.Create( 'StartSearch::Propriedade SearchStr está vazia.' );
 429  
 430    if ( FBufferBackup <> FBufferBegin ) and Assigned( FBufferBackup ) then begin
 431      FreeMem( FBufferBegin );
 432      GetMem( FBufferBegin, StrLen( FBufferBackup )+1 );
 433      FBuffer := StrCopy( FBufferBegin, FBufferBackup );
 434      FBufferEnd := FBuffer + StrLen( FBufferBackup );
 435    end;
 436  
 437    if nsBackward in FOptions then
 438      FBuffer := FBufferEnd-1
 439    else
 440      FBuffer := FBufferBegin;
 441  end;
 442  
 443  procedure TNotesSeeker.Replace(const S: String);
 444  var
 445    TempBuff: PChar;
 446    BufferOffset: Integer;
 447  begin
 448    TempBuff := nil;
 449    if not ( nsBackward in FOptions ) then begin
 450      BufferOffset := FBuffer-FMatchLen - FBufferBegin + Length( S );
 451      GetMem( TempBuff, ( FBuffer-FMatchLen - FBufferBegin) + Length(S) + ( FBufferEnd - FBuffer ) + 1 );
 452      FBufferEnd := StrLCopy( StrLCopy( StrLCopy( TempBuff, FBufferBegin, FBuffer-FMatchLen - FBufferBegin )+(FBuffer-FMatchLen - FBufferBegin), PChar( S ), Length( S ) )+Length( S ), FBuffer, FBufferEnd - FBuffer )+(FBufferEnd - FBuffer);
 453      FreeMem( FBufferBegin );
 454      FBufferBegin := TempBuff;
 455      FBuffer := FBufferBegin + BufferOffset;
 456    end
 457    else begin
 458      BufferOffset := FBufferEnd - (FBuffer + FMatchLen) + Length( S );
 459      if FBuffer < FBufferBegin then
 460        GetMem( TempBuff, FBufferEnd - (FBuffer+FMatchLen) + Length( S ) + ( FBuffer - FBufferBegin ) + 1 )
 461      else
 462        GetMem( TempBuff, FBufferEnd - (FBuffer+FMatchLen) + Length( S ) + ( FBuffer - FBufferBegin ) + 1 );
 463      FBufferEnd := StrLCopy( StrLCopy( StrLCopy( TempBuff, FBufferBegin, FBuffer-FBufferBegin+1 )+(FBuffer-FBufferBegin+1), PChar( S ), Length( S ) )+Length( S ), FBuffer+FMatchLen+1, FBufferEnd-1 - (FBuffer+FMatchLen) )+ ( FBufferEnd-1 - (FBuffer+FMatchLen) );
 464      FreeMem( FBufferBegin );
 465      FBufferBegin := TempBuff;
 466      FBuffer := FBufferEnd - BufferOffset;
 467    end;
 468  end;
 469  
 470  
 471  { ENotesSeekerException }
 472  { ENotesSeekerException : public }
 473  
 474  constructor ENotesSeekerException.Create(const Msg: string);
 475  begin
 476    inherited Create( 'TNotesSeeker.'+Msg );
 477  end;
 478  
 479  constructor ENotesSeekerException.CreateFmt(const Msg: string; const Args: array of const);
 480  begin
 481    inherited CreateFmt( 'TNotesSeeker.'+Msg, Args );
 482  end;
 483  
 484  procedure TNotesSeeker.EnableOptions(const CaseSensitive, WholeWords, HandleEOL, HandleWildCard, Backward: Boolean);
 485    var Opcoes: TNotesSeekerOptions;
 486  begin
 487    if CaseSensitive then Include( Opcoes, nsCaseSensitive ) else Exclude( Opcoes, nsCaseSensitive );
 488    if HandleEOL then Include( Opcoes, nsHandleEOL ) else Exclude( Opcoes, nsHandleEOL );
 489    if Backward then Include( Opcoes, nsBackward ) else Exclude( Opcoes, nsBackward );
 490    if HandleWildCard then Include( Opcoes, nsHandleWildCard ) else Exclude( Opcoes, nsHandleWildCard );
 491    if WholeWords then Include( Opcoes, nsWholeWords ) else Exclude( Opcoes, nsWholeWords );
 492    SetOptions( Opcoes );
 493  end;
 494  
 495  function TNotesSeeker.SearchForward: Boolean;
 496  begin
 497    Result := True;
 498    LineJump := 0;
 499    FMatchLine := 0;
 500    FMatchCol := 0;
 501    FMatchLen := 0;
 502    FSearch := FSearchBegin;
 503  
 504    if FBufferBegin + FStartAt > FBufferEnd then
 505      FStartAt := FBufferEnd - FBufferBegin;
 506    while FStartAt > FBuffer-FBufferBegin do begin
 507      if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin
 508        Inc( FBuffer, FEOLLen );
 509        Inc( FCurLine );
 510        FCurCol :=