1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: dk4strw.ctr
12 */
13
14 /** @file dk4strw.c The dk4strw module.
15 */
16
17
18 #include "dk4conf.h"
19
20 #ifndef DK4USE_H_INCLUDED
21 #include <libdk4base/dk4use.h>
22 #endif
23
24 #if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
25 #ifndef WINDOWS_H_INCLUDED
26 #include <windows.h>
27 #define WINDOWS_H_INCLUDED 1
28 #endif
29 #endif
30
31
32 #include <libdk4base/dk4strw.h>
33 #include <libdk4base/dk4mem.h>
34 #include <libdk4base/dk4numco.h>
35
36 #if DK4_HAVE_WCTYPE_H
37 #ifndef WCTYPE_H_INCLUDED
38 #include <wctype.h>
39 #define WCTYPE_H_INCLUDED 1
40 #endif
41 #endif
42
43 #if DK4_HAVE_ASSERT_H
44 #ifndef ASSERT_H_INCLUDED
45 #include <assert.h>
46 #define ASSERT_H_INCLUDED 1
47 #endif
48 #endif
49
50 #ifndef DK4MEMRS_H_INCLUDED
51 #include <libdk4base/dk4memrs.h>
52 #endif
53
54
55
56
57
58
59
60 /** Constant strings used in the module.
61 */
62 static const wchar_t * const dk4strw_modkw[] = {
63 /* 0 */
64 L" \t\r\n",
65
66 NULL
67
68 };
69
70
71
72 /** First index of a keyword indicating true in the
73 dk4str8_boolkw array below.
74 */
75 #define DK4STRW_FIRST_TRUE 5
76
77 /** Keywords for boolean values.
78 */
79 static const wchar_t * const dk4strw_boolkw[] = {
80 /* 0 */
81 L"-",
82
83 /* 1 */
84 L"0",
85
86 /* 2 */
87 L"n$o",
88
89 /* 3 */
90 L"of$f",
91
92 /* 4 */
93 L"f$alse",
94
95 /* 5 */
96 L"+",
97
98 /* 6 */
99 L"1",
100
101 /* 7 */
102 L"y$es",
103
104 /* 8 */
105 L"on",
106
107 /* 9 */
108 L"t$rue",
109
110 /* 10 */
111 L"ok",
112
113 NULL
114
115 };
116
117
118 #if 0
119 /** Number of significant digits when printing a double.
120 */
121 static const int dk4strw_dbl_digits = DK4_DBL_DIGITS;
122 #endif
123
124
125
126 void
127
dk4strw_cpy_to_left(wchar_t * dst,const wchar_t * src)128 dk4strw_cpy_to_left(wchar_t *dst, const wchar_t *src)
129 {
130 register wchar_t *dptr;
131 register const wchar_t *sptr;
132 #if DK4_USE_ASSERT
133 assert(NULL != dst);
134 assert(NULL != src);
135 #endif
136 if ((NULL != dst) && (NULL != src)) {
137 dptr = dst; sptr = src;
138 while(L'\0' != *sptr) { *(dptr++) = *(sptr++); }
139 *dptr = L'\0';
140 }
141 }
142
143
144
145 size_t
146
dk4strw_len(const wchar_t * src)147 dk4strw_len(const wchar_t *src)
148 {
149 if (NULL == src) { return 0; }
150 #if DK4_ON_WINDOWS
151 /* +++ Windows */
152 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
153 return ((size_t)lstrlenW(src));
154 #else
155 return (wcslen(src));
156 #endif
157 /* --- Windows */
158 #else
159 /* +++ Windows */
160 #if DK4_HAVE_WCSLEN
161 return (wcslen(src));
162 #else
163 size_t back = 0;
164 while(L'\0' != *src) { src++; back++; }
165 return back;
166 #endif
167 /* --- Windows */
168 #endif
169 }
170
171
172
173 wchar_t *
174
dk4strw_chr(const wchar_t * s,wchar_t c)175 dk4strw_chr(const wchar_t *s, wchar_t c)
176 {
177 if (NULL == s) { return NULL; }
178 #if DK4_ON_WINDOWS
179 /* +++ Windows */
180 #if DK4_WIN_DENY_CRT
181 {
182 wchar_t *back = NULL;
183 while ((L'\0' != *s) && (NULL == back)) {
184 if (c == *s) {
185 back = (wchar_t *)s;
186 }
187 s++;
188 }
189 return back;
190 }
191 #else
192 #ifdef __cplusplus
193 return ((wchar_t *)wcschr(s, c));
194 #else
195 return (wcschr(s, c));
196 #endif
197 #endif
198 /* --- Windows */
199 #else
200 /* +++ non-Windows */
201 #if DK4_HAVE_WCSCHR
202 #ifdef __cplusplus
203 return ((wchar_t *)wcschr(s, c));
204 #else
205 return (wcschr(s, c));
206 #endif
207 #else
208 {
209 wchar_t *back = NULL;
210 while ((L'\0' != *s) && (NULL == back)) {
211 if (c == *s) {
212 back = (wchar_t *)s;
213 }
214 s++;
215 }
216 return back;
217 }
218 #endif
219 /* --- non-Windows */
220 #endif
221 }
222
223
224
225 wchar_t *
226
dk4strw_rchr(const wchar_t * s,wchar_t c)227 dk4strw_rchr(const wchar_t *s, wchar_t c)
228 {
229 if (NULL == s) { return NULL; }
230 #if DK4_ON_WINDOWS
231 /* +++ Windows */
232 #if DK4_WIN_DENY_CRT
233 {
234 wchar_t *back = NULL;
235 while (L'\0' != *s) {
236 if (c == *s) {
237 back = (wchar_t *)s;
238 }
239 s++;
240 }
241 return back;
242 }
243 #else
244 #ifdef __cplusplus
245 return ((wchar_t *)wcsrchr(s, c));
246 #else
247 return (wcsrchr(s, c));
248 #endif
249 #endif
250 /* --- Windows */
251 #else
252 /* +++ non-Windows */
253 #if DK4_HAVE_WCSRCHR
254 #ifdef __cplusplus
255 return ((wchar_t *)wcsrchr(s, c));
256 #else
257 return (wcsrchr(s, c));
258 #endif
259 #else
260 {
261 wchar_t *back = NULL;
262 while (L'\0' != *s) {
263 if (c == *s) {
264 back = (wchar_t *)s;
265 }
266 s++;
267 }
268 return back;
269 }
270 #endif
271 /* --- non-Windows */
272 #endif
273 }
274
275
276
277 wchar_t
278
dk4strw_toupper(wchar_t c)279 dk4strw_toupper(wchar_t c)
280 {
281 #if DK4_ON_WINDOWS
282 /* +++ Windows */
283 #if DK4_WIN_DENY_CRT
284 if ((L'a' <= c) && (L'z' >= c)) {
285 return (L'A' + (c - L'a'));
286 } else {
287 return c;
288 }
289 #else
290 return (towupper(c));
291 #endif
292 /* --- Windows */
293 #else
294 /* +++ non-Windows */
295 return ((wchar_t)towupper((wint_t)c));
296 /* --- non-Windows */
297 #endif
298 }
299
300
301
302 wchar_t
303
dk4strw_tolower(wchar_t c)304 dk4strw_tolower(wchar_t c)
305 {
306 #if DK4_ON_WINDOWS
307 /* +++ Windows */
308 #if DK4_WIN_DENY_CRT
309 if ((L'A' <= c) && (L'Z' >= c)) {
310 return (L'a' + (c - L'A'));
311 } else {
312 return c;
313 }
314 #else
315 return (towlower(c));
316 #endif
317 /* --- Windows */
318 #else
319 /* +++ non-Windows */
320 return ((wchar_t)towlower((wint_t)c));
321 /* --- non-Windows */
322 #endif
323 }
324
325
326
327 int
328
dk4strw_cpy_s(wchar_t * dst,size_t sz,const wchar_t * src,dk4_er_t * erp)329 dk4strw_cpy_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp)
330 {
331 int back = 0;
332 size_t sl;
333 #if DK4_USE_ASSERT
334 assert(NULL != dst);
335 assert(0 < sz);
336 #endif
337 if ((NULL != dst) && (0 < sz)) {
338 *dst = L'\0';
339 if (NULL != src) {
340 sl = dk4strw_len(src);
341 if (sz > sl) {
342 #if DK4_ON_WINDOWS
343 /* +++ Windows */
344 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
345 (void)lstrcpyW(dst, (wchar_t *)src);
346 #else
347 #if DK4_USE_PRAGMA_WARNING_DISABLE
348 #pragma warning( push )
349 #pragma warning( disable: 4996 )
350 #endif
351 (void)wcscpy(dst, src);
352 #if DK4_USE_PRAGMA_WARNING_DISABLE
353 #pragma warning( pop )
354 #endif
355 #endif
356 /* --- Windows */
357 #else
358 /* +++ non-Windows */
359 #if DK4_HAVE_WCSCPY
360 (void)wcscpy(dst, src);
361 #else
362 size_t nbytes;
363 dk4_er_t er;
364 dk4error_init(&er);
365 if ((SIZE_MAX - 1) < sl) {
366 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
367 } else {
368 if ((SIZE_MAX / sizeof(wchar_t)) < (sl + 1)) {
369 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
370 } else {
371 nbytes = sizeof(wchar_t) * (sl + 1);
372 }
373 }
374 if (DK4_E_NONE == er.ec) {
375 DK4_MEMCPY(dst, src, nbytes);
376 } else {
377 dk4strw_cpy_to_left(dst, src);
378 }
379 #endif
380 /* --- non-Windows */
381 #endif
382 back = 1;
383 } else {
384 dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
385 }
386 } else {
387 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
388 }
389 } else {
390 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
391 }
392 return back;
393 }
394
395
396
397 int
398
dk4strw_cat_s(wchar_t * dst,size_t sz,const wchar_t * src,dk4_er_t * erp)399 dk4strw_cat_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp)
400 {
401 size_t la; /* Size of string in destination buffer */
402 size_t lb; /* Source string size */
403 int back = 0;
404 #if DK4_USE_ASSERT
405 assert(NULL != dst);
406 assert(0 < sz);
407 #endif
408 if ((NULL != dst) && (0 < sz) && (NULL != src)) {
409 la = dk4strw_len(dst);
410 lb = dk4strw_len(src);
411 if (sz > (la + lb)) {
412 #if DK4_ON_WINDOWS
413 /* +++ Windows */
414 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
415 (void)lstrcatW(dst, src);
416 #else
417 #if DK4_USE_PRAGMA_WARNING_DISABLE
418 #pragma warning( push )
419 #pragma warning( disable: 4996 )
420 #endif
421 (void)wcscat(dst, src);
422 #if DK4_USE_PRAGMA_WARNING_DISABLE
423 #pragma warning( pop )
424 #endif
425 #endif
426 /* --- Windows */
427 #else
428 /* +++ non-Windows */
429 #if DK4_HAVE_WCSCAT
430 (void)wcscat(dst, src);
431 #else
432 size_t nb;
433 dk4_er_t er;
434 dk4error_init(&er);
435 if ((SIZE_MAX - 1) < lb) {
436 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
437 } else {
438 if ((SIZE_MAX / sizeof(wchar_t)) < (lb + 1)) {
439 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
440 } else {
441 nb = sizeof(wchar_t) * (lb + 1);
442 }
443 }
444 if (DK4_E_NONE == er.ec) {
445 DK4_MEMCPY(&(dst[la]), src, nb);
446 } else {
447 dk4strw_cpy_to_left(&(dst[la]), src);
448 }
449 #endif
450 /* --- non-Windows */
451 #endif
452 back = 1;
453 } else {
454 dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
455 }
456 } else {
457 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
458 }
459 return back;
460 }
461
462
463
464
465 int
466
dk4strw_cmp(const wchar_t * s1,const wchar_t * s2)467 dk4strw_cmp(const wchar_t *s1, const wchar_t *s2)
468 {
469 int back = 0;
470 if (NULL != s1) {
471 if (NULL != s2) {
472 #if DK4_ON_WINDOWS
473 /* +++ Windows */
474 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
475 back = lstrcmpW(s1, s2);
476 if (0 > back) back = -1;
477 if (0 < back) back = 1;
478 #else
479 back = wcscmp(s1, s2);
480 if (0 > back) back = -1;
481 if (0 < back) back = 1;
482 #endif
483 /* --- Windows */
484 #else
485 /* +++ non-Windows */
486 #if DK4_HAVE_WCSCMP
487 back = wcscmp(s1, s2);
488 if (0 > back) back = -1;
489 if (0 < back) back = 1;
490 #else
491 #if DK4_HAVE__WCSCMP
492 back = _wcscmp(s1, s2);
493 if (0 > back) back = -1;
494 if (0 < back) back = 1;
495 #else
496 do {
497 if (*s1 > *s2) {
498 back = 1;
499 } else {
500 if (*s1 < *s2) {
501 back = -1;
502 } else {
503 if (L'\0' != *s1) {
504 s1++; s2++;
505 }
506 }
507 }
508 } while((0 == back) && (L'\0' != *s1));
509 #endif
510 #endif
511 /* --- non-Windows */
512 #endif
513 } else {
514 back = 1;
515 }
516 } else {
517 if (NULL != s2) {
518 back = -1;
519 }
520 }
521 return back;
522 }
523
524
525
526 int
527
dk4strw_ncmp(const wchar_t * s1,const wchar_t * s2,size_t n)528 dk4strw_ncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
529 {
530 int back = 0;
531 if (NULL != s1) {
532 if (NULL != s2) {
533 #if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \
534 || (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP))
535 while ((0 < n--) && (0 == back)) {
536 if (L'\0' == *s1) {
537 if (L'\0' == *s2) {
538 n = 0;
539 } else {
540 back = -1;
541 }
542 } else {
543 if (L'\0' == *s2) {
544 back = 1;
545 } else {
546 if (*s1 < *s2) {
547 back = -1;
548 } else {
549 if (*s1 > *s2) {
550 back = 1;
551 } else {
552 s1++; s2++;
553 }
554 }
555 }
556 }
557 }
558 #else
559 #if DK4_HAVE_WCSNCMP
560 back = wcsncmp(s1, s2, n);
561 #else
562 back = _wcsncmp(s1, s2, n);
563 #endif
564 if (-1 > back) back = -1;
565 if ( 1 < back) back = 1;
566 #endif
567 } else {
568 back = 1;
569 }
570 } else {
571 if (NULL != s2) {
572 back = -1;
573 }
574 }
575 return back;
576 }
577
578
579
580 int
581
dk4strw_casecmp(const wchar_t * s1,const wchar_t * s2)582 dk4strw_casecmp(const wchar_t *s1, const wchar_t *s2)
583 {
584 int back = 0;
585 if (NULL != s1) {
586 if (NULL != s2) {
587 #if DK4_ON_WINDOWS
588 /* +++ Windows */
589 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
590 back = lstrcmpiW(s1, s2);
591 if (0 > back) back = -1;
592 if (0 < back) back = 1;
593 #else
594 back =_wcsicmp(s1, s2);
595 if (0 > back) back = -1;
596 if (0 < back) back = 1;
597 #endif
598 /* --- Windows */
599 #else
600 /* +++ non-Windows */
601 #if DK4_HAVE_WCSCASECMP
602 back = wcscasecmp(s1, s2);
603 if (0 > back) back = -1;
604 if (0 < back) back = 1;
605 #else
606 #if DK4_HAVE__WCSCASECMP
607 back = _wcscasecmp(s1, s2);
608 if (0 > back) back = -1;
609 if (0 < back) back = 1;
610 #else
611 #if DK4_HAVE__WCSICMP
612 back = _wcsicmp(s1, s2);
613 if (0 > back) back = -1;
614 if (0 < back) back = 1;
615 #else
616 #if DK4_HAVE_WCSICMP
617 back = wcsicmp(s1, s2);
618 if (0 > back) back = -1;
619 if (0 < back) back = 1;
620 #else
621 wchar_t c1;
622 wchar_t c2;
623 c1 = dk4strw_toupper(*s1);
624 c2 = dk4strw_toupper(*s2);
625 do {
626 if (c1 > c2) {
627 back = 1;
628 } else {
629 if (c1 < c2) {
630 back = -1;
631 } else {
632 if (L'\0' != *s1) {
633 s1++; s2++;
634 }
635 }
636 }
637 } while((0 == back) && (L'\0' != *s1));
638 #endif
639 #endif
640 #endif
641 #endif
642 /* --- non-Windows */
643 #endif
644 } else {
645 back = 1;
646 }
647 } else {
648 if (NULL != s2) {
649 back = -1;
650 }
651 }
652 return back;
653 }
654
655
656
657 #if (DK4_ON_WINDOWS) || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
658
659 wchar_t *
660
dk4strw_dup(const wchar_t * src,dk4_er_t * erp)661 dk4strw_dup(const wchar_t *src, dk4_er_t *erp)
662 {
663 wchar_t *back = NULL;
664 size_t lgt;
665 if (NULL != src) {
666 lgt = dk4strw_len(src);
667 if (SIZE_MAX > lgt) {
668 back = dk4mem_new(wchar_t,(lgt+1),erp);
669 if (NULL != back) {
670 (void)dk4strw_cpy_s(back, (lgt+1), src, erp);
671 }
672 } else {
673 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
674 }
675 } else {
676 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
677 }
678 return back;
679 }
680
681 #endif
682
683
684
685 #if !DK4_HAVE_WCSCHR
686 /** Find first occurance of character in string.
687 @param src String to search for character.
688 @param c Character to find.
689 @return Pointer to first occurance on success, NULL on error.
690 */
691 static
692 const wchar_t *
dk4strw_i_wcschr(const wchar_t * src,wchar_t c)693 dk4strw_i_wcschr(const wchar_t *src, wchar_t c)
694 {
695 const wchar_t *back = NULL;
696 while ((L'\0' != *src) && (NULL == back)) {
697 if (*src == c) {
698 back = src;
699 } else {
700 src++;
701 }
702 }
703 return back;
704 }
705 #endif
706
707
708
709 wchar_t *
710
dk4strw_start(const wchar_t * src,const wchar_t * delim)711 dk4strw_start(const wchar_t *src, const wchar_t *delim)
712 {
713 wchar_t *back = NULL;
714 if (NULL != src) {
715 if (NULL == delim) { delim = dk4strw_modkw[0]; }
716 while((L'\0' != *src) && (NULL == back)) {
717 if (NULL != dk4strw_chr(delim, *src)) {
718 src++;
719 } else {
720 back = (wchar_t *)src;
721 }
722 }
723 }
724 return back;
725 }
726
727
728
729 /** Internal function for next token search.
730
731 CRT on Windows: Optional, disabling CRT degrades performance.
732 @param src String containing tokens, must be set to
733 the start of a token.
734 @param delim Delimiter set.
735 @return Pointer to next token on success, NULL on error.
736 */
737 static
738 wchar_t *
dk4strw_i_next(wchar_t * src,const wchar_t * delim)739 dk4strw_i_next(wchar_t *src, const wchar_t *delim)
740 {
741 wchar_t *back = NULL;
742 if (NULL != src) {
743 if (NULL == delim) { delim = dk4strw_modkw[0]; }
744 while ((L'\0' != *src) && (NULL == back)) {
745 if (NULL != dk4strw_chr(delim, *src)) {
746 back = src;
747 } else {
748 src++;
749 }
750 }
751 if (NULL != back) {
752 *(back++) = L'\0';
753 back = dk4strw_start(back, delim);
754 }
755 }
756 return back;
757 }
758
759
760
761 wchar_t *
762
dk4strw_next(wchar_t * src,const wchar_t * delim)763 dk4strw_next(wchar_t *src, const wchar_t *delim)
764 {
765 wchar_t *back = NULL;
766 if (NULL != src) {
767 back = dk4strw_start(src, delim);
768 if (NULL != back) {
769 back = dk4strw_i_next(back, delim);
770 }
771 }
772 return back;
773 }
774
775
776
777 wchar_t *
778
dk4strw_sep(wchar_t ** stringp,const wchar_t * delim)779 dk4strw_sep(wchar_t **stringp, const wchar_t *delim)
780 {
781 wchar_t *back = NULL;
782
783 #if DK4_USE_ASSERT
784 assert(NULL != stringp);
785 #endif
786 if (NULL != stringp) {
787 if (NULL != *stringp) {
788 if (NULL == delim) { delim = dk4strw_modkw[0]; }
789 back = dk4strw_start(*stringp, delim);
790 if (NULL != back) {
791 *stringp = dk4strw_next(back, delim);
792 } else {
793 *stringp = NULL;
794 }
795 }
796 }
797 return back;
798 }
799
800
801
802 size_t
803
dk4strw_tokenize(wchar_t ** dpp,size_t szdpp,wchar_t * src,const wchar_t * delim,dk4_er_t * erp)804 dk4strw_tokenize(
805 wchar_t **dpp, size_t szdpp, wchar_t *src, const wchar_t *delim, dk4_er_t *erp
806 )
807 {
808 wchar_t *context;
809 wchar_t *token;
810 size_t back = 0;
811 #if DK4_USE_ASSERT
812 assert(NULL != dpp);
813 assert(0 < szdpp);
814 #endif
815 if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) {
816 if (NULL == delim) { delim = dk4strw_modkw[0]; }
817 context = src;
818 while (NULL != (token = dk4strw_sep(&context, delim))) {
819 if (back < szdpp) {
820 dpp[back] = token;
821 }
822 back++;
823 }
824 if (back >= szdpp) { /* Too many tokens found */
825 dk4error_set_elsize_nelem(
826 erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back
827 );
828 back = 0;
829 }
830 } else {
831 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
832 }
833 return back;
834 }
835
836
837
838 void
839
dk4strw_normalize(wchar_t * src,const wchar_t * delim)840 dk4strw_normalize(wchar_t *src, const wchar_t *delim)
841 {
842
843 wchar_t *p1; /* Pointer to traverse text. */
844 wchar_t *p2; /* Start of next token. */
845 int cc; /* Flag: Can continue. */
846
847 if (NULL != src) {
848 if (NULL == delim) { delim = dk4strw_modkw[0]; }
849 p1 = src;
850 cc = 0;
851 if (L'\0' != *p1) {
852 if (NULL != dk4strw_chr(delim, *p1)) {
853 p2 = dk4strw_start(p1, delim);
854 if (NULL != p2) {
855 dk4strw_cpy_to_left(p1, p2);
856 cc = 1;
857 } else {
858 *p1 = L'\0';
859 }
860 } else {
861 cc = 1;
862 }
863 }
864 while (0 != cc) {
865 if (L'\0' == *p1) {
866 cc = 0;
867 } else {
868 if (NULL != dk4strw_chr(delim, *p1)) {
869 *p1 = *delim;
870 if (L'\0' == p1[1]) {
871 *p1 = L'\0';
872 cc = 0;
873 } else {
874 if (NULL != dk4strw_chr(delim, p1[1])) {
875 p2 = dk4strw_start(p1, delim);
876 if (NULL != p2) {
877 dk4strw_cpy_to_left(++p1, p2);
878 } else {
879 *p1 = L'\0';
880 cc = 0;
881 }
882 } else {
883 p1++;
884 }
885 }
886 } else {
887 p1++;
888 }
889 }
890 }
891 }
892 }
893
894
895
896 int
897
dk4strw_array_index(const wchar_t * const * arr,const wchar_t * str,int cs)898 dk4strw_array_index(const wchar_t * const *arr, const wchar_t *str, int cs)
899 {
900 int back = -1;
901 int cand = 0;
902 #if DK4_USE_ASSERT
903 assert(NULL != arr);
904 #endif
905 while ((NULL != *arr) && (-1 == back)) {
906 if (0 != cs) {
907 if (0 == dk4strw_cmp(*arr, str)) { back = cand; }
908 } else {
909 if (0 == dk4strw_casecmp(*arr, str)) { back = cand; }
910 }
911 arr++; cand++;
912 }
913 return back;
914 }
915
916
917
918
919 int
920
dk4strw_is_abbr(const wchar_t * str,const wchar_t * pattern,wchar_t spec,int cs)921 dk4strw_is_abbr(const wchar_t *str,const wchar_t *pattern,wchar_t spec,int cs)
922 {
923 const wchar_t *lptr = NULL; /* Pointer to traverse string */
924 const wchar_t *pptr = NULL; /* Pointer to traverse pattern */
925 int back = 0; /* Function result */
926 int fspec = 0; /* Flag: spec was found */
927 int cc = 1; /* Flag: Can continue */
928 wchar_t cl;
929 wchar_t cp;
930
931 #if DK4_USE_ASSERT
932 assert(NULL != pattern);
933 #endif
934 if ((NULL != str) && (NULL != pattern)) {
935 lptr = str; pptr = pattern;
936 while (0 != cc) {
937 if ((0 == fspec) && (*pptr == spec)) {
938 fspec = 1;
939 pptr++;
940 } else {
941 if (L'\0' != *lptr) {
942 cl = *lptr; cp = *pptr;
943 if (0 == cs) {
944 cl = dk4strw_toupper(cl);
945 cp = dk4strw_toupper(cp);
946 }
947 if (cl == cp) {
948 lptr++;
949 pptr++;
950 } else {
951 cc = 0;
952 }
953 } else {
954 cc = 0;
955 if ((L'\0' == *pptr) || (0 != fspec)) { back = 1; }
956 }
957 }
958 }
959 }
960
961 return back;
962 }
963
964
965
966 int
967
dk4strw_abbr_index(const wchar_t * const * arr,wchar_t spec,const wchar_t * str,int cs)968 dk4strw_abbr_index(
969 const wchar_t * const *arr,
970 wchar_t spec,
971 const wchar_t *str,
972 int cs
973 )
974 {
975 int back = -1;
976 int cand = 0; /* Traverse array */
977
978 #if DK4_USE_ASSERT
979 assert(NULL != arr);
980 #endif
981 if ((NULL != arr) && (NULL != str)) {
982 while ((NULL != *arr) && (-1 == back)) {
983 if (0 != dk4strw_is_abbr(str, *arr, spec, cs)) {
984 back = cand;
985 }
986 arr++; cand++;
987 }
988 }
989
990 return back;
991 }
992
993
994
995 int
996
dk4strw_is_bool(const wchar_t * str)997 dk4strw_is_bool(const wchar_t *str)
998 {
999 int back = 0;
1000 if (NULL != str) {
1001 if (-1 < dk4strw_abbr_index(dk4strw_boolkw, L'$', str, 0)) {
1002 back = 1;
1003 }
1004 }
1005 return back;
1006 }
1007
1008
1009
1010 int
1011
dk4strw_is_on(const wchar_t * str)1012 dk4strw_is_on(const wchar_t *str)
1013 {
1014 int back = 0;
1015
1016 if (NULL != str) {
1017 back = dk4strw_abbr_index(dk4strw_boolkw, L'$', str, 0);
1018 if (-1 < back) {
1019 if (DK4STRW_FIRST_TRUE <= back) {
1020 back = 1;
1021 } else {
1022 back = 0;
1023 }
1024 } else {
1025 back = 0;
1026 }
1027 }
1028
1029 return back;
1030 }
1031
1032
1033
1034 int
1035
dk4strw_pathcmp(const wchar_t * s1,const wchar_t * s2)1036 dk4strw_pathcmp(const wchar_t *s1, const wchar_t *s2)
1037 {
1038 #if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
1039 return (dk4strw_casecmp(s1, s2));
1040 #else
1041 return (dk4strw_cmp(s1, s2));
1042 #endif
1043 }
1044
1045
1046
1047 void
1048
dk4strw_rtwh(wchar_t * str,const wchar_t * whsp)1049 dk4strw_rtwh(wchar_t *str, const wchar_t *whsp)
1050 {
1051 wchar_t *ptr = NULL; /* Pointer to first whitespace */
1052
1053 if (NULL == whsp) { whsp = dk4strw_modkw[0]; }
1054 if (NULL != str) {
1055 while (L'\0' != *str) {
1056 if (NULL != dk4strw_chr(whsp, *str)) {
1057 if (NULL == ptr) { ptr = str; }
1058 } else {
1059 ptr = NULL;
1060 }
1061 str++;
1062 }
1063 if (NULL != ptr) { *ptr = L'\0'; }
1064 }
1065 }
1066
1067
1068
1069 void
1070
dk4strw_delnl(wchar_t * lptr)1071 dk4strw_delnl(wchar_t *lptr)
1072 {
1073 if (NULL != lptr) {
1074 while (L'\0' != *lptr) {
1075 if (L'\n' == *lptr) {
1076 *lptr = L'\0';
1077 } else {
1078 if (L'\r' == *lptr) {
1079 if (L'\n' == lptr[1]) {
1080 *lptr = L'\0';
1081 } else {
1082 if (L'\0' == lptr[1]) {
1083 *lptr = L'\0';
1084 } else {
1085 lptr++;
1086 }
1087 }
1088 } else {
1089 lptr++;
1090 }
1091 }
1092 }
1093 }
1094 }
1095
1096
1097
1098 const wchar_t *
1099
dk4strw_skip(const wchar_t * line,size_t skip)1100 dk4strw_skip(const wchar_t *line, size_t skip)
1101 {
1102 const wchar_t *back = NULL;
1103 size_t words = 0; /* Number of words already found */
1104 int lwt = 0; /* Flag: Last char was text */
1105
1106 if (NULL != line) {
1107 if (0 < skip) {
1108 while ((NULL == back) && (L'\0' != *line)) {
1109 if (L' ' == *line) {
1110 lwt = 0;
1111 } else {
1112 if (L'\t' == *line) {
1113 lwt = 0;
1114 } else {
1115 if (L'\n' == *line) {
1116 lwt = 0;
1117 } else {
1118 if (L'\r' == *line) {
1119 lwt = 0;
1120 } else {
1121 if (0 == lwt) {
1122 if (++words > skip) {
1123 back = line;
1124 }
1125 }
1126 lwt = 1;
1127 }
1128 }
1129 }
1130 }
1131 line++;
1132 }
1133 } else {
1134 back = dk4strw_start(line, NULL);
1135 }
1136 }
1137 return back;
1138 }
1139
1140
1141
1142 int
1143
dk4strw_buffer_sanitize(wchar_t * str,size_t sz)1144 dk4strw_buffer_sanitize(wchar_t *str, size_t sz)
1145 {
1146 size_t i;
1147 int back = 0;
1148 #if DK4_USE_ASSERT
1149 assert(NULL != str);
1150 assert(0 < sz);
1151 #endif
1152 if (NULL != str) {
1153 if (0 < sz) {
1154 if ((SIZE_MAX / sizeof(wchar_t)) >= sz) {
1155 back = dk4mem_reset_secure(str, (sz * sizeof(wchar_t)), NULL);
1156 } else {
1157 for (i = 0; i < sz; i++) { str[i] = L'\0'; }
1158 back = 1;
1159 for (i = 0; i < sz; i++) { if (L'\0' != str[i]) { back = 0; } }
1160 }
1161 } else {
1162 back = 1;
1163 }
1164 }
1165 return back;
1166 }
1167
1168
1169
1170 int
1171
dk4strw_sanitize(wchar_t * str)1172 dk4strw_sanitize(wchar_t *str)
1173 {
1174 int back = 0;
1175 if (NULL != str) {
1176 back = dk4strw_buffer_sanitize(str, dk4strw_len(str));
1177 }
1178 return back;
1179 }
1180
1181
1182
1183 int
1184
dk4strw_free_sanitized(wchar_t * str)1185 dk4strw_free_sanitized(wchar_t *str)
1186 {
1187 int back = 0;
1188 if (NULL != str) {
1189 back = dk4strw_sanitize(str);
1190 dk4mem_free(str);
1191 }
1192 return back;
1193 }
1194
1195
1196