xref: /aosp_15_r20/external/libwebsockets/minimal-examples/api-tests/api-test-fts/main.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * lws-api-test-fts - lws full-text search api test
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Written in 2010-2019 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker  * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker  */
9*1c60b9acSAndroid Build Coastguard Worker 
10*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
11*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
12*1c60b9acSAndroid Build Coastguard Worker #include <getopt.h>
13*1c60b9acSAndroid Build Coastguard Worker #endif
14*1c60b9acSAndroid Build Coastguard Worker #include <fcntl.h>
15*1c60b9acSAndroid Build Coastguard Worker 
16*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
17*1c60b9acSAndroid Build Coastguard Worker static struct option options[] = {
18*1c60b9acSAndroid Build Coastguard Worker 	{ "help",	no_argument,		NULL, 'h' },
19*1c60b9acSAndroid Build Coastguard Worker 	{ "createindex", no_argument,		NULL, 'c' },
20*1c60b9acSAndroid Build Coastguard Worker 	{ "index",	required_argument,	NULL, 'i' },
21*1c60b9acSAndroid Build Coastguard Worker 	{ "debug",	required_argument,	NULL, 'd' },
22*1c60b9acSAndroid Build Coastguard Worker 	{ "file",	required_argument,	NULL, 'f' },
23*1c60b9acSAndroid Build Coastguard Worker 	{ "lines",	required_argument,	NULL, 'l' },
24*1c60b9acSAndroid Build Coastguard Worker 	{ NULL, 0, 0, 0 }
25*1c60b9acSAndroid Build Coastguard Worker };
26*1c60b9acSAndroid Build Coastguard Worker #endif
27*1c60b9acSAndroid Build Coastguard Worker 
28*1c60b9acSAndroid Build Coastguard Worker static const char *index_filepath = "/tmp/lws-fts-test-index";
29*1c60b9acSAndroid Build Coastguard Worker static char filepath[256];
30*1c60b9acSAndroid Build Coastguard Worker 
main(int argc,char ** argv)31*1c60b9acSAndroid Build Coastguard Worker int main(int argc, char **argv)
32*1c60b9acSAndroid Build Coastguard Worker {
33*1c60b9acSAndroid Build Coastguard Worker 	int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
34*1c60b9acSAndroid Build Coastguard Worker 	int fd, fi, ft, createindex = 0, flags = LWSFTS_F_QUERY_AUTOCOMPLETE;
35*1c60b9acSAndroid Build Coastguard Worker 	struct lws_fts_search_params params;
36*1c60b9acSAndroid Build Coastguard Worker 	struct lws_fts_result *result;
37*1c60b9acSAndroid Build Coastguard Worker 	struct lws_fts_file *jtf;
38*1c60b9acSAndroid Build Coastguard Worker 	struct lws_fts *t;
39*1c60b9acSAndroid Build Coastguard Worker 	char buf[16384];
40*1c60b9acSAndroid Build Coastguard Worker 
41*1c60b9acSAndroid Build Coastguard Worker 	do {
42*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
43*1c60b9acSAndroid Build Coastguard Worker 		n = getopt_long(argc, argv, "hd:i:cfl", options, NULL);
44*1c60b9acSAndroid Build Coastguard Worker #else
45*1c60b9acSAndroid Build Coastguard Worker        n = getopt(argc, argv, "hd:i:cfl");
46*1c60b9acSAndroid Build Coastguard Worker #endif
47*1c60b9acSAndroid Build Coastguard Worker 		if (n < 0)
48*1c60b9acSAndroid Build Coastguard Worker 			continue;
49*1c60b9acSAndroid Build Coastguard Worker 		switch (n) {
50*1c60b9acSAndroid Build Coastguard Worker 		case 'i':
51*1c60b9acSAndroid Build Coastguard Worker 			strncpy(filepath, optarg, sizeof(filepath) - 1);
52*1c60b9acSAndroid Build Coastguard Worker 			filepath[sizeof(filepath) - 1] = '\0';
53*1c60b9acSAndroid Build Coastguard Worker 			index_filepath = filepath;
54*1c60b9acSAndroid Build Coastguard Worker 			break;
55*1c60b9acSAndroid Build Coastguard Worker 		case 'd':
56*1c60b9acSAndroid Build Coastguard Worker 			logs = atoi(optarg);
57*1c60b9acSAndroid Build Coastguard Worker 			break;
58*1c60b9acSAndroid Build Coastguard Worker 		case 'c':
59*1c60b9acSAndroid Build Coastguard Worker 			createindex = 1;
60*1c60b9acSAndroid Build Coastguard Worker 			break;
61*1c60b9acSAndroid Build Coastguard Worker 		case 'f':
62*1c60b9acSAndroid Build Coastguard Worker 			flags &= ~LWSFTS_F_QUERY_AUTOCOMPLETE;
63*1c60b9acSAndroid Build Coastguard Worker 			flags |= LWSFTS_F_QUERY_FILES;
64*1c60b9acSAndroid Build Coastguard Worker 			break;
65*1c60b9acSAndroid Build Coastguard Worker 		case 'l':
66*1c60b9acSAndroid Build Coastguard Worker 			flags |= LWSFTS_F_QUERY_FILES |
67*1c60b9acSAndroid Build Coastguard Worker 				 LWSFTS_F_QUERY_FILE_LINES;
68*1c60b9acSAndroid Build Coastguard Worker 			break;
69*1c60b9acSAndroid Build Coastguard Worker 		case 'h':
70*1c60b9acSAndroid Build Coastguard Worker 			fprintf(stderr,
71*1c60b9acSAndroid Build Coastguard Worker 				"Usage: %s [--createindex]"
72*1c60b9acSAndroid Build Coastguard Worker 					"[--index=<index filepath>] "
73*1c60b9acSAndroid Build Coastguard Worker 					"[-d <log bitfield>] file1 file2 \n",
74*1c60b9acSAndroid Build Coastguard Worker 					argv[0]);
75*1c60b9acSAndroid Build Coastguard Worker 			exit(1);
76*1c60b9acSAndroid Build Coastguard Worker 		}
77*1c60b9acSAndroid Build Coastguard Worker 	} while (n >= 0);
78*1c60b9acSAndroid Build Coastguard Worker 
79*1c60b9acSAndroid Build Coastguard Worker 	lws_set_log_level(logs, NULL);
80*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("LWS API selftest: full-text search\n");
81*1c60b9acSAndroid Build Coastguard Worker 
82*1c60b9acSAndroid Build Coastguard Worker 	if (createindex) {
83*1c60b9acSAndroid Build Coastguard Worker 
84*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("Creating index\n");
85*1c60b9acSAndroid Build Coastguard Worker 
86*1c60b9acSAndroid Build Coastguard Worker 		/*
87*1c60b9acSAndroid Build Coastguard Worker 		 * create an index by shifting through argv and indexing each
88*1c60b9acSAndroid Build Coastguard Worker 		 * file given there into a single combined index
89*1c60b9acSAndroid Build Coastguard Worker 		 */
90*1c60b9acSAndroid Build Coastguard Worker 
91*1c60b9acSAndroid Build Coastguard Worker 		ft = open(index_filepath, O_CREAT | O_WRONLY | O_TRUNC, 0600);
92*1c60b9acSAndroid Build Coastguard Worker 		if (ft < 0) {
93*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: can't open index %s\n", __func__,
94*1c60b9acSAndroid Build Coastguard Worker 				 index_filepath);
95*1c60b9acSAndroid Build Coastguard Worker 
96*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
97*1c60b9acSAndroid Build Coastguard Worker 		}
98*1c60b9acSAndroid Build Coastguard Worker 
99*1c60b9acSAndroid Build Coastguard Worker 		t = lws_fts_create(ft);
100*1c60b9acSAndroid Build Coastguard Worker 		if (!t) {
101*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: Unable to allocate trie\n", __func__);
102*1c60b9acSAndroid Build Coastguard Worker 
103*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
104*1c60b9acSAndroid Build Coastguard Worker 		}
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker 		while (optind < argc) {
107*1c60b9acSAndroid Build Coastguard Worker 
108*1c60b9acSAndroid Build Coastguard Worker 			fi = lws_fts_file_index(t, argv[optind],
109*1c60b9acSAndroid Build Coastguard Worker 						(int)strlen(argv[optind]), 1);
110*1c60b9acSAndroid Build Coastguard Worker 			if (fi < 0) {
111*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: Failed to get file idx for %s\n",
112*1c60b9acSAndroid Build Coastguard Worker 					 __func__, argv[optind]);
113*1c60b9acSAndroid Build Coastguard Worker 
114*1c60b9acSAndroid Build Coastguard Worker 				goto bail1;
115*1c60b9acSAndroid Build Coastguard Worker 			}
116*1c60b9acSAndroid Build Coastguard Worker 
117*1c60b9acSAndroid Build Coastguard Worker 			fd = open(argv[optind], O_RDONLY);
118*1c60b9acSAndroid Build Coastguard Worker 			if (fd < 0) {
119*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("unable to open %s for read\n",
120*1c60b9acSAndroid Build Coastguard Worker 						argv[optind]);
121*1c60b9acSAndroid Build Coastguard Worker 				goto bail;
122*1c60b9acSAndroid Build Coastguard Worker 			}
123*1c60b9acSAndroid Build Coastguard Worker 
124*1c60b9acSAndroid Build Coastguard Worker 			do {
125*1c60b9acSAndroid Build Coastguard Worker 				int n = (int)read(fd, buf, sizeof(buf));
126*1c60b9acSAndroid Build Coastguard Worker 
127*1c60b9acSAndroid Build Coastguard Worker 				if (n <= 0)
128*1c60b9acSAndroid Build Coastguard Worker 					break;
129*1c60b9acSAndroid Build Coastguard Worker 
130*1c60b9acSAndroid Build Coastguard Worker 				if (lws_fts_fill(t, (uint32_t)fi, buf, (size_t)n)) {
131*1c60b9acSAndroid Build Coastguard Worker 					lwsl_err("%s: lws_fts_fill failed\n",
132*1c60b9acSAndroid Build Coastguard Worker 						 __func__);
133*1c60b9acSAndroid Build Coastguard Worker 					close(fd);
134*1c60b9acSAndroid Build Coastguard Worker 
135*1c60b9acSAndroid Build Coastguard Worker 					goto bail;
136*1c60b9acSAndroid Build Coastguard Worker 				}
137*1c60b9acSAndroid Build Coastguard Worker 
138*1c60b9acSAndroid Build Coastguard Worker 			} while (1);
139*1c60b9acSAndroid Build Coastguard Worker 
140*1c60b9acSAndroid Build Coastguard Worker 			close(fd);
141*1c60b9acSAndroid Build Coastguard Worker 			optind++;
142*1c60b9acSAndroid Build Coastguard Worker 		}
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 		if (lws_fts_serialize(t)) {
145*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: serialize failed\n", __func__);
146*1c60b9acSAndroid Build Coastguard Worker 
147*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
148*1c60b9acSAndroid Build Coastguard Worker 		}
149*1c60b9acSAndroid Build Coastguard Worker 
150*1c60b9acSAndroid Build Coastguard Worker 		lws_fts_destroy(&t);
151*1c60b9acSAndroid Build Coastguard Worker 		close(ft);
152*1c60b9acSAndroid Build Coastguard Worker 
153*1c60b9acSAndroid Build Coastguard Worker 		return 0;
154*1c60b9acSAndroid Build Coastguard Worker 	}
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker 	/*
157*1c60b9acSAndroid Build Coastguard Worker 	 * shift through argv searching for each token
158*1c60b9acSAndroid Build Coastguard Worker 	 */
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker 	jtf = lws_fts_open(index_filepath);
161*1c60b9acSAndroid Build Coastguard Worker 	if (!jtf)
162*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
163*1c60b9acSAndroid Build Coastguard Worker 
164*1c60b9acSAndroid Build Coastguard Worker 	while (optind < argc) {
165*1c60b9acSAndroid Build Coastguard Worker 
166*1c60b9acSAndroid Build Coastguard Worker 		struct lws_fts_result_autocomplete *ac;
167*1c60b9acSAndroid Build Coastguard Worker 		struct lws_fts_result_filepath *fp;
168*1c60b9acSAndroid Build Coastguard Worker 		uint32_t *l, n;
169*1c60b9acSAndroid Build Coastguard Worker 
170*1c60b9acSAndroid Build Coastguard Worker 		memset(&params, 0, sizeof(params));
171*1c60b9acSAndroid Build Coastguard Worker 
172*1c60b9acSAndroid Build Coastguard Worker 		params.needle = argv[optind];
173*1c60b9acSAndroid Build Coastguard Worker 		params.flags = flags;
174*1c60b9acSAndroid Build Coastguard Worker 		params.max_autocomplete = 20;
175*1c60b9acSAndroid Build Coastguard Worker 		params.max_files = 20;
176*1c60b9acSAndroid Build Coastguard Worker 
177*1c60b9acSAndroid Build Coastguard Worker 		result = lws_fts_search(jtf, &params);
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 		if (!result) {
180*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: search failed\n", __func__);
181*1c60b9acSAndroid Build Coastguard Worker 			lws_fts_close(jtf);
182*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
183*1c60b9acSAndroid Build Coastguard Worker 		}
184*1c60b9acSAndroid Build Coastguard Worker 
185*1c60b9acSAndroid Build Coastguard Worker 		ac = result->autocomplete_head;
186*1c60b9acSAndroid Build Coastguard Worker 		fp = result->filepath_head;
187*1c60b9acSAndroid Build Coastguard Worker 
188*1c60b9acSAndroid Build Coastguard Worker 		if (!ac)
189*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: no autocomplete results\n", __func__);
190*1c60b9acSAndroid Build Coastguard Worker 
191*1c60b9acSAndroid Build Coastguard Worker 		while (ac) {
192*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: AC %s: %d agg hits\n", __func__,
193*1c60b9acSAndroid Build Coastguard Worker 				((char *)(ac + 1)), ac->instances);
194*1c60b9acSAndroid Build Coastguard Worker 
195*1c60b9acSAndroid Build Coastguard Worker 			ac = ac->next;
196*1c60b9acSAndroid Build Coastguard Worker 		}
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker 		if (!fp)
199*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: no filepath results\n", __func__);
200*1c60b9acSAndroid Build Coastguard Worker 
201*1c60b9acSAndroid Build Coastguard Worker 		while (fp) {
202*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: %s: (%d lines) %d hits \n", __func__,
203*1c60b9acSAndroid Build Coastguard Worker 				(((char *)(fp + 1)) + fp->matches_length),
204*1c60b9acSAndroid Build Coastguard Worker 				fp->lines_in_file, fp->matches);
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 			if (fp->matches_length) {
207*1c60b9acSAndroid Build Coastguard Worker 				l = (uint32_t *)(fp + 1);
208*1c60b9acSAndroid Build Coastguard Worker 				n = 0;
209*1c60b9acSAndroid Build Coastguard Worker 				while ((int)n++ < fp->matches)
210*1c60b9acSAndroid Build Coastguard Worker 					lwsl_notice(" %d\n", *l++);
211*1c60b9acSAndroid Build Coastguard Worker 			}
212*1c60b9acSAndroid Build Coastguard Worker 			fp = fp->next;
213*1c60b9acSAndroid Build Coastguard Worker 		}
214*1c60b9acSAndroid Build Coastguard Worker 
215*1c60b9acSAndroid Build Coastguard Worker 		lwsac_free(&params.results_head);
216*1c60b9acSAndroid Build Coastguard Worker 
217*1c60b9acSAndroid Build Coastguard Worker 		optind++;
218*1c60b9acSAndroid Build Coastguard Worker 	}
219*1c60b9acSAndroid Build Coastguard Worker 
220*1c60b9acSAndroid Build Coastguard Worker 	lws_fts_close(jtf);
221*1c60b9acSAndroid Build Coastguard Worker 
222*1c60b9acSAndroid Build Coastguard Worker 	return 0;
223*1c60b9acSAndroid Build Coastguard Worker 
224*1c60b9acSAndroid Build Coastguard Worker bail1:
225*1c60b9acSAndroid Build Coastguard Worker 	close(ft);
226*1c60b9acSAndroid Build Coastguard Worker bail:
227*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("FAILED\n");
228*1c60b9acSAndroid Build Coastguard Worker 
229*1c60b9acSAndroid Build Coastguard Worker 	return 1;
230*1c60b9acSAndroid Build Coastguard Worker }
231