summaryrefslogtreecommitdiff
path: root/src/TextSearchQuery.pas
blob: d4a7a6ba79e903b7456aabf34c2354d42e54d479 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
  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
        lTerm := TSearchTerm(Terms.Last);
        Terms.Remove(lTerm);
        lTerm.Free;
      end;
      Terms.Free;
      raise; // reraise exception
  end;
end;

destructor TTextSearchQuery.Destroy;
begin
  Cleanup;
  inherited Destroy;
end;

procedure TTextSearchQuery.Cleanup;
var
  i: TSearchTerm;
begin
  if Assigned(Terms) then
  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.