1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * lws-api-test-lws_tokenize
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Written in 2010-2021 by Andy Green <andy@warmcat.com>
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0
7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication.
8d4afb5ceSopenharmony_ci *
9d4afb5ceSopenharmony_ci * This demonstrates the most minimal http server you can make with lws.
10d4afb5ceSopenharmony_ci *
11d4afb5ceSopenharmony_ci * To keep it simple, it serves stuff from the subdirectory
12d4afb5ceSopenharmony_ci * "./mount-origin" of the directory it was started in.
13d4afb5ceSopenharmony_ci * You can change that by changing mount.origin below.
14d4afb5ceSopenharmony_ci */
15d4afb5ceSopenharmony_ci
16d4afb5ceSopenharmony_ci#include <libwebsockets.h>
17d4afb5ceSopenharmony_ci#include <string.h>
18d4afb5ceSopenharmony_ci#include <stdio.h>
19d4afb5ceSopenharmony_ci
20d4afb5ceSopenharmony_cistruct expected {
21d4afb5ceSopenharmony_ci	lws_tokenize_elem e;
22d4afb5ceSopenharmony_ci	const char *value;
23d4afb5ceSopenharmony_ci	size_t len;
24d4afb5ceSopenharmony_ci};
25d4afb5ceSopenharmony_ci
26d4afb5ceSopenharmony_cistruct tests {
27d4afb5ceSopenharmony_ci	const char *string;
28d4afb5ceSopenharmony_ci	struct expected *exp;
29d4afb5ceSopenharmony_ci	int count;
30d4afb5ceSopenharmony_ci	int flags;
31d4afb5ceSopenharmony_ci};
32d4afb5ceSopenharmony_ci
33d4afb5ceSopenharmony_cistruct expected expected1[] = {
34d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"protocol-1", 10 },
35d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1},
36d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"protocol_2", 10 },
37d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1},
38d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"protocol3", 9 },
39d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, NULL, 0 },
40d4afb5ceSopenharmony_ci	},
41d4afb5ceSopenharmony_ci	expected2[] = {
42d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN_NAME_COLON,		"Accept-Language", 15 },
43d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"fr-CH", 5 },
44d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER,			",", 1 },
45d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"fr", 2 },
46d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER,		";", 1},
47d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS,	"q", 1 },
48d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT,		"0.9", 3 },
49d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER,			",", 1 },
50d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"en", 2 },
51d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER,		";", 1},
52d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS,	"q", 1 },
53d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT,		"0.8", 3 },
54d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER,			",", 1 },
55d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"de", 2 },
56d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER,		";", 1},
57d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS,	"q", 1 },
58d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT,		"0.7", 3 },
59d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
60d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER,		"*", 1 },
61d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER,		";", 1 },
62d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS,	"q", 1 },
63d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT,		"0.5", 3 },
64d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, NULL, 0 },
65d4afb5ceSopenharmony_ci	},
66d4afb5ceSopenharmony_ci	expected3[] = {
67d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS,	"quoted", 6 },
68d4afb5ceSopenharmony_ci			{ LWS_TOKZE_QUOTED_STRING,	"things:", 7 },
69d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER,			",", 1 },
70d4afb5ceSopenharmony_ci			{ LWS_TOKZE_INTEGER,		"1234", 4 },
71d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, NULL, 0 },
72d4afb5ceSopenharmony_ci	},
73d4afb5ceSopenharmony_ci	expected4[] = {
74d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ERR_COMMA_LIST,		",", 1 },
75d4afb5ceSopenharmony_ci	},
76d4afb5ceSopenharmony_ci	expected5[] = {
77d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"brokenlist2", 11 },
78d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
79d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ERR_COMMA_LIST,		",", 1 },
80d4afb5ceSopenharmony_ci	},
81d4afb5ceSopenharmony_ci	expected6[] = {
82d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN,		"brokenlist3", 11 },
83d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
84d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ERR_COMMA_LIST,		",", 1 },
85d4afb5ceSopenharmony_ci
86d4afb5ceSopenharmony_ci	},
87d4afb5ceSopenharmony_ci	expected7[] = {
88d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN, "fr", 2 },
89d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, "-", 1 },
90d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN, "CH", 2 },
91d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ",", 1 },
92d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN, "fr", 2 },
93d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ";", 1 },
94d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS, "q", 1 },
95d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT, "0.9", 3 },
96d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ",", 1 },
97d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN, "en", 2 },
98d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ";", 1 },
99d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS, "q", 1 },
100d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT, "0.8", 3 },
101d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ",", 1 },
102d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN, "de", 2 },
103d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ";", 1 },
104d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS, "q", 1 },
105d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT, "0.7", 3 },
106d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ",", 1 },
107d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN, "*", 1 },
108d4afb5ceSopenharmony_ci			{ LWS_TOKZE_DELIMITER, ";", 1 },
109d4afb5ceSopenharmony_ci			{ LWS_TOKZE_TOKEN_NAME_EQUALS, "q", 1 },
110d4afb5ceSopenharmony_ci			{ LWS_TOKZE_FLOAT, "0.5", 3 },
111d4afb5ceSopenharmony_ci			{ LWS_TOKZE_ENDED, "", 0 },
112d4afb5ceSopenharmony_ci	},
113d4afb5ceSopenharmony_ci	expected8[] = {
114d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "Οὐχὶ", 10 },
115d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "ταὐτὰ", 12 },
116d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "παρίσταταί", 22 },
117d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "μοι", 6 },
118d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "γιγνώσκειν", 21 },
119d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
120d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "ὦ", 3 },
121d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "ἄνδρες", 13 },
122d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "᾿Αθηναῖοι", 20 },
123d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
124d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "greek", 5 },
125d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
126d4afb5ceSopenharmony_ci	},
127d4afb5ceSopenharmony_ci	expected9[] = {
128d4afb5ceSopenharmony_ci		/*
129d4afb5ceSopenharmony_ci		 *  because the tokenizer scans ahead for = aggregation,
130d4afb5ceSopenharmony_ci		 * it finds the broken utf8 before reporting the token
131d4afb5ceSopenharmony_ci		 */
132d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ERR_BROKEN_UTF8, "", 0 },
133d4afb5ceSopenharmony_ci	},
134d4afb5ceSopenharmony_ci	expected10[] = {
135d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "badutf8-2", 9 },
136d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "퟿", 3 },
137d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
138d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ERR_BROKEN_UTF8, "", 0 },
139d4afb5ceSopenharmony_ci	},
140d4afb5ceSopenharmony_ci	expected11[] = {
141d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "1.myserver", 10 },
142d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ".", 1 },
143d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "com", 3 },
144d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
145d4afb5ceSopenharmony_ci	},
146d4afb5ceSopenharmony_ci	expected12[] = {
147d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "1.myserver.com", 14 },
148d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
149d4afb5ceSopenharmony_ci	},
150d4afb5ceSopenharmony_ci	expected13[] = {
151d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "1.myserver.com", 14 },
152d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
153d4afb5ceSopenharmony_ci	},
154d4afb5ceSopenharmony_ci	expected14[] = {
155d4afb5ceSopenharmony_ci		{ LWS_TOKZE_INTEGER, "1", 1 },
156d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ".", 1 },
157d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "myserver", 8 },
158d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ".", 1 },
159d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "com", 3 },
160d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
161d4afb5ceSopenharmony_ci	},
162d4afb5ceSopenharmony_ci	expected15[] = {
163d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "close", 5 },
164d4afb5ceSopenharmony_ci		{ LWS_TOKZE_DELIMITER, ",", 1 },
165d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "Upgrade", 7 },
166d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
167d4afb5ceSopenharmony_ci	},
168d4afb5ceSopenharmony_ci	expected16[] = {
169d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN_NAME_EQUALS, "a", 1 },
170d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "5", 1 },
171d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
172d4afb5ceSopenharmony_ci	},
173d4afb5ceSopenharmony_ci	expected17[] = {
174d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "hello", 5 },
175d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
176d4afb5ceSopenharmony_ci	},
177d4afb5ceSopenharmony_ci	expected18[] = {
178d4afb5ceSopenharmony_ci		{ LWS_TOKZE_TOKEN, "x=y", 3 },
179d4afb5ceSopenharmony_ci		{ LWS_TOKZE_ENDED, "", 0 },
180d4afb5ceSopenharmony_ci	}
181d4afb5ceSopenharmony_ci;
182d4afb5ceSopenharmony_ci
183d4afb5ceSopenharmony_cistruct tests tests[] = {
184d4afb5ceSopenharmony_ci	{
185d4afb5ceSopenharmony_ci		" protocol-1, protocol_2\t,\tprotocol3\n",
186d4afb5ceSopenharmony_ci		expected1, LWS_ARRAY_SIZE(expected1),
187d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_MINUS_NONTERM | LWS_TOKENIZE_F_AGG_COLON
188d4afb5ceSopenharmony_ci	}, {
189d4afb5ceSopenharmony_ci		"Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5",
190d4afb5ceSopenharmony_ci		expected2, LWS_ARRAY_SIZE(expected2),
191d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_MINUS_NONTERM | LWS_TOKENIZE_F_AGG_COLON
192d4afb5ceSopenharmony_ci	}, {
193d4afb5ceSopenharmony_ci		"quoted = \"things:\", 1234",
194d4afb5ceSopenharmony_ci		expected3, LWS_ARRAY_SIZE(expected3),
195d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_MINUS_NONTERM | LWS_TOKENIZE_F_AGG_COLON
196d4afb5ceSopenharmony_ci	}, {
197d4afb5ceSopenharmony_ci		", brokenlist1",
198d4afb5ceSopenharmony_ci		expected4, LWS_ARRAY_SIZE(expected4),
199d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_COMMA_SEP_LIST
200d4afb5ceSopenharmony_ci	}, {
201d4afb5ceSopenharmony_ci		"brokenlist2,,",
202d4afb5ceSopenharmony_ci		expected5, LWS_ARRAY_SIZE(expected5),
203d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_COMMA_SEP_LIST
204d4afb5ceSopenharmony_ci	}, {
205d4afb5ceSopenharmony_ci		"brokenlist3,",
206d4afb5ceSopenharmony_ci		expected6, LWS_ARRAY_SIZE(expected6),
207d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_COMMA_SEP_LIST
208d4afb5ceSopenharmony_ci	}, {
209d4afb5ceSopenharmony_ci		"fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5",
210d4afb5ceSopenharmony_ci		expected7, LWS_ARRAY_SIZE(expected7),
211d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_ASTERISK_NONTERM | LWS_TOKENIZE_F_RFC7230_DELIMS
212d4afb5ceSopenharmony_ci	},
213d4afb5ceSopenharmony_ci	{
214d4afb5ceSopenharmony_ci		" Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι, greek",
215d4afb5ceSopenharmony_ci		expected8, LWS_ARRAY_SIZE(expected8),
216d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_RFC7230_DELIMS
217d4afb5ceSopenharmony_ci	},
218d4afb5ceSopenharmony_ci	{
219d4afb5ceSopenharmony_ci		"badutf8-1 \x80...",
220d4afb5ceSopenharmony_ci		expected9, LWS_ARRAY_SIZE(expected9),
221d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_MINUS_NONTERM | LWS_TOKENIZE_F_RFC7230_DELIMS
222d4afb5ceSopenharmony_ci	},
223d4afb5ceSopenharmony_ci	{
224d4afb5ceSopenharmony_ci		"badutf8-2 \xed\x9f\xbf,\x80...",
225d4afb5ceSopenharmony_ci		expected10, LWS_ARRAY_SIZE(expected10),
226d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_MINUS_NONTERM | LWS_TOKENIZE_F_RFC7230_DELIMS
227d4afb5ceSopenharmony_ci	},
228d4afb5ceSopenharmony_ci	{
229d4afb5ceSopenharmony_ci		"1.myserver.com",
230d4afb5ceSopenharmony_ci		expected11, LWS_ARRAY_SIZE(expected11),
231d4afb5ceSopenharmony_ci		0
232d4afb5ceSopenharmony_ci	},
233d4afb5ceSopenharmony_ci	{
234d4afb5ceSopenharmony_ci		"1.myserver.com",
235d4afb5ceSopenharmony_ci		expected12, LWS_ARRAY_SIZE(expected12),
236d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_DOT_NONTERM
237d4afb5ceSopenharmony_ci	},
238d4afb5ceSopenharmony_ci	{
239d4afb5ceSopenharmony_ci		"1.myserver.com",
240d4afb5ceSopenharmony_ci		expected13, LWS_ARRAY_SIZE(expected13),
241d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_DOT_NONTERM | LWS_TOKENIZE_F_NO_FLOATS
242d4afb5ceSopenharmony_ci	},
243d4afb5ceSopenharmony_ci	{
244d4afb5ceSopenharmony_ci		"1.myserver.com",
245d4afb5ceSopenharmony_ci		expected14, LWS_ARRAY_SIZE(expected14),
246d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_NO_FLOATS
247d4afb5ceSopenharmony_ci	},
248d4afb5ceSopenharmony_ci	{
249d4afb5ceSopenharmony_ci		"close,  Upgrade",
250d4afb5ceSopenharmony_ci		expected15, LWS_ARRAY_SIZE(expected15),
251d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_COMMA_SEP_LIST
252d4afb5ceSopenharmony_ci	},
253d4afb5ceSopenharmony_ci	{
254d4afb5ceSopenharmony_ci		"a=5", expected16, LWS_ARRAY_SIZE(expected16),
255d4afb5ceSopenharmony_ci		LWS_TOKENIZE_F_NO_INTEGERS
256d4afb5ceSopenharmony_ci	},
257d4afb5ceSopenharmony_ci	{
258d4afb5ceSopenharmony_ci		"# comment1\r\nhello #comment2\r\n#comment3", expected17,
259d4afb5ceSopenharmony_ci		LWS_ARRAY_SIZE(expected17), LWS_TOKENIZE_F_HASH_COMMENT
260d4afb5ceSopenharmony_ci	},
261d4afb5ceSopenharmony_ci	{
262d4afb5ceSopenharmony_ci		"x=y", expected18,
263d4afb5ceSopenharmony_ci		LWS_ARRAY_SIZE(expected18), LWS_TOKENIZE_F_EQUALS_NONTERM
264d4afb5ceSopenharmony_ci	}
265d4afb5ceSopenharmony_ci};
266d4afb5ceSopenharmony_ci
267d4afb5ceSopenharmony_ci/*
268d4afb5ceSopenharmony_ci * add LWS_TOKZE_ERRS to the element index (which may be negative by that
269d4afb5ceSopenharmony_ci * amount) to index this array
270d4afb5ceSopenharmony_ci */
271d4afb5ceSopenharmony_ci
272d4afb5ceSopenharmony_cistatic const char *element_names[] = {
273d4afb5ceSopenharmony_ci	"LWS_TOKZE_ERR_BROKEN_UTF8",
274d4afb5ceSopenharmony_ci	"LWS_TOKZE_ERR_UNTERM_STRING",
275d4afb5ceSopenharmony_ci	"LWS_TOKZE_ERR_MALFORMED_FLOAT",
276d4afb5ceSopenharmony_ci	"LWS_TOKZE_ERR_NUM_ON_LHS",
277d4afb5ceSopenharmony_ci	"LWS_TOKZE_ERR_COMMA_LIST",
278d4afb5ceSopenharmony_ci	"LWS_TOKZE_ENDED",
279d4afb5ceSopenharmony_ci	"LWS_TOKZE_DELIMITER",
280d4afb5ceSopenharmony_ci	"LWS_TOKZE_TOKEN",
281d4afb5ceSopenharmony_ci	"LWS_TOKZE_INTEGER",
282d4afb5ceSopenharmony_ci	"LWS_TOKZE_FLOAT",
283d4afb5ceSopenharmony_ci	"LWS_TOKZE_TOKEN_NAME_EQUALS",
284d4afb5ceSopenharmony_ci	"LWS_TOKZE_TOKEN_NAME_COLON",
285d4afb5ceSopenharmony_ci	"LWS_TOKZE_QUOTED_STRING",
286d4afb5ceSopenharmony_ci};
287d4afb5ceSopenharmony_ci
288d4afb5ceSopenharmony_ci
289d4afb5ceSopenharmony_ciint
290d4afb5ceSopenharmony_ciexp_cb1(void *priv, const char *name, char *out, size_t *pos, size_t olen,
291d4afb5ceSopenharmony_ci	size_t *exp_ofs)
292d4afb5ceSopenharmony_ci{
293d4afb5ceSopenharmony_ci	const char *replace = NULL;
294d4afb5ceSopenharmony_ci	size_t total, budget;
295d4afb5ceSopenharmony_ci
296d4afb5ceSopenharmony_ci	if (!strcmp(name, "test")) {
297d4afb5ceSopenharmony_ci		replace = "replacement_string";
298d4afb5ceSopenharmony_ci		total = strlen(replace);
299d4afb5ceSopenharmony_ci		goto expand;
300d4afb5ceSopenharmony_ci	}
301d4afb5ceSopenharmony_ci
302d4afb5ceSopenharmony_ci	return LSTRX_FATAL_NAME_UNKNOWN;
303d4afb5ceSopenharmony_ci
304d4afb5ceSopenharmony_ciexpand:
305d4afb5ceSopenharmony_ci	budget = olen - *pos;
306d4afb5ceSopenharmony_ci	total -= *exp_ofs;
307d4afb5ceSopenharmony_ci	if (total < budget)
308d4afb5ceSopenharmony_ci		budget = total;
309d4afb5ceSopenharmony_ci
310d4afb5ceSopenharmony_ci	if (out)
311d4afb5ceSopenharmony_ci		memcpy(out + *pos, replace + (*exp_ofs), budget);
312d4afb5ceSopenharmony_ci	*exp_ofs += budget;
313d4afb5ceSopenharmony_ci	*pos += budget;
314d4afb5ceSopenharmony_ci
315d4afb5ceSopenharmony_ci	if (budget == total)
316d4afb5ceSopenharmony_ci		return LSTRX_DONE;
317d4afb5ceSopenharmony_ci
318d4afb5ceSopenharmony_ci	return LSTRX_FILLED_OUT;
319d4afb5ceSopenharmony_ci}
320d4afb5ceSopenharmony_ci
321d4afb5ceSopenharmony_cistatic const char *exp_inp1 = "this-is-a-${test}-for-strexp";
322d4afb5ceSopenharmony_ci
323d4afb5ceSopenharmony_ciint main(int argc, const char **argv)
324d4afb5ceSopenharmony_ci{
325d4afb5ceSopenharmony_ci	struct lws_context_creation_info info;
326d4afb5ceSopenharmony_ci	struct lws_context *cx;
327d4afb5ceSopenharmony_ci	struct lws_tokenize ts;
328d4afb5ceSopenharmony_ci	lws_tokenize_elem e;
329d4afb5ceSopenharmony_ci	const char *p;
330d4afb5ceSopenharmony_ci	int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
331d4afb5ceSopenharmony_ci			/* for LLL_ verbosity above NOTICE to be built into lws,
332d4afb5ceSopenharmony_ci			 * lws must have been configured and built with
333d4afb5ceSopenharmony_ci			 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
334d4afb5ceSopenharmony_ci			/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
335d4afb5ceSopenharmony_ci			/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
336d4afb5ceSopenharmony_ci			/* | LLL_DEBUG */;
337d4afb5ceSopenharmony_ci	int fail = 0, ok = 0, flags = 0;
338d4afb5ceSopenharmony_ci	char dotstar[512];
339d4afb5ceSopenharmony_ci
340d4afb5ceSopenharmony_ci	if ((p = lws_cmdline_option(argc, argv, "-d")))
341d4afb5ceSopenharmony_ci		logs = atoi(p);
342d4afb5ceSopenharmony_ci
343d4afb5ceSopenharmony_ci	lws_set_log_level(logs, NULL);
344d4afb5ceSopenharmony_ci	lwsl_user("LWS API selftest: lws_tokenize\n");
345d4afb5ceSopenharmony_ci
346d4afb5ceSopenharmony_ci	if ((p = lws_cmdline_option(argc, argv, "-f")))
347d4afb5ceSopenharmony_ci		flags = atoi(p);
348d4afb5ceSopenharmony_ci
349d4afb5ceSopenharmony_ci
350d4afb5ceSopenharmony_ci	memset(&info, 0, sizeof info);
351d4afb5ceSopenharmony_ci	info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
352d4afb5ceSopenharmony_ci		       LWS_SERVER_OPTION_H2_JUST_FIX_WINDOW_UPDATE_OVERFLOW;
353d4afb5ceSopenharmony_ci
354d4afb5ceSopenharmony_ci	/*
355d4afb5ceSopenharmony_ci	 * since we know this lws context is only ever going to be used with
356d4afb5ceSopenharmony_ci	 * one client wsis / fds / sockets at a time, let lws know it doesn't
357d4afb5ceSopenharmony_ci	 * have to use the default allocations for fd tables up to ulimit -n.
358d4afb5ceSopenharmony_ci	 * It will just allocate for 1 internal and 1 (+ 1 http2 nwsi) that we
359d4afb5ceSopenharmony_ci	 * will use.
360d4afb5ceSopenharmony_ci	 */
361d4afb5ceSopenharmony_ci	info.fd_limit_per_thread = 1 + 1 + 1;
362d4afb5ceSopenharmony_ci
363d4afb5ceSopenharmony_ci#if 0
364d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) || defined(USE_WOLFSSL)
365d4afb5ceSopenharmony_ci	/*
366d4afb5ceSopenharmony_ci	 * OpenSSL uses the system trust store.  mbedTLS has to be told which
367d4afb5ceSopenharmony_ci	 * CA to trust explicitly.
368d4afb5ceSopenharmony_ci	 */
369d4afb5ceSopenharmony_ci	info.client_ssl_ca_filepath = "./warmcat.com.cer";
370d4afb5ceSopenharmony_ci#endif
371d4afb5ceSopenharmony_ci#endif
372d4afb5ceSopenharmony_ci#if 0
373d4afb5ceSopenharmony_ci	n = open("./warmcat.com.cer", O_RDONLY);
374d4afb5ceSopenharmony_ci	if (n >= 0) {
375d4afb5ceSopenharmony_ci		info.client_ssl_ca_mem_len = read(n, memcert, sizeof(memcert));
376d4afb5ceSopenharmony_ci		info.client_ssl_ca_mem = memcert;
377d4afb5ceSopenharmony_ci		close(n);
378d4afb5ceSopenharmony_ci		n = 0;
379d4afb5ceSopenharmony_ci		memcert[info.client_ssl_ca_mem_len++] = '\0';
380d4afb5ceSopenharmony_ci	}
381d4afb5ceSopenharmony_ci#endif
382d4afb5ceSopenharmony_ci	cx = lws_create_context(&info);
383d4afb5ceSopenharmony_ci
384d4afb5ceSopenharmony_ci	/* lws_strexp */
385d4afb5ceSopenharmony_ci
386d4afb5ceSopenharmony_ci	{
387d4afb5ceSopenharmony_ci		size_t in_len, used_in, used_out;
388d4afb5ceSopenharmony_ci		lws_strexp_t exp;
389d4afb5ceSopenharmony_ci		char obuf[128];
390d4afb5ceSopenharmony_ci		const char *p;
391d4afb5ceSopenharmony_ci
392d4afb5ceSopenharmony_ci		obuf[0] = '\0';
393d4afb5ceSopenharmony_ci		lws_strexp_init(&exp, NULL, exp_cb1, obuf, sizeof(obuf));
394d4afb5ceSopenharmony_ci		n = lws_strexp_expand(&exp, exp_inp1, 28, &used_in, &used_out);
395d4afb5ceSopenharmony_ci		if (n != LSTRX_DONE || used_in != 28 ||
396d4afb5ceSopenharmony_ci		    strcmp(obuf, "this-is-a-replacement_string-for-strexp")) {
397d4afb5ceSopenharmony_ci			lwsl_notice("%s: obuf %s\n", __func__, obuf);
398d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_strexp test 1 failed: %d\n", __func__, n);
399d4afb5ceSopenharmony_ci
400d4afb5ceSopenharmony_ci			return 1;
401d4afb5ceSopenharmony_ci		}
402d4afb5ceSopenharmony_ci
403d4afb5ceSopenharmony_ci		/* as above, but don't generate output, just find the length */
404d4afb5ceSopenharmony_ci
405d4afb5ceSopenharmony_ci		lws_strexp_init(&exp, NULL, exp_cb1, NULL, (size_t)-1);
406d4afb5ceSopenharmony_ci		n = lws_strexp_expand(&exp, exp_inp1, 28, &used_in, &used_out);
407d4afb5ceSopenharmony_ci		if (n != LSTRX_DONE || used_in != 28 || used_out != 39) {
408d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_strexp test 2 failed: %d, used_out: %d\n",
409d4afb5ceSopenharmony_ci					__func__, n, (int)used_out);
410d4afb5ceSopenharmony_ci
411d4afb5ceSopenharmony_ci			return 1;
412d4afb5ceSopenharmony_ci		}
413d4afb5ceSopenharmony_ci
414d4afb5ceSopenharmony_ci		p = exp_inp1;
415d4afb5ceSopenharmony_ci		in_len = strlen(p);
416d4afb5ceSopenharmony_ci		memset(obuf, 0, sizeof(obuf));
417d4afb5ceSopenharmony_ci		lws_strexp_init(&exp, NULL, exp_cb1, obuf, 16);
418d4afb5ceSopenharmony_ci		n = lws_strexp_expand(&exp, p, in_len, &used_in, &used_out);
419d4afb5ceSopenharmony_ci		if (n != LSTRX_FILLED_OUT || used_in != 16 || used_out != 16) {
420d4afb5ceSopenharmony_ci			lwsl_err("a\n");
421d4afb5ceSopenharmony_ci			return 1;
422d4afb5ceSopenharmony_ci		}
423d4afb5ceSopenharmony_ci
424d4afb5ceSopenharmony_ci		p += used_in;
425d4afb5ceSopenharmony_ci		in_len -= used_in;
426d4afb5ceSopenharmony_ci
427d4afb5ceSopenharmony_ci		memset(obuf, 0, sizeof(obuf));
428d4afb5ceSopenharmony_ci		lws_strexp_reset_out(&exp, obuf, 16);
429d4afb5ceSopenharmony_ci
430d4afb5ceSopenharmony_ci		n = lws_strexp_expand(&exp, p, in_len, &used_in, &used_out);
431d4afb5ceSopenharmony_ci		if (n != LSTRX_FILLED_OUT || used_in != 5 || used_out != 16) {
432d4afb5ceSopenharmony_ci			lwsl_err("b: n %d, used_in %d, used_out %d\n", n,
433d4afb5ceSopenharmony_ci					(int)used_in, (int)used_out);
434d4afb5ceSopenharmony_ci			return 2;
435d4afb5ceSopenharmony_ci		}
436d4afb5ceSopenharmony_ci
437d4afb5ceSopenharmony_ci		p += used_in;
438d4afb5ceSopenharmony_ci		in_len -= used_in;
439d4afb5ceSopenharmony_ci
440d4afb5ceSopenharmony_ci		memset(obuf, 0, sizeof(obuf));
441d4afb5ceSopenharmony_ci		lws_strexp_reset_out(&exp, obuf, 16);
442d4afb5ceSopenharmony_ci
443d4afb5ceSopenharmony_ci		n = lws_strexp_expand(&exp, p, in_len, &used_in, &used_out);
444d4afb5ceSopenharmony_ci		if (n != LSTRX_DONE || used_in != 7 || used_out != 7) {
445d4afb5ceSopenharmony_ci			lwsl_err("c: n %d, used_in %d, used_out %d\n", n, (int)used_in, (int)used_out);
446d4afb5ceSopenharmony_ci			return 2;
447d4afb5ceSopenharmony_ci		}
448d4afb5ceSopenharmony_ci	}
449d4afb5ceSopenharmony_ci
450d4afb5ceSopenharmony_ci	/* sanity check lws_strnncpy() */
451d4afb5ceSopenharmony_ci
452d4afb5ceSopenharmony_ci	lws_strnncpy(dotstar, "12345678", 4, sizeof(dotstar));
453d4afb5ceSopenharmony_ci	if (strcmp(dotstar, "1234")) {
454d4afb5ceSopenharmony_ci		lwsl_err("%s: lws_strnncpy check failed\n", __func__);
455d4afb5ceSopenharmony_ci
456d4afb5ceSopenharmony_ci		return 1;
457d4afb5ceSopenharmony_ci	}
458d4afb5ceSopenharmony_ci	lws_strnncpy(dotstar, "12345678", 8, 6);
459d4afb5ceSopenharmony_ci	if (strcmp(dotstar, "12345")) {
460d4afb5ceSopenharmony_ci		lwsl_err("%s: lws_strnncpy check failed\n", __func__);
461d4afb5ceSopenharmony_ci
462d4afb5ceSopenharmony_ci		return 1;
463d4afb5ceSopenharmony_ci	}
464d4afb5ceSopenharmony_ci
465d4afb5ceSopenharmony_ci	/* sanity check lws_nstrstr() */
466d4afb5ceSopenharmony_ci
467d4afb5ceSopenharmony_ci	{
468d4afb5ceSopenharmony_ci		static const char *t1 = "abc123456";
469d4afb5ceSopenharmony_ci		const char *mcp;
470d4afb5ceSopenharmony_ci
471d4afb5ceSopenharmony_ci		mcp = lws_nstrstr(t1, strlen(t1), "abc", 3);
472d4afb5ceSopenharmony_ci		if (mcp != t1) {
473d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_nstrstr 1 failed\n", __func__);
474d4afb5ceSopenharmony_ci			return 1;
475d4afb5ceSopenharmony_ci		}
476d4afb5ceSopenharmony_ci		mcp = lws_nstrstr(t1, strlen(t1), "def", 3);
477d4afb5ceSopenharmony_ci		if (mcp != NULL) {
478d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_nstrstr 2 failed\n", __func__);
479d4afb5ceSopenharmony_ci			return 1;
480d4afb5ceSopenharmony_ci		}
481d4afb5ceSopenharmony_ci		mcp = lws_nstrstr(t1, strlen(t1), "456", 3);
482d4afb5ceSopenharmony_ci		if (mcp != t1 + 6) {
483d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_nstrstr 3 failed: %p\n", __func__, mcp);
484d4afb5ceSopenharmony_ci			return 1;
485d4afb5ceSopenharmony_ci		}
486d4afb5ceSopenharmony_ci		mcp = lws_nstrstr(t1, strlen(t1), "1", 1);
487d4afb5ceSopenharmony_ci		if (mcp != t1 + 3) {
488d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_nstrstr 4 failed\n", __func__);
489d4afb5ceSopenharmony_ci			return 1;
490d4afb5ceSopenharmony_ci		}
491d4afb5ceSopenharmony_ci		mcp = lws_nstrstr(t1, strlen(t1), "abc1234567", 10);
492d4afb5ceSopenharmony_ci		if (mcp != NULL) {
493d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_nstrstr 5 failed\n", __func__);
494d4afb5ceSopenharmony_ci			return 1;
495d4afb5ceSopenharmony_ci		}
496d4afb5ceSopenharmony_ci	}
497d4afb5ceSopenharmony_ci
498d4afb5ceSopenharmony_ci	/* sanity check lws_json_simple_find() */
499d4afb5ceSopenharmony_ci
500d4afb5ceSopenharmony_ci	{
501d4afb5ceSopenharmony_ci		static const char *t1 = "{\"myname1\":true,"
502d4afb5ceSopenharmony_ci					 "\"myname2\":\"string\", "
503d4afb5ceSopenharmony_ci					 "\"myname3\": 123}";
504d4afb5ceSopenharmony_ci		size_t alen;
505d4afb5ceSopenharmony_ci		const char *mcp;
506d4afb5ceSopenharmony_ci
507d4afb5ceSopenharmony_ci		mcp = lws_json_simple_find(t1, strlen(t1), "\"myname1\":", &alen);
508d4afb5ceSopenharmony_ci		if (mcp != t1 + 11 || alen != 4) {
509d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_json_simple_find 1 failed: (%d) %s\n",
510d4afb5ceSopenharmony_ci				 __func__, (int)alen, mcp);
511d4afb5ceSopenharmony_ci			return 1;
512d4afb5ceSopenharmony_ci		}
513d4afb5ceSopenharmony_ci
514d4afb5ceSopenharmony_ci		mcp = lws_json_simple_find(t1, strlen(t1), "\"myname2\":", &alen);
515d4afb5ceSopenharmony_ci		if (mcp != t1 + 27 || alen != 6) {
516d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_json_simple_find 2 failed\n", __func__);
517d4afb5ceSopenharmony_ci			return 1;
518d4afb5ceSopenharmony_ci		}
519d4afb5ceSopenharmony_ci
520d4afb5ceSopenharmony_ci		mcp = lws_json_simple_find(t1, strlen(t1), "\"myname3\":", &alen);
521d4afb5ceSopenharmony_ci		if (mcp != t1 + 47 || alen != 3) {
522d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_json_simple_find 3 failed\n", __func__);
523d4afb5ceSopenharmony_ci			return 1;
524d4afb5ceSopenharmony_ci		}
525d4afb5ceSopenharmony_ci
526d4afb5ceSopenharmony_ci		mcp = lws_json_simple_find(t1, strlen(t1), "\"nope\":", &alen);
527d4afb5ceSopenharmony_ci		if (mcp != NULL) {
528d4afb5ceSopenharmony_ci			lwsl_err("%s: lws_json_simple_find 4 failed\n", __func__);
529d4afb5ceSopenharmony_ci			return 1;
530d4afb5ceSopenharmony_ci		}
531d4afb5ceSopenharmony_ci	}
532d4afb5ceSopenharmony_ci
533d4afb5ceSopenharmony_ci	p = lws_cmdline_option(argc, argv, "-s");
534d4afb5ceSopenharmony_ci
535d4afb5ceSopenharmony_ci	for (n = 0; n < (int)LWS_ARRAY_SIZE(tests); n++) {
536d4afb5ceSopenharmony_ci		int m = 0, in_fail = fail;
537d4afb5ceSopenharmony_ci		struct expected *exp = tests[n].exp;
538d4afb5ceSopenharmony_ci
539d4afb5ceSopenharmony_ci		memset(&ts, 0, sizeof(ts));
540d4afb5ceSopenharmony_ci		ts.start = tests[n].string;
541d4afb5ceSopenharmony_ci		ts.len = strlen(ts.start);
542d4afb5ceSopenharmony_ci		ts.flags = (uint16_t)tests[n].flags;
543d4afb5ceSopenharmony_ci
544d4afb5ceSopenharmony_ci		do {
545d4afb5ceSopenharmony_ci			e = lws_tokenize(&ts);
546d4afb5ceSopenharmony_ci
547d4afb5ceSopenharmony_ci			lws_strnncpy(dotstar, ts.token, ts.token_len,
548d4afb5ceSopenharmony_ci				     sizeof(dotstar));
549d4afb5ceSopenharmony_ci			lwsl_info("{ %s, \"%s\", %d }\n",
550d4afb5ceSopenharmony_ci				  element_names[e + LWS_TOKZE_ERRS], dotstar,
551d4afb5ceSopenharmony_ci				  (int)ts.token_len);
552d4afb5ceSopenharmony_ci
553d4afb5ceSopenharmony_ci			if (m == (int)tests[n].count) {
554d4afb5ceSopenharmony_ci				lwsl_notice("fail: expected end earlier\n");
555d4afb5ceSopenharmony_ci				fail++;
556d4afb5ceSopenharmony_ci				break;
557d4afb5ceSopenharmony_ci			}
558d4afb5ceSopenharmony_ci
559d4afb5ceSopenharmony_ci			if (e != exp->e) {
560d4afb5ceSopenharmony_ci				lwsl_notice("fail... tok %s vs expected %s\n",
561d4afb5ceSopenharmony_ci					element_names[e + LWS_TOKZE_ERRS],
562d4afb5ceSopenharmony_ci					element_names[exp->e + LWS_TOKZE_ERRS]);
563d4afb5ceSopenharmony_ci				fail++;
564d4afb5ceSopenharmony_ci				break;
565d4afb5ceSopenharmony_ci			}
566d4afb5ceSopenharmony_ci
567d4afb5ceSopenharmony_ci			if (e > 0 &&
568d4afb5ceSopenharmony_ci			    (ts.token_len != exp->len ||
569d4afb5ceSopenharmony_ci			     memcmp(exp->value, ts.token, exp->len))) {
570d4afb5ceSopenharmony_ci				lws_strnncpy(dotstar, ts.token, ts.token_len,
571d4afb5ceSopenharmony_ci					     sizeof(dotstar));
572d4afb5ceSopenharmony_ci				lwsl_notice("fail token mismatch %d %d %s\n",
573d4afb5ceSopenharmony_ci					    (int)ts.token_len, (int)exp->len,
574d4afb5ceSopenharmony_ci					    dotstar);
575d4afb5ceSopenharmony_ci				fail++;
576d4afb5ceSopenharmony_ci				break;
577d4afb5ceSopenharmony_ci			}
578d4afb5ceSopenharmony_ci
579d4afb5ceSopenharmony_ci			m++;
580d4afb5ceSopenharmony_ci			exp++;
581d4afb5ceSopenharmony_ci
582d4afb5ceSopenharmony_ci		} while (e > 0);
583d4afb5ceSopenharmony_ci
584d4afb5ceSopenharmony_ci		if (fail == in_fail)
585d4afb5ceSopenharmony_ci			ok++;
586d4afb5ceSopenharmony_ci	}
587d4afb5ceSopenharmony_ci
588d4afb5ceSopenharmony_ci	if (p) {
589d4afb5ceSopenharmony_ci		ts.start = p;
590d4afb5ceSopenharmony_ci		ts.len = strlen(p);
591d4afb5ceSopenharmony_ci		ts.flags = (uint16_t)flags;
592d4afb5ceSopenharmony_ci
593d4afb5ceSopenharmony_ci		printf("\t{\n\t\t\"%s\",\n"
594d4afb5ceSopenharmony_ci		       "\t\texpected%d, LWS_ARRAY_SIZE(expected%d),\n\t\t",
595d4afb5ceSopenharmony_ci		       p, (int)LWS_ARRAY_SIZE(tests) + 1,
596d4afb5ceSopenharmony_ci		       (int)LWS_ARRAY_SIZE(tests) + 1);
597d4afb5ceSopenharmony_ci
598d4afb5ceSopenharmony_ci		if (!flags)
599d4afb5ceSopenharmony_ci			printf("0\n\t},\n");
600d4afb5ceSopenharmony_ci		else {
601d4afb5ceSopenharmony_ci			if (flags & LWS_TOKENIZE_F_MINUS_NONTERM)
602d4afb5ceSopenharmony_ci				printf("LWS_TOKENIZE_F_MINUS_NONTERM");
603d4afb5ceSopenharmony_ci			if (flags & LWS_TOKENIZE_F_AGG_COLON) {
604d4afb5ceSopenharmony_ci				if (flags & 1)
605d4afb5ceSopenharmony_ci					printf(" | ");
606d4afb5ceSopenharmony_ci				printf("LWS_TOKENIZE_F_AGG_COLON");
607d4afb5ceSopenharmony_ci			}
608d4afb5ceSopenharmony_ci			if (flags & LWS_TOKENIZE_F_COMMA_SEP_LIST) {
609d4afb5ceSopenharmony_ci				if (flags & 3)
610d4afb5ceSopenharmony_ci					printf(" | ");
611d4afb5ceSopenharmony_ci				printf("LWS_TOKENIZE_F_COMMA_SEP_LIST");
612d4afb5ceSopenharmony_ci			}
613d4afb5ceSopenharmony_ci			if (flags & LWS_TOKENIZE_F_RFC7230_DELIMS) {
614d4afb5ceSopenharmony_ci				if (flags & 7)
615d4afb5ceSopenharmony_ci					printf(" | ");
616d4afb5ceSopenharmony_ci				printf("LWS_TOKENIZE_F_RFC7230_DELIMS");
617d4afb5ceSopenharmony_ci			}
618d4afb5ceSopenharmony_ci			if (flags & LWS_TOKENIZE_F_DOT_NONTERM) {
619d4afb5ceSopenharmony_ci				if (flags & 15)
620d4afb5ceSopenharmony_ci					printf(" | ");
621d4afb5ceSopenharmony_ci				printf("LWS_TOKENIZE_F_DOT_NONTERM");
622d4afb5ceSopenharmony_ci			}
623d4afb5ceSopenharmony_ci			if (flags & LWS_TOKENIZE_F_NO_FLOATS) {
624d4afb5ceSopenharmony_ci				if (flags & 31)
625d4afb5ceSopenharmony_ci					printf(" | ");
626d4afb5ceSopenharmony_ci				printf("LWS_TOKENIZE_F_NO_FLOATS");
627d4afb5ceSopenharmony_ci			}
628d4afb5ceSopenharmony_ci			printf("\n\t},\n");
629d4afb5ceSopenharmony_ci		}
630d4afb5ceSopenharmony_ci
631d4afb5ceSopenharmony_ci		printf("\texpected%d[] = {\n", (int)LWS_ARRAY_SIZE(tests) + 1);
632d4afb5ceSopenharmony_ci
633d4afb5ceSopenharmony_ci		do {
634d4afb5ceSopenharmony_ci			e = lws_tokenize(&ts);
635d4afb5ceSopenharmony_ci
636d4afb5ceSopenharmony_ci			lws_strnncpy(dotstar, ts.token, ts.token_len,
637d4afb5ceSopenharmony_ci				     sizeof(dotstar));
638d4afb5ceSopenharmony_ci
639d4afb5ceSopenharmony_ci			printf("\t\t{ %s, \"%s\", %d },\n",
640d4afb5ceSopenharmony_ci				  element_names[e + LWS_TOKZE_ERRS],
641d4afb5ceSopenharmony_ci				  dotstar, (int)ts.token_len);
642d4afb5ceSopenharmony_ci
643d4afb5ceSopenharmony_ci		} while (e > 0);
644d4afb5ceSopenharmony_ci
645d4afb5ceSopenharmony_ci		printf("\t}\n");
646d4afb5ceSopenharmony_ci	}
647d4afb5ceSopenharmony_ci
648d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
649d4afb5ceSopenharmony_ci	{
650d4afb5ceSopenharmony_ci		time_t t;
651d4afb5ceSopenharmony_ci
652d4afb5ceSopenharmony_ci		if (lws_http_date_parse_unix("Tue, 15 Nov 1994 08:12:31 GMT", 29, &t)) {
653d4afb5ceSopenharmony_ci			lwsl_err("%s: date parse failed\n", __func__);
654d4afb5ceSopenharmony_ci			fail++;
655d4afb5ceSopenharmony_ci		} else {
656d4afb5ceSopenharmony_ci			/* lwsl_notice("%s: %llu\n", __func__, (unsigned long long)t); */
657d4afb5ceSopenharmony_ci			if (t != (time_t)784887151) {
658d4afb5ceSopenharmony_ci				lwsl_err("%s: date parse wrong\n", __func__);
659d4afb5ceSopenharmony_ci				fail++;
660d4afb5ceSopenharmony_ci			} else {
661d4afb5ceSopenharmony_ci				char s[30];
662d4afb5ceSopenharmony_ci
663d4afb5ceSopenharmony_ci				if (lws_http_date_render_from_unix(s, sizeof(s), &t)) {
664d4afb5ceSopenharmony_ci					lwsl_err("%s: failed date render\n", __func__);
665d4afb5ceSopenharmony_ci					fail++;
666d4afb5ceSopenharmony_ci				} else {
667d4afb5ceSopenharmony_ci					if (!strcmp(s, "Tue, 15 Nov 1994 08:12:31 GMT")) {
668d4afb5ceSopenharmony_ci						lwsl_err("%s: date render wrong\n", __func__);
669d4afb5ceSopenharmony_ci						fail++;
670d4afb5ceSopenharmony_ci					}
671d4afb5ceSopenharmony_ci				}
672d4afb5ceSopenharmony_ci			}
673d4afb5ceSopenharmony_ci		}
674d4afb5ceSopenharmony_ci	}
675d4afb5ceSopenharmony_ci#endif
676d4afb5ceSopenharmony_ci
677d4afb5ceSopenharmony_ci	{
678d4afb5ceSopenharmony_ci		char buf[24];
679d4afb5ceSopenharmony_ci		int m;
680d4afb5ceSopenharmony_ci
681d4afb5ceSopenharmony_ci		m = lws_humanize(buf, sizeof(buf), 0, humanize_schema_si);
682d4afb5ceSopenharmony_ci		if (m != 1 || strcmp(buf, "0")) {
683d4afb5ceSopenharmony_ci			lwsl_user("%s: humanize 1 fail '%s' (%d)\n", __func__, buf, m);
684d4afb5ceSopenharmony_ci			fail++;
685d4afb5ceSopenharmony_ci		}
686d4afb5ceSopenharmony_ci		m = lws_humanize(buf, sizeof(buf), 2, humanize_schema_si);
687d4afb5ceSopenharmony_ci		if (m != 1 || strcmp(buf, "2")) {
688d4afb5ceSopenharmony_ci			lwsl_user("%s: humanize 2 fail '%s' (%d)\n", __func__, buf, m);
689d4afb5ceSopenharmony_ci			fail++;
690d4afb5ceSopenharmony_ci		}
691d4afb5ceSopenharmony_ci		m = lws_humanize(buf, sizeof(buf), 999, humanize_schema_si);
692d4afb5ceSopenharmony_ci		if (m != 3 || strcmp(buf, "999")) {
693d4afb5ceSopenharmony_ci			lwsl_user("%s: humanize 3 fail '%s' (%d)\n", __func__, buf, m);
694d4afb5ceSopenharmony_ci			fail++;
695d4afb5ceSopenharmony_ci		}
696d4afb5ceSopenharmony_ci		m = lws_humanize(buf, sizeof(buf), 1000, humanize_schema_si);
697d4afb5ceSopenharmony_ci		if (m != 4 || strcmp(buf, "1000")) {
698d4afb5ceSopenharmony_ci			lwsl_user("%s: humanize 4 fail '%s' (%d)\n", __func__, buf, m);
699d4afb5ceSopenharmony_ci			fail++;
700d4afb5ceSopenharmony_ci		}
701d4afb5ceSopenharmony_ci		m = lws_humanize(buf, sizeof(buf), 1024, humanize_schema_si);
702d4afb5ceSopenharmony_ci		if (m != 7 || strcmp(buf, "1.000Ki")) {
703d4afb5ceSopenharmony_ci			lwsl_user("%s: humanize 5 fail '%s' (%d)\n", __func__, buf, m);
704d4afb5ceSopenharmony_ci			fail++;
705d4afb5ceSopenharmony_ci		}
706d4afb5ceSopenharmony_ci	}
707d4afb5ceSopenharmony_ci
708d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("allied", 6, "allied", 6)) {
709d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 1 fail\n", __func__);
710d4afb5ceSopenharmony_ci		fail++;
711d4afb5ceSopenharmony_ci	}
712d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("a*", 2, "allied", 6)) {
713d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 2 fail\n", __func__);
714d4afb5ceSopenharmony_ci		fail++;
715d4afb5ceSopenharmony_ci	}
716d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("all*", 4, "allied", 6)) {
717d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 3 fail\n", __func__);
718d4afb5ceSopenharmony_ci		fail++;
719d4afb5ceSopenharmony_ci	}
720d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("all*d", 5, "allied", 6)) {
721d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 4 fail\n", __func__);
722d4afb5ceSopenharmony_ci		fail++;
723d4afb5ceSopenharmony_ci	}
724d4afb5ceSopenharmony_ci	if (!lws_strcmp_wildcard("b*", 2, "allied", 6)) {
725d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 5 fail\n", __func__);
726d4afb5ceSopenharmony_ci		fail++;
727d4afb5ceSopenharmony_ci	}
728d4afb5ceSopenharmony_ci	if (!lws_strcmp_wildcard("b*ed", 4, "allied", 6)) {
729d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 6 fail\n", __func__);
730d4afb5ceSopenharmony_ci		fail++;
731d4afb5ceSopenharmony_ci	}
732d4afb5ceSopenharmony_ci	if (!lws_strcmp_wildcard("allie", 5, "allied", 6)) {
733d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 7 fail\n", __func__);
734d4afb5ceSopenharmony_ci		fail++;
735d4afb5ceSopenharmony_ci	}
736d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("allie*", 6, "allied", 6)) {
737d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 8 fail\n", __func__);
738d4afb5ceSopenharmony_ci		fail++;
739d4afb5ceSopenharmony_ci	}
740d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("*llie*", 6, "allied", 6)) {
741d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 9 fail\n", __func__);
742d4afb5ceSopenharmony_ci		fail++;
743d4afb5ceSopenharmony_ci	}
744d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("*llied", 6, "allied", 6)) {
745d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 10 fail\n", __func__);
746d4afb5ceSopenharmony_ci		fail++;
747d4afb5ceSopenharmony_ci	}
748d4afb5ceSopenharmony_ci	if (!lws_strcmp_wildcard("*llie", 5, "allied", 6)) {
749d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 11 fail\n", __func__);
750d4afb5ceSopenharmony_ci		fail++;
751d4afb5ceSopenharmony_ci	}
752d4afb5ceSopenharmony_ci	if (!lws_strcmp_wildcard("*nope", 5, "allied", 6)) {
753d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 12 fail\n", __func__);
754d4afb5ceSopenharmony_ci		fail++;
755d4afb5ceSopenharmony_ci	}
756d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("*li*", 4, "allied", 6)) {
757d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 13 fail\n", __func__);
758d4afb5ceSopenharmony_ci		fail++;
759d4afb5ceSopenharmony_ci	}
760d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("*", 1, "allied", 6)) {
761d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 14 fail\n", __func__);
762d4afb5ceSopenharmony_ci		fail++;
763d4afb5ceSopenharmony_ci	}
764d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("*abc*d", 6, "xxabyyabcdd", 11)) {
765d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 15 fail\n", __func__);
766d4afb5ceSopenharmony_ci		fail++;
767d4afb5ceSopenharmony_ci	}
768d4afb5ceSopenharmony_ci	if (lws_strcmp_wildcard("ssproxy.n.cn.*", 14,
769d4afb5ceSopenharmony_ci				"ssproxy.n.cn.failures", 21)) {
770d4afb5ceSopenharmony_ci		lwsl_user("%s: wc 16 fail\n", __func__);
771d4afb5ceSopenharmony_ci		fail++;
772d4afb5ceSopenharmony_ci	}
773d4afb5ceSopenharmony_ci
774d4afb5ceSopenharmony_ci	lwsl_user("Completed: PASS: %d, FAIL: %d\n", ok, fail);
775d4afb5ceSopenharmony_ci
776d4afb5ceSopenharmony_ci	lws_context_destroy(cx);
777d4afb5ceSopenharmony_ci
778d4afb5ceSopenharmony_ci	return !(ok && !fail);
779d4afb5ceSopenharmony_ci}
780