4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file stringfilter.cpp Searching and filtering using a stringterm. */
13 #include "string_func.h"
14 #include "strings_func.h"
15 #include "stringfilter_type.h"
18 static const WChar STATE_WHITESPACE
= ' ';
19 static const WChar STATE_WORD
= 'w';
20 static const WChar STATE_QUOTE1
= '\'';
21 static const WChar STATE_QUOTE2
= '"';
24 * Set the term to filter on.
25 * @param str Filter term
27 void StringFilter::SetFilterTerm(const char *str
)
29 this->word_index
.Reset();
30 this->word_matches
= 0;
31 free(this->filter_buffer
);
35 char *dest
= (char *)malloc(strlen(str
) + 1);
36 this->filter_buffer
= dest
;
38 WChar state
= STATE_WHITESPACE
;
39 const char *pos
= str
;
40 WordState
*word
= NULL
;
44 len
= Utf8Decode(&c
, pos
);
46 if (c
== 0 || (state
== STATE_WORD
&& IsWhitespace(c
))) {
52 state
= STATE_WHITESPACE
;
53 if (c
!= 0) continue; else break;
56 if (state
== STATE_WHITESPACE
) {
58 if (IsWhitespace(c
)) continue;
62 if (c
== STATE_QUOTE1
|| c
== STATE_QUOTE2
) {
67 } else if (state
== STATE_WORD
) {
76 word
= this->word_index
.Append();
81 memcpy(dest
, pos
, len
);
87 * Reset the matching state to process a new item.
89 void StringFilter::ResetState()
91 this->word_matches
= 0;
92 const WordState
*end
= this->word_index
.End();
93 for (WordState
*it
= this->word_index
.Begin(); it
!= end
; ++it
) {
99 * Pass another text line from the current item to the filter.
101 * You can call this multiple times for a single item, if the filter shall apply to multiple things.
102 * Before processing the next item you have to call ResetState().
104 * @param str Another line from the item.
106 void StringFilter::AddLine(const char *str
)
108 if (str
== NULL
) return;
110 bool match_case
= this->case_sensitive
!= NULL
&& *this->case_sensitive
;
111 const WordState
*end
= this->word_index
.End();
112 for (WordState
*it
= this->word_index
.Begin(); it
!= end
; ++it
) {
114 if ((match_case
? strstr(str
, it
->start
) : strcasestr(str
, it
->start
)) != NULL
) {
116 this->word_matches
++;
123 * Pass another text line from the current item to the filter.
125 * You can call this multiple times for a single item, if the filter shall apply to multiple things.
126 * Before processing the next item you have to call ResetState().
128 * @param str Another line from the item.
130 void StringFilter::AddLine(StringID str
)
132 char buffer
[DRAW_STRING_BUFFER
];
133 GetString(buffer
, str
, lastof(buffer
));