OpenTTD
stringfilter.cpp
Go to the documentation of this file.
1 /* $Id$ */
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.clear();
32  this->word_index.shrink_to_fit();
33  this->word_matches = 0;
34  free(this->filter_buffer);
35 
36  assert(str != nullptr);
37 
38  char *dest = MallocT<char>(strlen(str) + 1);
39  this->filter_buffer = dest;
40 
41  WChar state = STATE_WHITESPACE;
42  const char *pos = str;
43  WordState *word = nullptr;
44  size_t len;
45  for (;; pos += len) {
46  WChar c;
47  len = Utf8Decode(&c, pos);
48 
49  if (c == 0 || (state == STATE_WORD && IsWhitespace(c))) {
50  /* Finish word */
51  if (word != nullptr) {
52  *(dest++) = '\0';
53  word = nullptr;
54  }
55  state = STATE_WHITESPACE;
56  if (c != 0) continue; else break;
57  }
58 
59  if (state == STATE_WHITESPACE) {
60  /* Skip whitespace */
61  if (IsWhitespace(c)) continue;
62  state = STATE_WORD;
63  }
64 
65  if (c == STATE_QUOTE1 || c == STATE_QUOTE2) {
66  if (state == c) {
67  /* Stop quoting */
68  state = STATE_WORD;
69  continue;
70  } else if (state == STATE_WORD) {
71  /* Start quoting */
72  state = c;
73  continue;
74  }
75  }
76 
77  /* Add to word */
78  if (word == nullptr) {
79  /*C++17: word = &*/ this->word_index.push_back({dest, false});
80  word = &this->word_index.back();
81  }
82 
83  memcpy(dest, pos, len);
84  dest += len;
85  }
86 }
87 
92 {
93  this->word_matches = 0;
94  for (WordState &ws : this->word_index) {
95  ws.match = false;
96  }
97 }
98 
107 void StringFilter::AddLine(const char *str)
108 {
109  if (str == nullptr) return;
110 
111  bool match_case = this->case_sensitive != nullptr && *this->case_sensitive;
112  for (WordState &ws : this->word_index) {
113  if (!ws.match) {
114  if ((match_case ? strstr(str, ws.start) : strcasestr(str, ws.start)) != nullptr) {
115  ws.match = true;
116  this->word_matches++;
117  }
118  }
119  }
120 }
121 
131 {
132  char buffer[DRAW_STRING_BUFFER];
133  GetString(buffer, str, lastof(buffer));
134  AddLine(buffer);
135 }
Functions related to OTTD&#39;s strings.
void ResetState()
Reset the matching state to process a new item.
static bool IsWhitespace(WChar c)
Check whether UNICODE character is whitespace or not, i.e.
Definition: string_func.h:242
static const int DRAW_STRING_BUFFER
Size of the buffer used for drawing strings.
Definition: gfx_func.h:85
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition: string.cpp:448
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
const char * filter_buffer
Parsed filter string. Words separated by 0.
void SetFilterTerm(const char *str)
Set the term to filter on.
Functions related to low-level strings.
Functions related to the gfx engine.
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
uint word_matches
Summary of filter state: Number of words matched.
State of a single filter word.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
void AddLine(const char *str)
Pass another text line from the current item to the filter.
Searching and filtering using a stringterm.
std::vector< WordState > word_index
Word index and filter state.
const bool * case_sensitive
Match case-sensitively (usually a static variable).
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:131
uint32 WChar
Type for wide characters, i.e.
Definition: string_type.h:37