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(¶ms, 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, ¶ms);
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(¶ms.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