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