OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

stringfilter.cpp
Go to the documentation of this file.
1 /* $Id: stringfilter.cpp 26482 2014-04-23 20:13:33Z rubidium $ */
2
3 /*
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/>.
8 */
9
12 #include "stdafx.h"
13 #include "string_func.h"
14 #include "strings_func.h"
15 #include "stringfilter_type.h"
16 #include "gfx_func.h"
17
18 #include "safeguards.h"
19
20 static const WChar STATE_WHITESPACE = ' ';
21 static const WChar STATE_WORD = 'w';
22 static const WChar STATE_QUOTE1 = '\'';
23 static const WChar STATE_QUOTE2 = '"';
24
29 void StringFilter::SetFilterTerm(const char *str)
30 {
31 this->word_index.Reset();
32 this->word_matches = 0;
33 free(this->filter_buffer);
34
35 assert(str != NULL);
36
37 char *dest = MallocT<char>(strlen(str) + 1);
38 this->filter_buffer = dest;
39
40 WChar state = STATE_WHITESPACE;
41 const char *pos = str;
42 WordState *word = NULL;
43 size_t len;
44 for (;; pos += len) {
45 WChar c;
46 len = Utf8Decode(&c, pos);
47
48 if (c == 0 || (state == STATE_WORD && IsWhitespace(c))) {
49 /* Finish word */
50 if (word != NULL) {
51 *(dest++) = '\0';
52 word = NULL;
53 }
54 state = STATE_WHITESPACE;
55 if (c != 0) continue; else break;
56 }
57
58 if (state == STATE_WHITESPACE) {
59 /* Skip whitespace */
60 if (IsWhitespace(c)) continue;
61 state = STATE_WORD;
62 }
63
64 if (c == STATE_QUOTE1 || c == STATE_QUOTE2) {
65 if (state == c) {
66 /* Stop quoting */
67 state = STATE_WORD;
68 continue;
69 } else if (state == STATE_WORD) {
70 /* Start quoting */
71 state = c;
72 continue;
73 }
74 }
75
76 /* Add to word */
77 if (word == NULL) {
78 word = this->word_index.Append();
79 word->start = dest;
80 word->match = false;
81 }
82
83 memcpy(dest, pos, len);
84 dest += len;
85 }
86 }
87
91 void StringFilter::ResetState()
92 {
93 this->word_matches = 0;
94 const WordState *end = this->word_index.End();
95 for (WordState *it = this->word_index.Begin(); it != end; ++it) {
96 it->match = false;
97 }
98 }
99
108 void StringFilter::AddLine(const char *str)
109 {
110 if (str == NULL) return;
111
112 bool match_case = this->case_sensitive != NULL && *this->case_sensitive;
113 const WordState *end = this->word_index.End();
114 for (WordState *it = this->word_index.Begin(); it != end; ++it) {
115 if (!it->match) {
116 if ((match_case ? strstr(str, it->start) : strcasestr(str, it->start)) != NULL) {
117 it->match = true;
118 this->word_matches++;
119 }
120 }
121 }
122 }
123
132 void StringFilter::AddLine(StringID str)
133 {
134 char buffer[DRAW_STRING_BUFFER];
135 GetString(buffer, str, lastof(buffer));
136 AddLine(buffer);
137 }