1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi/native_api.h"
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <ctime>
22 #include <js_native_api.h>
23 #include <malloc.h>
24 #include <node_api.h>
25 #include <search.h>
26 #include <unistd.h>
27 #include <hilog/log.h>
28
29 #define PARAM_0 0
30 #define PARAM_5 5
31 #define PARAM_27 27
32 #define PARAM_1 1
33 #define PARAM_2 2
34 #define PARAM_10 10
35 #define PARAM_3 3
36 #define PARAM_24 24
37 #define PARAM_30 30
38 #define PARAM_22 22
39 #define PARAM_26 26
40 #define PARAM_0xff 0xff
41 #define PARAM_UNNORMAL (-1)
42 #define ERRON_0 0
43 #define TWICE 12
44 #define ARRAY_SIZE (10)
45 #define FAIL (-1)
46 #define NOERR 0
47 #define VALUE_ONE 1
48 #define VALUE_TWO 1
49 #define BUFFERSIZE 128
50 #define LOOPNUM 12
51 #undef LOG_DOMAIN
52 #undef LOG_TAG
53 #define LOG_DOMAIN 0xFEFE
54 #define LOG_TAG "MUSL_LIBCTEST"
55
56 static void *g_root = nullptr;
57
Compare(const void * pa,const void * pb)58 static int Compare(const void *pa, const void *pb)
59 {
60 if (*static_cast<const int *>(pa) < *static_cast<const int *>(pb))
61 return PARAM_UNNORMAL;
62 if (*static_cast<const int *>(pa) > *static_cast<const int *>(pb))
63 return VALUE_ONE;
64 return NOERR;
65 }
66
action(const void * nodep,VISIT which,int depth)67 static void action(const void *nodep, VISIT which, int depth)
68 {
69 int *datap = nullptr;
70
71 switch (which) {
72 case preorder:
73 break;
74 case postorder:
75 datap = *(int **)nodep;
76 printf("%6d\n", *datap);
77 break;
78 case endorder:
79 break;
80 case leaf:
81 datap = *(int **)nodep;
82 printf("%6d\n", *datap);
83 break;
84 }
85 }
86
Tdestroy(napi_env env,napi_callback_info info)87 static napi_value Tdestroy(napi_env env, napi_callback_info info)
88 {
89 void *rootParam = nullptr;
90 napi_value result = nullptr;
91 errno = ERRON_0;
92 tdestroy(rootParam, free);
93 napi_create_int32(env, errno, &result);
94 return result;
95 }
96
Tdelete(napi_env env,napi_callback_info info)97 static napi_value Tdelete(napi_env env, napi_callback_info info)
98 {
99 errno = ERRON_0;
100 tdelete(g_root, nullptr, nullptr);
101 napi_value result = nullptr;
102 napi_create_int32(env, errno, &result);
103 return result;
104 }
105
Tfind(napi_env env,napi_callback_info info)106 static napi_value Tfind(napi_env env, napi_callback_info info)
107 {
108 errno = ERRON_0;
109 tfind(g_root, nullptr, nullptr);
110 napi_value result = nullptr;
111 napi_create_int32(env, errno, &result);
112 return result;
113 }
114
Hcreate(napi_env env,napi_callback_info info)115 static napi_value Hcreate(napi_env env, napi_callback_info info)
116 {
117 int ret = PARAM_0;
118 ret = hcreate(BUFSIZ);
119 hdestroy();
120 napi_value result = nullptr;
121 if (ret == NOERR) {
122 napi_create_int32(env, FAIL, &result);
123 } else {
124 napi_create_int32(env, NOERR, &result);
125 }
126 return result;
127 }
128
HcreateR(napi_env env,napi_callback_info info)129 static napi_value HcreateR(napi_env env, napi_callback_info info)
130 {
131 int ret = PARAM_0;
132 struct hsearch_data h_data = {PARAM_0};
133 hcreate_r(BUFSIZ, &h_data);
134 hdestroy_r(&h_data);
135 napi_value result = nullptr;
136 if (ret == NOERR) {
137 napi_create_int32(env, FAIL, &result);
138 } else {
139 napi_create_int32(env, NOERR, &result);
140 }
141 return result;
142 }
143
Hdestroy(napi_env env,napi_callback_info info)144 static napi_value Hdestroy(napi_env env, napi_callback_info info)
145 {
146 int ret = PARAM_0;
147 ret = hcreate(BUFSIZ);
148 hdestroy();
149 ret = hcreate(BUFSIZ);
150 hdestroy();
151 napi_value result = nullptr;
152 if (ret == NOERR) {
153 napi_create_int32(env, FAIL, &result);
154 } else {
155 napi_create_int32(env, NOERR, &result);
156 }
157 return result;
158 }
159
HdestroyR(napi_env env,napi_callback_info info)160 static napi_value HdestroyR(napi_env env, napi_callback_info info)
161 {
162 int ret = PARAM_0;
163 struct hsearch_data h_data = {PARAM_0};
164 memset(&h_data, PARAM_0, sizeof(struct hsearch_data));
165 hcreate_r(BUFSIZ, &h_data);
166 hdestroy_r(&h_data);
167 memset(&h_data, PARAM_0, sizeof(struct hsearch_data));
168 ret = hcreate_r(BUFSIZ, &h_data);
169 hdestroy_r(&h_data);
170 napi_value result = nullptr;
171 if (ret == PARAM_0) {
172 napi_create_int32(env, FAIL, &result);
173 } else {
174 napi_create_int32(env, NOERR, &result);
175 }
176 return result;
177 }
178
179 static char data[][30] = {"alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india",
180 "juliet", "kilo", "lima", "mike", "november", "oscar", "papa", "quebec", "romeo",
181 "sierra", "tango", "uniform", "victor", "whisky", "x-ray", "yankee", "zulu"};
182
Hsearch(napi_env env,napi_callback_info info)183 static napi_value Hsearch(napi_env env, napi_callback_info info)
184 {
185 napi_value result = nullptr;
186 ENTRY e, *ep;
187 int i;
188
189 hcreate(PARAM_30);
190
191 for (i = PARAM_0; i < PARAM_24; i++) {
192 e.key = data[i];
193 e.data = (void *)&i;
194 ep = hsearch(e, ENTER);
195 if (ep == nullptr) {
196 napi_create_int32(env, FAIL, &result);
197 return result;
198 }
199 }
200
201 for (i = PARAM_22; i < PARAM_26; i++) {
202 e.key = data[i];
203 ep = hsearch(e, FIND);
204 }
205 hdestroy();
206 napi_create_int32(env, NOERR, &result);
207 return result;
208 }
209
HsearchR(napi_env env,napi_callback_info info)210 static napi_value HsearchR(napi_env env, napi_callback_info info)
211 {
212 napi_value result = nullptr;
213 struct hsearch_data *htab = (struct hsearch_data *)calloc(VALUE_ONE, sizeof(struct hsearch_data));
214 if (!htab) {
215 printf("calloc fail\n");
216 exit(NOERR);
217 }
218 if (hcreate_r(PARAM_10, htab) == PARAM_0) {
219 printf("hcreat_r fail\n");
220 exit(NOERR);
221 }
222 char keys[][8] = {"key1", "key2", "key3"};
223 char dataVal[][8] = {"yasuo", "kitty", "ruiwen"};
224 int i;
225 for (i = PARAM_0; i < PARAM_3; i++) {
226 ENTRY e, *ep;
227 e.key = keys[i];
228 e.data = (void *)(&dataVal[i]);
229 hsearch_r(e, ENTER, &ep, htab);
230 }
231 for (i = PARAM_0; i < PARAM_3; i++) {
232 ENTRY e2, *ep2;
233 e2.key = keys[i];
234 hsearch_r(e2, FIND, &ep2, htab);
235 if (ep2 != nullptr) {
236 napi_create_int32(env, NOERR, &result);
237 } else {
238 napi_create_int32(env, FAIL, &result);
239 }
240 }
241 hdestroy_r(htab);
242 if (htab) {
243 free(htab);
244 }
245 napi_create_int32(env, FAIL, &result);
246 return result;
247 }
248
249 struct Q {
250 struct Q *n;
251 struct Q *p;
252 int i;
253 };
254
Insque(napi_env env,napi_callback_info info)255 static napi_value Insque(napi_env env, napi_callback_info info)
256 {
257 struct Q elem = {PARAM_0};
258 insque(&elem, nullptr);
259 napi_value result = nullptr;
260 if (elem.n == nullptr && elem.p == nullptr) {
261 napi_create_int32(env, NOERR, &result);
262 } else {
263 napi_create_int32(env, FAIL, &result);
264 }
265 return result;
266 }
267
268 typedef int (*fc)(const void *, const void *);
269
LSearch(napi_env env,napi_callback_info info)270 static napi_value LSearch(napi_env env, napi_callback_info info)
271 {
272 int arr[5] = {27, 14, 29, 68, 55};
273 size_t n = PARAM_5;
274 int key = PARAM_27;
275 fc f = Compare;
276 int *ret = static_cast<int *>(lsearch(&key, arr, &n, sizeof(int), f));
277 napi_value result = nullptr;
278 if (ret) {
279 napi_create_int32(env, NOERR, &result);
280 } else {
281 napi_create_int32(env, FAIL, &result);
282 }
283 return result;
284 }
285
Lfind(napi_env env,napi_callback_info info)286 static napi_value Lfind(napi_env env, napi_callback_info info)
287 {
288 size_t argc = PARAM_2;
289 napi_value args[2] = {nullptr};
290 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
291 int array[3];
292 size_t nlength;
293 int key = PARAM_0;
294 void *ret = nullptr;
295 napi_get_value_int32(env, args[0], array);
296 napi_get_value_int32(env, args[0], array + VALUE_ONE);
297 napi_get_value_int32(env, args[0], array + VALUE_TWO);
298 napi_get_value_int32(env, args[0], &key);
299 ret = lfind(&key, array, &nlength, sizeof(int), Compare);
300 napi_value result = nullptr;
301 if (ret == nullptr) {
302 napi_create_int32(env, FAIL, &result);
303 } else {
304 napi_create_int32(env, NOERR, &result);
305 }
306 return result;
307 }
308
Remque(napi_env env,napi_callback_info info)309 static napi_value Remque(napi_env env, napi_callback_info info)
310 {
311 napi_value result = nullptr;
312 errno = NOERR;
313 struct Q *elem = (struct Q *)malloc(sizeof(struct Q));
314 if (elem == nullptr) {
315 OH_LOG_INFO(LOG_APP, "Remque malloc failed");
316 napi_create_int32(env, FAIL, &result);
317 return result;
318 }
319 insque(elem, nullptr);
320 remque(elem);
321 if (errno == NOERR) {
322 napi_create_int32(env, NOERR, &result);
323 } else {
324 napi_create_int32(env, FAIL, &result);
325 }
326 return result;
327 }
328
329 struct stu {
330 int stu_no;
331 char name[BUFFERSIZE];
332 };
333
334 typedef struct stu stu_t;
CompareStu(const void * pa,const void * pb)335 int CompareStu(const void *pa, const void *pb) { return ((stu_t *)pa)->stu_no - ((stu_t *)pb)->stu_no; }
336
Tsearch(napi_env env,napi_callback_info info)337 static napi_value Tsearch(napi_env env, napi_callback_info info)
338 {
339 void *rootVal = nullptr;
340 stu_t stuSturct;
341 sprintf(stuSturct.name, "shanghai_%d", stuSturct.stu_no);
342 stu_t **rtp = (stu_t **)tsearch(&stuSturct, &rootVal, CompareStu);
343 napi_value result = nullptr;
344 if (rtp != nullptr) {
345 napi_create_int32(env, NOERR, &result);
346 } else {
347 napi_create_int32(env, FAIL, &result);
348 }
349
350 return result;
351 }
352
Twalk(napi_env env,napi_callback_info info)353 static napi_value Twalk(napi_env env, napi_callback_info info)
354 {
355 int i = PARAM_0, *ptr = nullptr;
356 void *val = nullptr;
357 void *rootVal = nullptr;
358 napi_value result = nullptr;
359 srand(time(nullptr));
360 for (i = PARAM_0; i < LOOPNUM; i++) {
361 ptr = static_cast<int *>(malloc(sizeof(int)));
362 if (ptr == nullptr) {
363 OH_LOG_INFO(LOG_APP, "Twalk malloc failed");
364 napi_create_int32(env, FAIL, &result);
365 return result;
366 }
367 *ptr = rand() & PARAM_0xff;
368 val = tsearch((void *)ptr, &rootVal, Compare);
369 if (val == nullptr)
370 exit(EXIT_FAILURE);
371 else if ((*(int **)val) != ptr)
372 free(ptr);
373 }
374 twalk(rootVal, action);
375 tdestroy(rootVal, free);
376 if (rootVal != nullptr) {
377 napi_create_int32(env, NOERR, &result);
378 } else {
379 napi_create_int32(env, FAIL, &result);
380 }
381 return result;
382 }
383
384 EXTERN_C_START
Init(napi_env env,napi_value exports)385 static napi_value Init(napi_env env, napi_value exports)
386 {
387 napi_property_descriptor desc[] = {
388 {"tdestroy", nullptr, Tdestroy, nullptr, nullptr, nullptr, napi_default, nullptr},
389 {"tdelete", nullptr, Tdelete, nullptr, nullptr, nullptr, napi_default, nullptr},
390 {"tfind", nullptr, Tfind, nullptr, nullptr, nullptr, napi_default, nullptr},
391 {"hcreate", nullptr, Hcreate, nullptr, nullptr, nullptr, napi_default, nullptr},
392 {"hcreateR", nullptr, HcreateR, nullptr, nullptr, nullptr, napi_default, nullptr},
393 {"hdestroy", nullptr, Hdestroy, nullptr, nullptr, nullptr, napi_default, nullptr},
394 {"hdestroyR", nullptr, HdestroyR, nullptr, nullptr, nullptr, napi_default, nullptr},
395 {"hsearch", nullptr, Hsearch, nullptr, nullptr, nullptr, napi_default, nullptr},
396 {"hsearchR", nullptr, HsearchR, nullptr, nullptr, nullptr, napi_default, nullptr},
397 {"insque", nullptr, Insque, nullptr, nullptr, nullptr, napi_default, nullptr},
398 {"lSearch", nullptr, LSearch, nullptr, nullptr, nullptr, napi_default, nullptr},
399 {"lfind", nullptr, Lfind, nullptr, nullptr, nullptr, napi_default, nullptr},
400 {"remque", nullptr, Remque, nullptr, nullptr, nullptr, napi_default, nullptr},
401 {"tsearch", nullptr, Tsearch, nullptr, nullptr, nullptr, napi_default, nullptr},
402 {"twalk", nullptr, Twalk, nullptr, nullptr, nullptr, napi_default, nullptr},
403 };
404 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
405 return exports;
406 }
407
408 EXTERN_C_END
409
410 static napi_module demoModule = {
411 .nm_version = 1,
412 .nm_flags = 0,
413 .nm_filename = nullptr,
414 .nm_register_func = Init,
415 .nm_modname = "search",
416 .nm_priv = ((void *)0),
417 .reserved = {0},
418 };
419
RegisterEntryModule(void)420 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
421