FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
component_fuzzer.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4// 版權所有 2021 Arthur Sonzogni。保留所有權利。
5// 本原始碼的使用受 MIT 授權條款約束,該條款可在 LICENSE 檔案中找到。
6#include <cassert>
8#include <vector>
11
12using namespace ftxui;
13namespace {
14
15bool GeneratorBool(const char*& data, size_t& size) {
16 if (size == 0) {
17 return false;
18 }
19
20 auto out = bool(data[0] % 2);
21 data++;
22 size--;
23 return out;
24}
25
26std::string GeneratorString(const char*& data, size_t& size) {
27 int index = 0;
28 while (index < size && data[index]) {
29 ++index;
30 }
31
32 auto out = std::string(data, data + index);
33 data += index;
34 size -= index;
35
36 // The input component do not support invalid UTF8 yet.
37 // 輸入元件尚不支援無效的 UTF8。
38 try {
39 to_wstring(out);
40 } catch (...) {
41 return "0";
42 }
43 return std::move(out);
44}
45
46int GeneratorInt(const char* data, size_t size) {
47 if (size == 0) {
48 return 0;
49 }
50 auto out = int(data[0]);
51 data++;
52 size--;
53 return out;
54}
55
56Color GeneratorColor(const char* data, size_t size) {
57 return Color::RGB(GeneratorInt(data, size), GeneratorInt(data, size),
58 GeneratorInt(data, size));
59}
60
61AnimatedColorOption GeneratorAnimatedColorOption(const char* data,
62 size_t size) {
64 option.enabled = GeneratorBool(data, size);
65 option.inactive = GeneratorColor(data, size);
66 option.active = GeneratorColor(data, size);
67 option.duration = std::chrono::milliseconds(GeneratorInt(data, size));
68 return option;
69}
70
71AnimatedColorsOption GeneratorAnimatedColorsOptions(const char* data,
72 size_t size) {
74 option.background = GeneratorAnimatedColorOption(data, size);
75 option.foreground = GeneratorAnimatedColorOption(data, size);
76 return option;
77}
78
79ButtonOption GeneratorButtonOption(const char* data, size_t size) {
80 ButtonOption option;
81 option.animated_colors = GeneratorAnimatedColorsOptions(data, size);
82 return option;
83}
84
85UnderlineOption GeneratorUnderlineOption(const char* data, size_t size) {
86 UnderlineOption option;
87 option.enabled = GeneratorBool(data, size);
88 option.color_active = GeneratorColor(data, size);
89 option.color_inactive = GeneratorColor(data, size);
90 option.leader_duration = std::chrono::milliseconds(GeneratorInt(data, size));
91 option.follower_duration =
92 std::chrono::milliseconds(GeneratorInt(data, size));
93 option.leader_delay = std::chrono::milliseconds(GeneratorInt(data, size));
94 option.follower_delay = std::chrono::milliseconds(GeneratorInt(data, size));
95 return option;
96}
97
98MenuEntryOption GeneratorMenuEntryOption(const char* data, size_t size) {
99 MenuEntryOption option;
100 option.animated_colors = GeneratorAnimatedColorsOptions(data, size);
101 return option;
102}
103
104MenuOption GeneratorMenuOption(const char* data, size_t size) {
105 MenuOption option;
106 option.underline = GeneratorUnderlineOption(data, size);
107 option.entries_option = GeneratorMenuEntryOption(data, size);
108 option.direction = static_cast<Direction>(GeneratorInt(data, size) % 4);
109 return option;
110}
111
112bool g_bool;
113int g_int;
114std::vector<std::string> g_list;
115
116Components GeneratorComponents(const char*& data, size_t& size, int depth);
117
118Component GeneratorComponent(const char*& data, size_t& size, int depth) {
119 depth--;
120 int value = GeneratorInt(data, size);
121 if (depth <= 0) {
122 return Button(GeneratorString(data, size), [] {});
123 }
124
125 constexpr int value_max = 19;
126 value = (value % value_max + value_max) % value_max;
127 switch (value) {
128 case 0:
129 return Button(
130 GeneratorString(data, size), [] {},
131 GeneratorButtonOption(data, size));
132 case 1:
133 return Checkbox(GeneratorString(data, size), &g_bool);
134 case 2:
135 return Input(GeneratorString(data, size), GeneratorString(data, size));
136 case 3:
137 return Menu(&g_list, &g_int, GeneratorMenuOption(data, size));
138 case 4:
139 return Radiobox(&g_list, &g_int);
140 case 5:
141 return Toggle(&g_list, &g_int);
142 case 6:
143 return Slider(GeneratorString(data, size), &g_int,
144 GeneratorInt(data, size), GeneratorInt(data, size),
145 GeneratorInt(data, size));
146 case 7:
147 return ResizableSplitLeft(GeneratorComponent(data, size, depth - 1),
148 GeneratorComponent(data, size, depth - 1),
149 &g_int);
150 case 8:
151 return ResizableSplitRight(GeneratorComponent(data, size, depth - 1),
152 GeneratorComponent(data, size, depth - 1),
153 &g_int);
154 case 9:
155 return ResizableSplitTop(GeneratorComponent(data, size, depth - 1),
156 GeneratorComponent(data, size, depth - 1),
157 &g_int);
158 case 10:
159 return ResizableSplitBottom(GeneratorComponent(data, size, depth - 1),
160 GeneratorComponent(data, size, depth - 1),
161 &g_int);
162 case 11:
163 return Container::Vertical(GeneratorComponents(data, size, depth - 1));
164
165 case 12:
166 return Container::Vertical(GeneratorComponents(data, size, depth - 1),
167 &g_int);
168
169 case 13:
170 return Container::Horizontal(GeneratorComponents(data, size, depth - 1));
171 case 14:
172 return Container::Horizontal(GeneratorComponents(data, size, depth - 1),
173 &g_int);
174 case 15:
175 return Container::Tab(GeneratorComponents(data, size, depth - 1), &g_int);
176 case 16:
177 return Maybe(GeneratorComponent(data, size, depth - 1), &g_bool);
178 case 17:
179 return Dropdown(&g_list, &g_int);
180 case 18:
181 return Collapsible(GeneratorString(data, size),
182 GeneratorComponent(data, size, depth - 1),
183 GeneratorBool(data, size));
184 default:
185 assert(false);
186 }
187}
188
189Components GeneratorComponents(const char*& data, size_t& size, int depth) {
190 Components out;
191 if (depth > 0) {
192 while (size && GeneratorInt(data, size) % 2) {
193 out.push_back(GeneratorComponent(data, size, depth - 1));
194 }
195 }
196 return std::move(out);
197}
198
199} // namespace
200extern "C" int LLVMFuzzerTestOneInput(const char* data, size_t size) {
201 g_bool = GeneratorBool(data, size);
202 g_int = GeneratorInt(data, size);
203 g_list = {
204 "test_1", "test_2", "test_3", "test_4", "test_5",
205 };
206
207 int depth = 10;
208 auto component = GeneratorComponent(data, size, depth);
209
210 int width = GeneratorInt(data, size);
211 int height = GeneratorInt(data, size);
212
213 width %= 500;
214 width += 500;
215
216 height %= 500;
217 height += 500;
218
219 auto screen =
220 Screen::Create(Dimension::Fixed(width), Dimension::Fixed(height));
221
222 // Generate some events.
223 // 生成一些事件。
224 std::vector<Event> events;
225 auto parser =
226 TerminalInputParser([&](const Event& event) { events.push_back(event); });
227
228 for (size_t i = 0; i < size; ++i) {
229 parser.Add(data[i]);
230 }
231
232 for (const auto& event : events) {
233 component->OnEvent(event);
234 auto document = component->Render();
235 Render(screen, document);
236 }
237 return 0; // Non-zero return values are reserved for future use.
238 // 非零回傳值保留供未來使用。
239}
int LLVMFuzzerTestOneInput(const char *data, size_t size)
auto component
Definition gallery.cpp:127
animation::Duration follower_duration
MenuEntryOption entries_option
animation::Duration follower_delay
UnderlineOption underline
animation::Duration leader_duration
AnimatedColorsOption animated_colors
animation::Duration leader_delay
Component Maybe(Component, const bool *show)
裝飾一個組件 |child|。它只在 |show| 為 true 時顯示。
Component ResizableSplitTop(Component main, Component back, int *main_size)
兩個元件之間的垂直分割,可透過滑鼠設定。
Component Checkbox(CheckboxOption options)
Component Menu(MenuOption options)
文字列表。選定的元素會被聚焦。
Component Toggle(ConstStringListRef entries, int *selected)
元素的水平列表。使用者可以在其中導航。
Component Radiobox(RadioboxOption options)
元素清單,只能選擇一個。
Component Button(ButtonOption options)
繪製一個按鈕。點擊時執行一個函數。
Component Input(InputOption options={})
用於編輯文字的輸入框。
Component ResizableSplitRight(Component main, Component back, int *main_size)
兩個元件之間的水平分割,可透過滑鼠設定。
Component Dropdown(ConstStringListRef entries, int *selected)
下拉式選單。
Component ResizableSplitBottom(Component main, Component back, int *main_size)
兩個元件之間的垂直分割,可透過滑鼠設定。
Component ResizableSplitLeft(Component main, Component back, int *main_size)
兩個元件之間的水平分割,可透過滑鼠設定。
關於潛在動畫顏色的選項。
AnimatedButton 元件的選項。
代表一個事件。它可以是按鍵事件、終端機大小調整,或更多...
Definition event.hpp:27
MenuEntry 元件的選項。
Menu 元件的選項。
底線效果的選項。
Decorator size(WidthOrHeight, Constraint, int value)
限制元素的大小。
Direction
Direction 是一個列舉,表示四個主要方向。
Definition direction.hpp:12
static Screen Create(Dimensions dimension)
創建具有給定尺寸的螢幕。
Definition screen.cpp:395
static Color RGB(uint8_t red, uint8_t green, uint8_t blue)
從 RGB 表示建立一個顏色。 https://en.wikipedia.org/wiki/RGB_color_model
Color 是一個在終端使用者介面中表示顏色的類別。
Definition color.hpp:20
FTXUI 的 ftxui:: 命名空間
Definition animation.hpp:10
std::vector< Component > Components
std::wstring to_wstring(const std::string &s)
將 UTF8 std::string 轉換為 std::wstring。
Definition string.cpp:1614
Component Collapsible(ConstStringRef label, Component child, Ref< bool > show=false)
可折疊元件。它顯示一個帶有箭頭的核取方塊。一旦啟用,子元件就會顯示。
Component Slider(SliderOption< T > options)
void Render(Screen &screen, const Element &element)
std::shared_ptr< ComponentBase > Component