OpenTTD
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 
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 
133 {
134  char buffer[DRAW_STRING_BUFFER];
135  GetString(buffer, str, lastof(buffer));
136  AddLine(buffer);
137 }
Functions related to OTTD&#39;s strings.
bool match
Already matched?
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:87
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition: string.cpp:437
#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.
const char * start
Word to filter for.
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.
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:114
SmallVector< WordState, 4 > word_index
Word index and filter state.
uint32 WChar
Type for wide characters, i.e.
Definition: string_type.h:35