clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name index.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/isvv/naviserver/nsd -resource-dir /usr/local/lib/clang/15.0.0 -D _FORTIFY_SOURCE=2 -D NDEBUG -D SYSTEM_MALLOC -I ../include -I /usr/include/tcl8.6 -D HAVE_CONFIG_H -internal-isystem /usr/local/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c99 -fdebug-compilation-dir=/home/isvv/naviserver/nsd -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker alpha -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-07-23-130959-11103-1 -x c index.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | #include "nsd.h" |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | static ssize_t BinSearch(void *const*elPtrPtr, void *const* listPtrPtr, ssize_t n, Ns_IndexCmpProc *cmpProc) |
44 | NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(4); |
45 | static ssize_t BinSearchKey(const void *key, void *const*listPtrPtr, ssize_t n, Ns_IndexCmpProc *cmpProc) |
46 | NS_GNUC_NONNULL(1) NS_GNUC_NONNULL(2) NS_GNUC_NONNULL(4); |
47 | |
48 | static Ns_IndexCmpProc CmpStr; |
49 | static Ns_IndexKeyCmpProc CmpKeyWithStr; |
50 | |
51 | static Ns_IndexCmpProc CmpInts; |
52 | static Ns_IndexKeyCmpProc CmpKeyWithInt; |
53 | |
54 | #ifdef _MSC_VER_VERY_OLD |
55 | static void * |
56 | NsBsearch (register const void *key, register const void *base, |
57 | register size_t nmemb, register size_t size, |
58 | int (*compar)(const void *left, const void *right)); |
59 | #endif |
60 | |
61 |
|
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | void |
79 | Ns_IndexInit(Ns_Index *indexPtr, size_t inc, |
80 | int (*CmpEls) (const void *left, const void *right), |
81 | int (*CmpKeyWithEl) (const void *left, const void *right)) |
82 | { |
83 | |
84 | NS_NONNULL_ASSERT(indexPtr != NULL); |
85 | NS_NONNULL_ASSERT(CmpEls != NULL); |
86 | NS_NONNULL_ASSERT(CmpKeyWithEl != NULL); |
87 | |
88 | indexPtr->n = 0u; |
89 | indexPtr->max = inc; |
90 | indexPtr->inc = inc; |
91 | |
92 | indexPtr->CmpEls = CmpEls; |
93 | indexPtr->CmpKeyWithEl = CmpKeyWithEl; |
94 | |
95 | indexPtr->el = (void **) ns_malloc((size_t)inc * sizeof(void *)); |
96 | } |
97 | |
98 |
|
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | void |
116 | Ns_IndexTrunc(Ns_Index* indexPtr) |
117 | { |
118 | NS_NONNULL_ASSERT(indexPtr != NULL); |
119 | |
120 | indexPtr->n = 0u; |
121 | ns_free(indexPtr->el); |
122 | indexPtr->max = indexPtr->inc; |
123 | indexPtr->el = (void **) ns_malloc((size_t)indexPtr->inc * sizeof(void *)); |
124 | } |
125 | |
126 |
|
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | void |
144 | Ns_IndexDestroy(Ns_Index *indexPtr) |
145 | { |
146 | NS_NONNULL_ASSERT(indexPtr != NULL); |
147 | |
148 | indexPtr->CmpEls = NULL; |
149 | indexPtr->CmpKeyWithEl = NULL; |
150 | ns_free(indexPtr->el); |
151 | } |
152 | |
153 |
|
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | Ns_Index * |
171 | Ns_IndexDup(const Ns_Index *indexPtr) |
172 | { |
173 | Ns_Index *newPtr; |
174 | |
175 | NS_NONNULL_ASSERT(indexPtr != NULL); |
176 | |
177 | newPtr = (Ns_Index *) ns_malloc(sizeof(Ns_Index)); |
178 | memcpy(newPtr, indexPtr, sizeof(Ns_Index)); |
179 | newPtr->el = (void **) ns_malloc(indexPtr->max * sizeof(void *)); |
180 | memcpy(newPtr->el, indexPtr->el, indexPtr->n * sizeof(void *)); |
181 | |
182 | return newPtr; |
183 | } |
184 | |
185 |
|
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | void * |
203 | Ns_IndexFind(const Ns_Index *indexPtr, const void *key) |
204 | { |
205 | void *const *pPtrPtr; |
206 | |
207 | NS_NONNULL_ASSERT(indexPtr != NULL); |
208 | NS_NONNULL_ASSERT(key != NULL); |
209 | |
210 | pPtrPtr = (void **) bsearch(key, indexPtr->el, indexPtr->n, |
211 | sizeof(void *), indexPtr->CmpKeyWithEl); |
212 | |
213 | return (pPtrPtr != NULL) ? *pPtrPtr : NULL; |
214 | } |
215 | |
216 |
|
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
233 | |
234 | |
235 | void * |
236 | Ns_IndexFindInf(const Ns_Index *indexPtr, const void *key) |
237 | { |
238 | void *result = NULL; |
239 | |
240 | NS_NONNULL_ASSERT(indexPtr != NULL); |
241 | NS_NONNULL_ASSERT(key != NULL); |
242 | |
243 | if (indexPtr->n > 0u) { |
244 | ssize_t i = BinSearchKey(key, indexPtr->el, (ssize_t)indexPtr->n, |
245 | indexPtr->CmpKeyWithEl); |
246 | |
247 | if (i < (ssize_t)indexPtr->n) { |
248 | if ((i > 0) && |
249 | ((indexPtr->CmpKeyWithEl)(key, &(indexPtr->el[i])) != 0)) { |
250 | result = indexPtr->el[i - 1]; |
251 | } else { |
252 | result = indexPtr->el[i]; |
253 | } |
254 | } |
255 | } |
256 | |
257 | return result; |
258 | } |
259 | |
260 |
|
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | void ** |
279 | Ns_IndexFindMultiple(const Ns_Index *indexPtr, const void *key) |
280 | { |
281 | void *const *firstPtrPtr; |
282 | void **retPtrPtr = NULL; |
283 | |
284 | NS_NONNULL_ASSERT(indexPtr != NULL); |
285 | NS_NONNULL_ASSERT(key != NULL); |
286 | |
287 | |
288 | |
289 | |
290 | firstPtrPtr = (void **) bsearch(key, indexPtr->el, indexPtr->n, |
291 | sizeof(void *), indexPtr->CmpKeyWithEl); |
292 | |
293 | if (firstPtrPtr != NULL) { |
| 1 | Assuming 'firstPtrPtr' is not equal to NULL | |
|
| |
294 | size_t i, n; |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | while (firstPtrPtr != indexPtr->el |
| 3 | | Assuming 'firstPtrPtr' is not equal to field 'el' | |
|
| 5 | | Loop condition is true. Entering loop body | |
|
| 6 | | Assuming 'firstPtrPtr' is equal to field 'el' | |
|
301 | && indexPtr->CmpKeyWithEl(key, firstPtrPtr - 1) == 0) { |
| 4 | | Assuming the condition is true | |
|
302 | firstPtrPtr--; |
303 | } |
304 | |
305 | |
306 | |
307 | |
308 | n = indexPtr->n - (size_t)(firstPtrPtr - indexPtr->el); |
309 | for (i = 1u; |
310 | i < n && indexPtr->CmpKeyWithEl(key, firstPtrPtr + i) == 0; |
| |
311 | i++) { |
312 | ; |
313 | } |
314 | |
315 | |
316 | |
317 | |
318 | retPtrPtr = ns_malloc((i + 1u) * sizeof(void *)); |
319 | if (unlikely(retPtrPtr == NULL)) { |
| 8 | | Assuming 'retPtrPtr' is not equal to null | |
|
| |
320 | Ns_Fatal("IndexFindMultiple: out of memory while allocating result"); |
321 | } else { |
322 | memcpy(retPtrPtr, firstPtrPtr, i * sizeof(void *)); |
| 10 | | Memory copy function accesses out-of-bound array element |
|
323 | retPtrPtr[i] = NULL; |
324 | } |
325 | } |
326 | |
327 | return retPtrPtr; |
328 | } |
329 | |
330 |
|
331 | |
332 | |
333 | |
334 | |
335 | |
336 | |
337 | |
338 | |
339 | |
340 | |
341 | |
342 | |
343 | |
344 | |
345 | |
346 | |
347 | |
348 | static ssize_t |
349 | BinSearch(void *const* elPtrPtr, void *const* listPtrPtr, ssize_t n, Ns_IndexCmpProc *cmpProc) |
350 | { |
351 | ssize_t low = 0, high = n-1, mid = 0; |
352 | |
353 | NS_NONNULL_ASSERT(elPtrPtr != NULL); |
354 | NS_NONNULL_ASSERT(listPtrPtr != NULL); |
355 | NS_NONNULL_ASSERT(cmpProc != NULL); |
356 | |
357 | while (low <= high) { |
358 | int cond; |
359 | |
360 | mid = (low + high) / 2; |
361 | cond = (*cmpProc) (elPtrPtr, ((const unsigned char *const*)listPtrPtr) + mid); |
362 | if (cond < 0) { |
363 | high = mid - 1; |
364 | } else if (cond > 0) { |
365 | low = mid + 1; |
366 | } else { |
367 | return mid; |
368 | } |
369 | } |
370 | return (high < mid) ? mid : low; |
371 | } |
372 | |
373 |
|
374 | |
375 | |
376 | |
377 | |
378 | |
379 | |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | static ssize_t |
392 | BinSearchKey(const void *key, void *const* listPtrPtr, ssize_t n, Ns_IndexCmpProc *cmpProc) |
393 | { |
394 | ssize_t low = 0, high = n-1, mid = 0; |
395 | |
396 | NS_NONNULL_ASSERT(key != NULL); |
397 | NS_NONNULL_ASSERT(listPtrPtr != NULL); |
398 | NS_NONNULL_ASSERT(cmpProc != NULL); |
399 | |
400 | while (low <= high) { |
401 | int cond; |
402 | |
403 | mid = (low + high) / 2; |
404 | cond = (*cmpProc)(key, ((const unsigned char *const*)listPtrPtr) + mid); |
405 | if (cond < 0) { |
406 | high = mid - 1; |
407 | } else if (cond > 0) { |
408 | low = mid + 1; |
409 | } else { |
410 | return mid; |
411 | } |
412 | } |
413 | return (high < mid) ? mid : low; |
414 | } |
415 | |
416 |
|
417 | |
418 | |
419 | |
420 | |
421 | |
422 | |
423 | |
424 | |
425 | |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | |
432 | |
433 | void |
434 | Ns_IndexAdd(Ns_Index *indexPtr, void *el) |
435 | { |
436 | ssize_t i; |
437 | |
438 | NS_NONNULL_ASSERT(indexPtr != NULL); |
439 | NS_NONNULL_ASSERT(el != NULL); |
440 | |
441 | if (indexPtr->n == indexPtr->max) { |
442 | indexPtr->max += indexPtr->inc; |
443 | indexPtr->el = (void **) ns_realloc(indexPtr->el, |
444 | indexPtr->max * sizeof(void *)); |
445 | } else if (indexPtr->max == 0u) { |
446 | indexPtr->max = indexPtr->inc; |
447 | indexPtr->el = (void **) ns_malloc(indexPtr->max * sizeof(void *)); |
448 | } |
449 | if (indexPtr->n > 0u) { |
450 | i = BinSearch(&el, indexPtr->el, (ssize_t)indexPtr->n, indexPtr->CmpEls); |
451 | } else { |
452 | i = 0; |
453 | } |
454 | |
455 | if (i < (int)indexPtr->n) { |
456 | size_t j; |
457 | |
458 | for (j = indexPtr->n; (int)j > i; j--) { |
459 | indexPtr->el[j] = indexPtr->el[j - 1u]; |
460 | } |
461 | } |
462 | indexPtr->el[i] = el; |
463 | indexPtr->n++; |
464 | } |
465 | |
466 |
|
467 | |
468 | |
469 | |
470 | |
471 | |
472 | |
473 | |
474 | |
475 | |
476 | |
477 | |
478 | |
479 | |
480 | |
481 | |
482 | |
483 | void |
484 | Ns_IndexDel(Ns_Index *indexPtr, const void *el) |
485 | { |
486 | size_t i, j; |
487 | |
488 | NS_NONNULL_ASSERT(indexPtr != NULL); |
489 | NS_NONNULL_ASSERT(el != NULL); |
490 | |
491 | for (i = 0u; i < indexPtr->n; i++) { |
492 | if (indexPtr->el[i] == el) { |
493 | indexPtr->n--; |
494 | if (i < indexPtr->n) { |
495 | for (j = i; j < indexPtr->n; j++) { |
496 | indexPtr->el[j] = indexPtr->el[j + 1u]; |
497 | } |
498 | } |
499 | break; |
500 | } |
501 | } |
502 | } |
503 | |
504 |
|
505 | |
506 | |
507 | |
508 | |
509 | |
510 | |
511 | |
512 | |
513 | |
514 | |
515 | |
516 | |
517 | |
518 | |
519 | |
520 | |
521 | void * |
522 | Ns_IndexEl(const Ns_Index *indexPtr, size_t i) |
523 | { |
524 | NS_NONNULL_ASSERT(indexPtr != NULL); |
525 | |
526 | return indexPtr->el[i]; |
527 | } |
528 | |
529 |
|
530 | |
531 | |
532 | |
533 | |
534 | |
535 | |
536 | |
537 | |
538 | |
539 | |
540 | |
541 | |
542 | |
543 | |
544 | |
545 | |
546 | static int |
547 | CmpStr(const void *leftPtr, const void *rightPtr) |
548 | { |
549 | NS_NONNULL_ASSERT(leftPtr != NULL); |
550 | NS_NONNULL_ASSERT(rightPtr != NULL); |
551 | |
552 | return strcmp(*(const char**)leftPtr, *((const char**)rightPtr)); |
553 | } |
554 | |
555 |
|
556 | |
557 | |
558 | |
559 | |
560 | |
561 | |
562 | |
563 | |
564 | |
565 | |
566 | |
567 | |
568 | |
569 | |
570 | |
571 | |
572 | static int |
573 | CmpKeyWithStr(const void *key, const void *elPtr) |
574 | { |
575 | NS_NONNULL_ASSERT(key != NULL); |
576 | NS_NONNULL_ASSERT(elPtr != NULL); |
577 | |
578 | return strcmp((const char *)key, *(const char *const*)elPtr); |
579 | } |
580 | |
581 |
|
582 | |
583 | |
584 | |
585 | |
586 | |
587 | |
588 | |
589 | |
590 | |
591 | |
592 | |
593 | |
594 | |
595 | |
596 | |
597 | |
598 | |
599 | void |
600 | Ns_IndexStringInit(Ns_Index *indexPtr, size_t inc) |
601 | { |
602 | NS_NONNULL_ASSERT(indexPtr != NULL); |
603 | |
604 | Ns_IndexInit(indexPtr, inc, CmpStr, CmpKeyWithStr); |
605 | } |
606 | |
607 |
|
608 | |
609 | |
610 | |
611 | |
612 | |
613 | |
614 | |
615 | |
616 | |
617 | |
618 | |
619 | |
620 | |
621 | |
622 | |
623 | |
624 | |
625 | Ns_Index * |
626 | Ns_IndexStringDup(const Ns_Index *indexPtr) |
627 | { |
628 | Ns_Index *newPtr; |
629 | size_t i; |
630 | |
631 | NS_NONNULL_ASSERT(indexPtr != NULL); |
632 | |
633 | newPtr = (Ns_Index *) ns_malloc(sizeof(Ns_Index)); |
634 | memcpy(newPtr, indexPtr, sizeof(Ns_Index)); |
635 | newPtr->el = (void **) ns_malloc(indexPtr->max * sizeof(void *)); |
636 | |
637 | for (i = 0u; i < newPtr->n; i++) { |
638 | newPtr->el[i] = ns_strdup(indexPtr->el[i]); |
639 | } |
640 | |
641 | return newPtr; |
642 | } |
643 | |
644 |
|
645 | |
646 | |
647 | |
648 | |
649 | |
650 | |
651 | |
652 | |
653 | |
654 | |
655 | |
656 | |
657 | |
658 | |
659 | |
660 | |
661 | void |
662 | Ns_IndexStringAppend(Ns_Index *addtoPtr, const Ns_Index *addfromPtr) |
663 | { |
664 | size_t i; |
665 | |
666 | NS_NONNULL_ASSERT(addtoPtr != NULL); |
667 | NS_NONNULL_ASSERT(addfromPtr != NULL); |
668 | |
669 | for (i = 0u; i < addfromPtr->n; i++) { |
670 | Ns_IndexAdd(addtoPtr, ns_strdup(addfromPtr->el[i])); |
671 | } |
672 | } |
673 | |
674 |
|
675 | |
676 | |
677 | |
678 | |
679 | |
680 | |
681 | |
682 | |
683 | |
684 | |
685 | |
686 | |
687 | |
688 | |
689 | |
690 | |
691 | void |
692 | Ns_IndexStringDestroy(Ns_Index *indexPtr) |
693 | { |
694 | size_t i; |
695 | |
696 | NS_NONNULL_ASSERT(indexPtr != NULL); |
697 | |
698 | for (i = 0u; i < indexPtr->n; i++) { |
699 | ns_free(indexPtr->el[i]); |
700 | } |
701 | |
702 | Ns_IndexDestroy(indexPtr); |
703 | } |
704 | |
705 |
|
706 | |
707 | |
708 | |
709 | |
710 | |
711 | |
712 | |
713 | |
714 | |
715 | |
716 | |
717 | |
718 | |
719 | |
720 | |
721 | |
722 | void |
723 | Ns_IndexStringTrunc(Ns_Index *indexPtr) |
724 | { |
725 | size_t i; |
726 | |
727 | NS_NONNULL_ASSERT(indexPtr != NULL); |
728 | |
729 | for (i = 0u; i < indexPtr->n; i++) { |
730 | ns_free(indexPtr->el[i]); |
731 | } |
732 | |
733 | Ns_IndexTrunc(indexPtr); |
734 | } |
735 | |
736 |
|
737 | |
738 | |
739 | |
740 | |
741 | |
742 | |
743 | |
744 | |
745 | |
746 | |
747 | |
748 | |
749 | |
750 | |
751 | |
752 | |
753 | static int |
754 | CmpInts(const void *leftPtr, const void *rightPtr) |
755 | { |
756 | int result, left, right; |
757 | |
758 | NS_NONNULL_ASSERT(leftPtr != NULL); |
759 | NS_NONNULL_ASSERT(rightPtr != NULL); |
760 | |
761 | left = *(const int *)leftPtr; |
762 | right = *(const int *)rightPtr; |
763 | |
764 | if (left == right) { |
765 | result = 0; |
766 | } else { |
767 | result = (left < right) ? -1 : 1; |
768 | } |
769 | return result; |
770 | } |
771 | |
772 |
|
773 | |
774 | |
775 | |
776 | |
777 | |
778 | |
779 | |
780 | |
781 | |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | |
789 | static int |
790 | CmpKeyWithInt(const void *keyPtr, const void *elPtr) |
791 | { |
792 | int result, key, element; |
793 | |
794 | NS_NONNULL_ASSERT(keyPtr != NULL); |
795 | NS_NONNULL_ASSERT(elPtr != NULL); |
796 | |
797 | key = *(const int *)keyPtr; |
798 | element = *(const int *)elPtr; |
799 | |
800 | if (key == element) { |
801 | result = 0; |
802 | } else { |
803 | result = key < element ? -1 : 1; |
804 | } |
805 | return result; |
806 | } |
807 | |
808 |
|
809 | |
810 | |
811 | |
812 | |
813 | |
814 | |
815 | |
816 | |
817 | |
818 | |
819 | |
820 | |
821 | |
822 | |
823 | |
824 | |
825 | void |
826 | Ns_IndexIntInit(Ns_Index *indexPtr, size_t inc) |
827 | { |
828 | NS_NONNULL_ASSERT(indexPtr != NULL); |
829 | |
830 | Ns_IndexInit(indexPtr, inc, CmpInts, CmpKeyWithInt); |
831 | } |
832 | |
833 | #ifdef _MSC_VER_VERY_OLD |
834 | #define bsearch(a, b, c, d, e) NsBsearch((a), (b), (c), (d), (e)) |
835 | |
836 | |
837 | |
838 | |
839 | |
840 | |
841 | |
842 | |
843 | |
844 | |
845 | |
846 | |
847 | |
848 | |
849 | |
850 | |
851 | |
852 | |
853 | |
854 | |
855 | static void * |
856 | NsBsearch (register const void *key, register const void *base, |
857 | register size_t nmemb, register size_t size, |
858 | int (*compar)(const void *key, const void *value)) |
859 | { |
860 | while (nmemb > 0) { |
861 | register const void *mid_point; |
862 | register int cmp; |
863 | |
864 | mid_point = (char *)base + size * (nmemb >> 1); |
865 | if ((cmp = (*compar)(key, mid_point)) == 0) |
866 | return (void *)mid_point; |
867 | if (cmp >= 0) { |
868 | base = (char *)mid_point + size; |
869 | nmemb = (nmemb - 1) >> 1; |
870 | } else |
871 | nmemb >>= 1; |
872 | } |
873 | return NULL; |
874 | } |
875 | #endif |
876 | |
877 | |
878 | |
879 | |
880 | |
881 | |
882 | |
883 | |
884 | |