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