summaryrefslogtreecommitdiff
path: root/src/TextSearchQuery.pas
blob: 2a5697b5e09eb5992960bbc1c8e871bd157d8f1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Unit TextSearchQuery;

{$mode objfpc}{$H+}

// NewView - a new OS/2 Help Viewer
// Copyright 2001 Aaron Lawrence (aaronl at consultant dot com)
// This software is released under the Gnu Public License - see readme.txt

Interface

// Encapsulates a parsed search query.

uses
  Classes, SysUtils;

Type
  ESearchSyntaxError = class( Exception )
  end;

  TSearchTermCombineMethod = ( cmOr, cmAnd, cmNot );

  TSearchTerm = class
    Text: string;
    CombineMethod: TSearchTermCombineMethod;
  end;

  TTextSearchQuery = class
  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
  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
    Destroy; // clean up
    raise; // reraise exception
  end;
end;

destructor TTextSearchQuery.Destroy;
var
  i: TSearchTerm;
begin
  while Terms.Count > 0 do
  begin
    i := TSearchTerm(Terms.Last);
    Terms.Remove(i);
    i.Free;
  end;

//  DestroyListObjects( Terms );
  Terms.Destroy;
end;

function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm;
begin
  Result := TSearchTerm(Terms[ Index ]);
end;

function TTextSearchQuery.GetTermCount: longint;
begin
  Result := Terms.Count;
end;

Initialization
End.