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: dk4str8.ctr
12 */
13
14 /** @file dk4str8.c The dk4str8 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 #include <libdk4base/dk4str8.h>
32
33 #if DK4_HAVE_STRING_H
34 #ifndef STRING_H_INCLUDED
35 #include <string.h>
36 #define STRING_H_INCLUDED 1
37 #endif
38 #endif
39
40 #if DK4_HAVE_CTYPE_H
41 #ifndef CTYPE_H_INCLUDED
42 #include <ctype.h>
43 #define CTYPE_H_INCLUDED 1
44 #endif
45 #endif
46
47 #if DK4_HAVE_ASSERT_H
48 #ifndef ASSERT_H_INCLUDED
49 #include <assert.h>
50 #define ASSERT_H_INCLUDED 1
51 #endif
52 #endif
53
54
55 #ifndef DK4NUMCO_H_INCLUDED
56 #include <libdk4base/dk4numco.h>
57 #endif
58
59 #ifndef DK4MEM_H_INCLUDED
60 #include <libdk4base/dk4mem.h>
61 #endif
62
63 #ifndef DK4MEMRS_H_INCLUDED
64 #include <libdk4base/dk4memrs.h>
65 #endif
66
67
68
69
70
71
72 /** Constant strings used in the module.
73 */
74 static const char * const dk4str8_modkw[] = {
75 /* 0 */
76 " \t\r\n",
77
78 NULL
79
80 };
81
82
83
84 /** First index of a keyword indicating true in the
85 dk4str8_boolkw array below.
86 */
87 #define DK4STR8_FIRST_TRUE 5
88
89 /** Keywords for boolean values.
90 */
91 static const char * const dk4str8_boolkw[] = {
92 /* 0 */
93 "-",
94
95 /* 1 */
96 "0",
97
98 /* 2 */
99 "n$o",
100
101 /* 3 */
102 "of$f",
103
104 /* 4 */
105 "f$alse",
106
107 /* 5 */
108 "+",
109
110 /* 6 */
111 "1",
112
113 /* 7 */
114 "y$es",
115
116 /* 8 */
117 "on",
118
119 /* 9 */
120 "t$rue",
121
122 /* 10 */
123 "ok",
124
125 NULL
126
127 };
128
129
130
131 #if 0
132 /** Number of significant digits.
133 */
134 static const int dk4str8_dbl_digits = DK4_DBL_DIGITS;
135 #endif
136
137
138 void
139
dk4str8_cpy_to_left(char * dst,const char * src)140 dk4str8_cpy_to_left(char *dst, const char *src)
141 {
142 register char *dptr;
143 register const char *sptr;
144 #if DK4_USE_ASSERT
145 assert(NULL != dst);
146 assert(NULL != src);
147 #endif
148 if (NULL != dst) {
149 *dst = '\0';
150 if (NULL != src) {
151 dptr = dst; sptr = src;
152 while('\0' != *sptr) { *(dptr++) = *(sptr++); }
153 *dptr = '\0';
154 }
155 }
156 }
157
158
159
160 size_t
161
dk4str8_len(const char * src)162 dk4str8_len(const char *src)
163 {
164 if (NULL == src) {
165 return 0;
166 }
167 #if DK4_ON_WINDOWS
168 /* +++ Windows */
169 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
170 return ((size_t)lstrlenA(src));
171 #else
172 return (strlen(src));
173 #endif
174 /* --- Windows */
175 #else
176 /* +++ non-Windows */
177 return (strlen(src));
178 /* --- non-Windows */
179 #endif
180 }
181
182
183
184 char
185
dk4str8_toupper(char c)186 dk4str8_toupper(char c)
187 {
188 #if DK4_ON_WINDOWS
189 #if DK4_WIN_DENY_CRT
190 char back;
191 back = c;
192 if (('a' <= c) && ('z' >= c)) {
193 back = 'A' + (c - 'a');
194 }
195 return back;
196 #else
197 return (char)toupper((unsigned char)c);
198 #endif
199 #else
200 return (char)toupper((unsigned char)c);
201 #endif
202 }
203
204
205
206 char
207
dk4str8_tolower(char c)208 dk4str8_tolower(char c)
209 {
210 #if DK4_ON_WINDOWS
211 #if DK4_WIN_DENY_CRT
212 char back;
213 back = c;
214 if (('A' <= c) && ('Z' >= c)) {
215 back = 'a' + (c - 'A');
216 }
217 return back;
218 #else
219 return (char)tolower((unsigned char)c);
220 #endif
221 #else
222 return (char)tolower((unsigned char)c);
223 #endif
224 }
225
226
227
228 char *
229
dk4str8_chr(const char * s,char c)230 dk4str8_chr(const char *s, char c)
231 {
232 if (NULL == s) { return NULL; }
233 #if DK4_ON_WINDOWS
234 /* +++ Windows */
235 #if DK4_WIN_DENY_CRT
236 {
237 char *back = NULL;
238 while (('\0' != *s) && (NULL == back)) {
239 if (c == *s) {
240 back = (char *)s;
241 } else {
242 s++;
243 }
244 }
245 return back;
246 }
247 #else
248 #ifdef __cplusplus
249 return ((char *)strchr(s, (int)((unsigned char)c)));
250 #else
251 return (strchr(s, (int)((unsigned char)c)));
252 #endif
253 #endif
254 /* --- Windows */
255 #else
256 /* +++ non-Windows */
257 #ifdef __cplusplus
258 return ((char *)strchr(s, (int)((unsigned char)c)));
259 #else
260 return (strchr(s, (int)((unsigned char)c)));
261 #endif
262 /* --- non-Windows */
263 #endif
264 }
265
266
267
268 char *
269
dk4str8_rchr(const char * s,char c)270 dk4str8_rchr(const char *s, char c)
271 {
272 if (NULL == s) { return NULL; }
273 #if DK4_ON_WINDOWS
274 #if DK4_WIN_DENY_CRT
275 {
276 char *back = NULL;
277 while ('\0' != *s) {
278 if (c == *s) {
279 back = (char *)s;
280 }
281 s++;
282 }
283 return back;
284 }
285 #else
286 #ifdef __cplusplus
287 return ((char *)strrchr(s, (int)((unsigned char)c)));
288 #else
289 return (strrchr(s, (int)((unsigned char)c)));
290 #endif
291 #endif
292 #else
293 #ifdef __cplusplus
294 return ((char *)strrchr(s, (int)((unsigned char)c)));
295 #else
296 return (strrchr(s, (int)((unsigned char)c)));
297 #endif
298 #endif
299 }
300
301
302
303 int
304
dk4str8_cpy_s(char * dst,size_t sz,const char * src,dk4_er_t * erp)305 dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp)
306 {
307 int back = 0;
308 #if DK4_USE_ASSERT
309 assert(NULL != dst);
310 assert(0 < sz);
311 #endif
312 if ((NULL != dst) && (0 < sz)) {
313 *dst = '\0';
314 if (NULL != src) {
315 if (dk4str8_len(src) < sz) {
316 #if DK4_ON_WINDOWS
317 /* +++ Windows */
318 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
319 (void)lstrcpyA(dst, (char *)src);
320 #else
321 #if DK4_USE_PRAGMA_WARNING_DISABLE
322 #pragma warning( push )
323 #pragma warning( disable: 4996 )
324 #endif
325 (void)strcpy(dst, src);
326 #if DK4_USE_PRAGMA_WARNING_DISABLE
327 #pragma warning( pop )
328 #endif
329 #endif
330 /* --- Windows */
331 #else
332 /* +++ non-Windows */
333 (void)strcpy(dst, src);
334 /* --- non-Windows */
335 #endif
336 back = 1;
337 } else {
338 *dst = '\0';
339 dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
340 }
341 } else {
342 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
343 }
344 } else {
345 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
346 }
347 return back;
348 }
349
350
351
352 int
353
dk4str8_cat_s(char * dst,size_t sz,const char * src,dk4_er_t * erp)354 dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp)
355 {
356 size_t la;
357 size_t lb;
358 int back = 0;
359 #if DK4_USE_ASSERT
360 assert(NULL != dst);
361 assert(0 < sz);
362 #endif
363 if ((NULL != dst) && (0 < sz) && (NULL != src)) {
364 la = dk4str8_len(dst);
365 lb = dk4str8_len(src);
366 if ((SIZE_MAX - la) >= lb) {
367 if ((la + lb) < sz) {
368 #if DK4_ON_WINDOWS
369 /* +++ Windows */
370 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
371 (void)lstrcatA(dst, (char *)src);
372 #else
373 #if DK4_USE_PRAGMA_WARNING_DISABLE
374 #pragma warning( push )
375 #pragma warning( disable: 4996 )
376 #endif
377 (void)strcat(dst, src);
378 #if DK4_USE_PRAGMA_WARNING_DISABLE
379 #pragma warning( pop )
380 #endif
381 #endif
382 /* --- Windows */
383 #else
384 /* +++ non-Windows */
385 (void)strcat(dst, src);
386 /* --- non-Windows */
387 #endif
388 back = 1;
389 } else {
390 dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
391 }
392 } else {
393 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
394 }
395 } else {
396 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
397 }
398 return back;
399 }
400
401
402
403 int
404
dk4str8_cmp(const char * s1,const char * s2)405 dk4str8_cmp(const char *s1, const char *s2)
406 {
407 int back = 0;
408 if (NULL != s1) {
409 if (NULL != s2) {
410 #if DK4_ON_WINDOWS
411 /* +++ Windows */
412 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
413 back = lstrcmpA(s1, s2);
414 #else
415 back = strcmp(s1, s2);
416 #endif
417 /* --- Windows */
418 #else
419 /* +++ non-Windows */
420 back = strcmp(s1, s2);
421 /* --- non-Windows */
422 #endif
423 if (0 > back) back = -1;
424 if (0 < back) back = 1;
425 } else {
426 back = 1;
427 }
428 } else {
429 if (NULL != s2) {
430 back = -1;
431 }
432 }
433 return back;
434 }
435
436
437
438 int
439
dk4str8_ncmp(const char * s1,const char * s2,size_t n)440 dk4str8_ncmp(const char *s1, const char *s2, size_t n)
441 {
442 int back = 0;
443 if (NULL != s1) {
444 if (NULL != s2) {
445 #if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \
446 || (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP))
447 while((0 < n--) && (0 == back)) {
448 if ('\0' == *s1) {
449 if ('\0' == *s2) {
450 n = 0;
451 } else {
452 back = -1;
453 }
454 } else {
455 if ('\0' == *s2) {
456 back = 1;
457 } else {
458 if (*s1 > *s2) {
459 back = 1;
460 } else {
461 if (*s1 < *s2) {
462 back = -1;
463 } else {
464 s1++; s2++;
465 }
466 }
467 }
468 }
469 }
470 #else
471 back = strncmp(s1, s2, n);
472 if (-1 > back) back = -1;
473 if ( 1 < back) back = 1;
474 #endif
475 } else {
476 back = 1;
477 }
478 } else {
479 if (NULL != s2) {
480 back = -1;
481 }
482 }
483 return back;
484 }
485
486
487
488 int
489
dk4str8_casecmp(const char * s1,const char * s2)490 dk4str8_casecmp(const char *s1, const char *s2)
491 {
492 int back = 0;
493 if (NULL != s1) {
494 if (NULL != s2) {
495 #if DK4_ON_WINDOWS
496 /* +++ Windows */
497 #if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
498 back = lstrcmpiA(s1, s2);
499 #else
500 back = _stricmp(s1, s2);
501 #endif
502 /* --- non-Windows */
503 #else
504 /* +++ non-Windows */
505 #if DK4_HAVE_STRCASECMP
506 back = strcasecmp(s1, s2);
507 #else
508 #if DK4_HAVE__STRICMP
509 back = _stricmp(s1, s2);
510 #else
511 #if DK4_HAVE_STRICMP
512 back = stricmp(s1, s2);
513 #else
514 #error No function for case-insensitive comparison available!
515 #endif
516 #endif
517 #endif
518 /* --- non-Windows */
519 #endif
520 if (0 > back) back = -1;
521 if (0 < back) back = 1;
522 } else {
523 back = 1;
524 }
525 } else {
526 if (NULL != s2) {
527 back = -1;
528 }
529 }
530 return back;
531 }
532
533
534
535 #if (DK4_ON_WINDOWS) || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
536
537 char *
538
dk4str8_dup(const char * src,dk4_er_t * erp)539 dk4str8_dup(const char *src, dk4_er_t *erp)
540 {
541 char *back = NULL;
542 size_t lgt;
543 if (NULL != src) {
544 lgt = dk4str8_len(src);
545 if (SIZE_MAX > lgt) {
546 back = (char *)dk4mem_malloc_bytes((1+lgt), erp);
547 if (NULL != back) {
548 (void)dk4str8_cpy_s(back, (1+lgt), src, erp);
549 }
550 } else {
551 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
552 }
553 } else {
554 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
555 }
556 return back;
557 }
558
559 #endif
560
561
562
563 char *
564
dk4str8_start(const char * src,const char * delim)565 dk4str8_start(const char *src, const char *delim)
566 {
567 char *back = NULL;
568 if (NULL != src) {
569 if (NULL == delim) { delim = dk4str8_modkw[0]; }
570 while (('\0' != *src) && (NULL == back)) {
571 if (NULL != dk4str8_chr(delim, *src)) {
572 src++;
573 } else {
574 back = (char *)src;
575 }
576 }
577 }
578 return back;
579 }
580
581
582
583 /** Internal function for next token search.
584
585 CRT on Windows: Optional, disabling CRT degrades performance.
586 @param src String containing tokens, must be set to
587 the start of a token.
588 @param delim Delimiter set.
589 @return Pointer to next token on success, NULL on error.
590 */
591 static
592 char *
dk4str8_i_next(char * src,const char * delim)593 dk4str8_i_next(char *src, const char *delim)
594 {
595 char *back = NULL;
596 if (NULL != src) {
597 if (NULL == delim) { delim = dk4str8_modkw[0]; }
598 while (('\0' != *src) && (NULL == back)) {
599 if (NULL != dk4str8_chr(delim, *src)) {
600 back = src;
601 } else {
602 src++;
603 }
604 }
605 if (NULL != back) {
606 *(back++) = '\0';
607 back = dk4str8_start(back, delim);
608 }
609 }
610 return back;
611 }
612
613
614
615 char *
616
dk4str8_next(char * src,const char * delim)617 dk4str8_next(char *src, const char *delim)
618 {
619 char *back = NULL;
620 if (NULL != src) {
621 back = dk4str8_start(src, delim);
622 if (NULL != back) {
623 back = dk4str8_i_next(back, delim);
624 }
625 }
626 return back;
627 }
628
629
630
631 char *
632
dk4str8_sep(char ** stringp,const char * delim)633 dk4str8_sep(char **stringp, const char *delim)
634 {
635 char *back = NULL;
636
637 #if DK4_USE_ASSERT
638 assert(NULL != stringp);
639 #endif
640 if (NULL != stringp) {
641 if (NULL != *stringp) {
642 if (NULL == delim) { delim = dk4str8_modkw[0]; }
643 back = dk4str8_start(*stringp, delim);
644 if (NULL != back) {
645 *stringp = dk4str8_next(back, delim);
646 } else {
647 *stringp = NULL;
648 }
649 }
650 }
651 return back;
652 }
653
654
655
656 size_t
657
dk4str8_tokenize(char ** dpp,size_t szdpp,char * src,const char * delim,dk4_er_t * erp)658 dk4str8_tokenize(
659 char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp
660 )
661 {
662 char *context;
663 char *token;
664 size_t back = 0;
665 #if DK4_USE_ASSERT
666 assert(NULL != dpp);
667 assert(0 < szdpp);
668 #endif
669 if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) {
670 if (NULL == delim) { delim = dk4str8_modkw[0]; }
671 context = src;
672 while (NULL != (token = dk4str8_sep(&context, delim))) {
673 if (back < szdpp) {
674 dpp[back] = token;
675 }
676 back++;
677 }
678 if (back >= szdpp) {
679 dk4error_set_elsize_nelem(
680 erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back
681 );
682 back = 0;
683 }
684 } else {
685 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
686 }
687 return back;
688 }
689
690
691
692 void
693
dk4str8_normalize(char * src,const char * delim)694 dk4str8_normalize(char *src, const char *delim)
695 {
696 char *p1; /* Pointer to traverse text. */
697 char *p2; /* Start of next token. */
698 int cc; /* Flag: Can continue. */
699 if (NULL != src) {
700 /*
701 Set up delimiter set, correct if necessary.
702 */
703 if (NULL == delim) { delim = dk4str8_modkw[0]; }
704 /*
705 Remove leading delimiters.
706 */
707 p1 = src;
708 cc = 0;
709 if ('\0' != *p1) {
710 if (NULL != dk4str8_chr(delim, *p1)) {
711 p2 = dk4str8_start(p1, delim);
712 if (NULL != p2) {
713 dk4str8_cpy_to_left(p1, p2);
714 cc = 1;
715 } else {
716 *p1 = '\0';
717 }
718 } else {
719 cc = 1;
720 }
721 }
722 /*
723 Now traverse the string.
724 */
725 while (0 != cc) {
726 if ('\0' == *p1) {
727 cc = 0;
728 } else {
729 if (NULL != dk4str8_chr(delim, *p1)) {
730 *p1 = *delim;
731 if ('\0' == p1[1]) {
732 *p1 = '\0';
733 cc = 0;
734 } else {
735 if (NULL != dk4str8_chr(delim, p1[1])) {
736 p2 = dk4str8_start(p1, delim);
737 if (NULL != p2) {
738 dk4str8_cpy_to_left(++p1, p2);
739 } else {
740 *p1 = '\0';
741 cc = 0;
742 }
743 } else {
744 p1++;
745 }
746 }
747 } else {
748 p1++;
749 }
750 }
751 }
752 }
753 }
754
755
756
757 int
758
dk4str8_array_index(const char * const * arr,const char * str,int cs)759 dk4str8_array_index(const char * const *arr, const char *str, int cs)
760 {
761 int back = -1;
762 int cand = 0;
763 #if DK4_USE_ASSERT
764 assert(NULL != arr);
765 #endif
766 if ((NULL != arr) && (NULL != str)) {
767 while((NULL != *arr) && (-1 == back)) {
768 if (0 != cs) {
769 if (0 == dk4str8_cmp(*arr, str)) { back = cand; }
770 } else {
771 if (0 == dk4str8_casecmp(*arr, str)) { back = cand; }
772 }
773 arr++; cand++;
774 }
775 }
776 return back;
777 }
778
779
780
781 int
782
dk4str8_is_abbr(const char * str,const char * pattern,char spec,int cs)783 dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs)
784 {
785 const char *lptr = NULL; /* Pointer to traverse string */
786 const char *pptr = NULL; /* Pointer to traverse pattern */
787 int back = 0; /* Function result */
788 int fspec = 0; /* Flag: spec was found */
789 int cc = 1; /* Flag: Can continue */
790 char cl;
791 char cp;
792
793 #if DK4_USE_ASSERT
794 assert(NULL != pattern);
795 #endif
796 if ((NULL != str) && (NULL != pattern)) {
797 lptr = str; pptr = pattern;
798 while (0 != cc) {
799 if ((0 == fspec) && (*pptr == spec)) {
800 fspec = 1;
801 pptr++;
802 } else {
803 if ('\0' != *lptr) {
804 cl = *lptr; cp = *pptr;
805 if (0 == cs) {
806 cl = dk4str8_toupper(cl);
807 cp = dk4str8_toupper(cp);
808 }
809 if (cl == cp) {
810 lptr++;
811 pptr++;
812 } else {
813 cc = 0;
814 }
815 } else {
816 cc = 0;
817 if (('\0' == *pptr) || (0 != fspec)) { back = 1; }
818 }
819 }
820 }
821 }
822 return back;
823 }
824
825
826
827 int
828
dk4str8_abbr_index(const char * const * arr,char spec,const char * str,int cs)829 dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs)
830 {
831 int back = -1;
832 int cand = 0;
833
834 #if DK4_USE_ASSERT
835 assert(NULL != arr);
836 #endif
837 if ((NULL != arr) && (NULL != str)) {
838 while ((NULL != *arr) && (-1 == back)) {
839 if (0 != dk4str8_is_abbr(str, *arr, spec, cs)) {
840 back = cand;
841 }
842 arr++; cand++;
843 }
844 }
845
846 return back;
847 }
848
849
850
851 int
852
dk4str8_is_bool(const char * str)853 dk4str8_is_bool(const char *str)
854 {
855 int back = 0;
856 if (NULL != str) {
857 if (-1 < dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0)) {
858 back = 1;
859 }
860 }
861 return back;
862 }
863
864
865
866 int
867
dk4str8_is_on(const char * str)868 dk4str8_is_on(const char *str)
869 {
870 int back = 0;
871
872 if (NULL != str) {
873 back = dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0);
874 if (-1 < back) {
875 if (DK4STR8_FIRST_TRUE <= back) {
876 back = 1;
877 } else {
878 back = 0;
879 }
880 } else {
881 back = 0;
882 }
883 }
884
885 return back;
886 }
887
888
889
890 int
891
dk4str8_pathcmp(const char * s1,const char * s2)892 dk4str8_pathcmp(const char *s1, const char *s2)
893 {
894 #if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
895 return (dk4str8_casecmp(s1, s2));
896 #else
897 return (dk4str8_cmp(s1, s2));
898 #endif
899 }
900
901
902
903 void
904
dk4str8_rtwh(char * str,const char * whsp)905 dk4str8_rtwh(char *str, const char *whsp)
906 {
907 char *ptr = NULL;
908 if (NULL == whsp) { whsp = dk4str8_modkw[0]; }
909 if (NULL != str) {
910 while ('\0' != *str) {
911 if (NULL != dk4str8_chr(whsp, *str)) {
912 if (NULL == ptr) { ptr = str; }
913 } else {
914 ptr = NULL;
915 }
916 str++;
917 }
918 if (NULL != ptr) { *ptr = '\0'; }
919 }
920 }
921
922
923
924 void
925
dk4str8_delnl(char * lptr)926 dk4str8_delnl(char *lptr)
927 {
928 if (NULL != lptr) {
929 while ('\0' != *lptr) {
930 if ('\n' == *lptr) {
931 *lptr = '\0';
932 } else {
933 if ('\r' == *lptr) {
934 if ('\n' == lptr[1]) {
935 *lptr = '\0';
936 } else {
937 if ('\0' == lptr[1]) {
938 *lptr = '\0';
939 } else {
940 lptr++;
941 }
942 }
943 } else {
944 lptr++;
945 }
946 }
947 }
948 }
949 }
950
951
952
953 const char *
954
dk4str8_skip(const char * line,size_t skip)955 dk4str8_skip(const char *line, size_t skip)
956 {
957 const char *back = NULL;
958 size_t words = 0; /* Number of words already found */
959 int lwt = 0; /* Flag: Last char was text */
960
961 if (NULL != line) {
962 if (0 < skip) {
963 while((NULL == back) && ('\0' != *line)) {
964 switch (*line) {
965 case ' ': case '\t': case '\n': case '\r': {
966 lwt = 0;
967 } break;
968 default: {
969 if (0 == lwt) {
970 if (++words > skip) {
971 back = line;
972 }
973 }
974 lwt = 1;
975 } break;
976 }
977 line++;
978 }
979 } else {
980 back = dk4str8_start(line, NULL);
981 }
982 }
983 return back;
984 }
985
986
987
988 int
989
dk4str8_buffer_sanitize(char * str,size_t sz)990 dk4str8_buffer_sanitize(char *str, size_t sz)
991 {
992 int back = 0;
993 #if DK4_USE_ASSERT
994 assert(NULL != str);
995 assert(0 < sz);
996 #endif
997 if (NULL != str) {
998 if (0 < sz) {
999 back = dk4mem_reset_secure(str, sz, NULL);
1000 } else {
1001 back = 1;
1002 }
1003 }
1004 return back;
1005 }
1006
1007
1008
1009 int
1010
dk4str8_sanitize(char * str)1011 dk4str8_sanitize(char *str)
1012 {
1013 int back = 0;
1014 if (NULL != str) {
1015 back = dk4str8_buffer_sanitize(str, dk4str8_len(str));
1016 }
1017 return back;
1018 }
1019
1020
1021
1022 int
1023
dk4str8_free_sanitized(char * str)1024 dk4str8_free_sanitized(char *str)
1025 {
1026 int back = 0;
1027 if (NULL != str) {
1028 back = dk4str8_sanitize(str);
1029 dk4mem_free(str);
1030 }
1031 return back;
1032 }
1033
1034