OpenTTD Source 20241224-master-gf74b0cf984
stringfilter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#include "stdafx.h"
11#include "core/alloc_func.hpp"
12#include "string_func.h"
13#include "strings_func.h"
14#include "stringfilter_type.h"
15#include "gfx_func.h"
16
17#include "safeguards.h"
18
19static const char32_t STATE_WHITESPACE = ' ';
20static const char32_t STATE_WORD = 'w';
21static const char32_t STATE_QUOTE1 = '\'';
22static const char32_t STATE_QUOTE2 = '"';
23
28void StringFilter::SetFilterTerm(const char *str)
29{
30 this->word_index.clear();
31 this->word_index.shrink_to_fit();
32 this->word_matches = 0;
33 free(this->filter_buffer);
34
35 assert(str != nullptr);
36
37 char *dest = MallocT<char>(strlen(str) + 1);
38 this->filter_buffer = dest;
39
40 char32_t state = STATE_WHITESPACE;
41 const char *pos = str;
42 WordState *word = nullptr;
43 size_t len;
44 for (;; pos += len) {
45 char32_t c;
46 len = Utf8Decode(&c, pos);
47
48 if (c == 0 || (state == STATE_WORD && IsWhitespace(c))) {
49 /* Finish word */
50 if (word != nullptr) {
51 *(dest++) = '\0';
52 word = nullptr;
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 == nullptr) {
78 word = &this->word_index.emplace_back(WordState{ dest, false });
79 }
80
81 memcpy(dest, pos, len);
82 dest += len;
83 }
84}
85
90void StringFilter::SetFilterTerm(const std::string &str)
91{
92 this->SetFilterTerm(str.c_str());
93}
94
99{
100 this->word_matches = 0;
101 for (WordState &ws : this->word_index) {
102 ws.match = false;
103 }
104}
105
114void StringFilter::AddLine(const char *str)
115{
116 if (str == nullptr) return;
117
118 bool match_case = this->case_sensitive != nullptr && *this->case_sensitive;
119 for (WordState &ws : this->word_index) {
120 if (!ws.match) {
121 if (this->locale_aware) {
122 if (match_case ? StrNaturalContains(str, ws.start) : StrNaturalContainsIgnoreCase(str, ws.start)) {
123 ws.match = true;
124 this->word_matches++;
125 }
126 } else {
127 if ((match_case ? strstr(str, ws.start) : strcasestr(str, ws.start)) != nullptr) {
128 ws.match = true;
129 this->word_matches++;
130 }
131 }
132 }
133 }
134}
135
144void StringFilter::AddLine(const std::string &str)
145{
146 AddLine(str.c_str());
147}
148
158{
159 AddLine(GetString(str));
160}
Functions related to the allocation of memory.
Functions related to the gfx engine.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition stdafx.h:334
bool StrNaturalContains(const std::string_view str, const std::string_view value)
Checks if a string is contained in another string with a locale-aware comparison that is case sensiti...
Definition string.cpp:660
size_t Utf8Decode(char32_t *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition string.cpp:419
bool StrNaturalContainsIgnoreCase(const std::string_view str, const std::string_view value)
Checks if a string is contained in another string with a locale-aware comparison that is case insensi...
Definition string.cpp:687
Functions related to low-level strings.
bool IsWhitespace(char32_t c)
Check whether UNICODE character is whitespace or not, i.e.
Searching and filtering using a stringterm.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:333
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
State of a single filter word.
uint word_matches
Summary of filter state: Number of words matched.
const char * filter_buffer
Parsed filter string. Words separated by 0.
std::vector< WordState > word_index
Word index and filter state.
void SetFilterTerm(const char *str)
Set the term to filter on.
bool locale_aware
Match words using the current locale.
void ResetState()
Reset the matching state to process a new item.
const bool * case_sensitive
Match case-sensitively (usually a static variable).
void AddLine(const char *str)
Pass another text line from the current item to the filter.