anchor.diff:  
   destructor TTextSearchQuery.Destroy;
   begin
  -  Cleanup;
  +  DestroyListObjects( Terms );
  +  Terms.Free;
     inherited Destroy;
   end;
   
  -procedure TTextSearchQuery.Cleanup;
  +function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm;
  +begin
  +  Result := TSearchTerm(Terms[ Index ]);
  +end;
  +
  +function TTextSearchQuery.GetTermCount: longint;
  +begin
  +  Result := Terms.Count;
  +end;
  +
  +constructor TSearchTerm.Create( const TheText: string;
  +                                const TheCombineMethod: TSearchTermCombineMethod );
   var
  -  i: TSearchTerm;
  -begin
  -  if Assigned(Terms) then
  +  TermParseIndex: longint;
  +  TermChar: char;
  +  TermPart: string;
  +begin
  +  Parts := TStringList.Create;
  +
  +  Text := TheText;
  +  CombineMethod := TheCombineMethod;
  +
  +  // Break out each part of the term as IPF does:
  +  // consecutive alphanumeric chars become a "word"
  +  // but each symbol is a separate word, and symbols break
  +  // up alphanumerics into multiple words. e.g.
  +  // CAKE_SAUSAGE becomes three words in IPF,
  +  // one each for "CAKE" "_" and "SAUSAGE"
  +
  +  TermParseIndex := 1;
  +  while TermParseIndex <= Length( Text ) do
     begin
  -  while Terms.Count > 0 do
  -    begin
  -      i := TSearchTerm(Terms.Last);
  -      Terms.Remove(i);
  -      i.Free;
  -    end;
  -
  -    //  DestroyListObjects( Terms );
  -    Terms.Free;
  -  end;
  -
  -end;
  -
  -function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm;
  -begin
  -  Result := TSearchTerm(Terms[ Index ]);
  -end;
  -
  -function TTextSearchQuery.GetTermCount: longint;
  -begin
  -  Result := Terms.Count;
  -end;
  -
  -Initialization
  -End.
  +    // collect alphanumeric chars
  +    TermPart := '';
  +    while TermParseIndex <= Length( Text ) do
  +    begin
  +      TermChar := Text[ TermParseIndex ];
  +      if  (    IsAlpha( TermChar )
  +            or IsDigit( TermChar ) ) then
  +      begin
  +        // alpha numeric, collect it
  +        TermPart := TermPart + TermChar;
  +        inc( TermParseIndex );
  +      end
  +      else
  +      begin
  +        // not alpha numeric, so stop
  +        break;
  +      end;
  +    end;
  +    if Length( TermPart ) > 0 then
  +    begin
  +      Parts.Add( TermPart ); // add collected alphanumeric part
  +    end;
  +
  +    if TermParseIndex <= Length( Text ) then
  +    begin
  +      // must be a symbol,
  +      // each symbol (excluding space) is an individual item
  +      if Text[ TermParseIndex ] <> ' ' then
  +        Parts.Add( Text[ TermParseIndex ] );
  +      inc( TermParseIndex );
  +    end;
  +
  +  end;
  +
  +end;
  +
  +destructor TSearchTerm.Destroy;
  +begin
  +  Parts.Free;
  +  inherited Destroy;
  +end;
  +
  +
  +end.
  
positive.code:   ESearchSyntaxError = class( Exception )
    end;
  
    TSearchTermCombineMethod = ( cmOr, cmAnd, cmNot );
  
    TSearchTerm = class
      Text: string;
      CombineMethod: TSearchTermCombineMethod;
    end;
  
    TTextSearchQuery = class
    private
      procedure Cleanup;
    protected
      Terms: TList;
      function GetTerm( Index: longint ): TSearchTerm;
      function GetTermCount: longint;
    public
      constructor Create( SearchString: string );
      destructor Destroy; override;
  
      property Term[ Index: longint ]: TSearchTerm read GetTerm;
      property TermCount: longint read GetTermCount;
    end;
  
  Implementation
  
  uses
    nvUtilities;
  //  ACLStringUtility, ACLUtility, Dialogs;
  
  constructor TTextSearchQuery.Create( SearchString: string );
  var
    SearchWord: string;
    RemainingSearchString: string;
    CombineMethod: TSearchTermCombineMethod;
    lTerm: TSearchTerm;
  begin
    inherited Create;
    Terms := TList.Create;
    try
      RemainingSearchString := Uppercase( SearchString );
      while RemainingSearchString <> '' do
      begin
        SearchWord := ExtractNextValue( RemainingSearchString, ' ' );
  
        // Check for modifiers + (word must be matched)
        // and - (word must not be matched)
        case SearchWord[ 1 ] of
         '+':
           CombineMethod := cmAnd;
         '-':
           CombineMethod := cmNot;
         else
           CombineMethod := cmOr;
        end;
        if CombineMethod <> cmOr then
        begin
          // delete + or -
          if Length( SearchWord ) = 1 then
            raise ESearchSyntaxError.Create( 'No search word given after "'
                                             + SearchWord + '" before "'
                                             + RemainingSearchString
                                             + '"' );
          Delete( SearchWord, 1, 1 );
        end;
  
        lTerm := TSearchTerm.Create;
        lTerm.Text := SearchWord;
        lTerm.CombineMethod := CombineMethod;
        Terms.Add( lTerm );
      end;
    except
        while Terms.Count > 0 do
        begin
  
negative.code: {$mode objfpc}{$H+}
  
  // NewView - a new OS/2 Help Viewer
  // Copyright 2003 Aaron Lawrence (aaronl at consultant dot com)
  // This software is released under the Gnu Public License - see readme.txt
  
  Interface
  