1 /*
2 Copyright (C) 2011-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: dk3str.ctr
12 */
13 
14 /**	@file dk3str.c The dk3str module.
15 */
16 
17 
18 #include <libdk3c/dk3all.h>
19 #include <libdk3c/dk3unused.h>
20 
21 
22 
23 
24 
25 
26 /* ************************************************************************ */
27 /* *                                                                      * */
28 /* *         Static data                                                  * */
29 /* *                                                                      * */
30 /* ************************************************************************ */
31 
32 
33 
34 /**	The set of whitespace characters.
35 */
36 static char const dk3str_c8_def_whsp[] = { " \t\r\n" };
37 
38 /**	The current directory.
39 */
40 static char const dk3str_c8_dot[] = { "." };
41 
42 /**	The parent directory.
43 */
44 static char const dk3str_c8_dot_dot[] = { ".." };
45 
46 /**	File name separator.
47 */
48 static char const dk3str_c8_fnsep[] = {
49 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
50 "\\"
51 #else
52 "/"
53 #endif
54 };
55 
56 
57 /**	Keywords to set boolean values.
58 */
59 static char const * const dk3str_c8_bool_kw[] = {
60   "0",
61   "n$o",
62   "of$f",
63   "f$alse",
64   "-",
65   "+",
66   "1",
67   "y$es",
68   "on",
69   "ok",
70   "t$rue",
71   NULL
72 };
73 
74 /**	Index of first "true" entry in \a dk3str_c8_bool_kw.
75 */
76 #define	INDEX_OF_FIRST_BOOLEAN_TRUE 5
77 
78 
79 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
80 /**	File name separator character.
81 */
82 #define	FNS_C8		'\\'
83 /**	Not the file name separator character.
84 */
85 #define	NO_FNS_C8	'/'
86 #else
87 /**	File name separator character.
88 */
89 #define	FNS_C8		'/'
90 /**	Not the file name separator character.
91 */
92 #define	NO_FNS_C8	'\\'
93 #endif
94 
95 
96 
97 /**	Default white spaces set.
98 */
99 static dk3_c16_t const c16_def_whsp[] = {
100   0x0020U, 0x0009U, 0x000AU, 0x000DU, 0U
101 };
102 
103 /**	The dot for the current directory.
104 */
105 static dk3_c16_t const c16_dot[] = {
106   0x002EU, 0U
107 };
108 
109 /**	The dot dot for the parent directory.
110 */
111 static dk3_c16_t const c16_dot_dot[] = {
112   0x002EU, 0x002EU, 0U
113 };
114 
115 /**	File name separator (slash or backslash).
116 */
117 static dk3_c16_t const c16_fnsep[] = {
118 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
119 0x005CU,
120 #else
121 0x002FU,
122 #endif
123 0U
124 };
125 
126 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
127 /**	File name separator for 16-bit character strings.
128 */
129 #define	FNS_C16		0x005CU
130 /**	Not the file name separator for 16-bit character strings.
131 */
132 #define NO_FNS_C16	0x002FU
133 #else
134 /**	File name separator for 16-bit character strings.
135 */
136 #define FNS_C16		0x002FU
137 /**	Not the file name separator for 16-bit character strings.
138 */
139 #define NO_FNS_C16	0x005CU
140 #endif
141 
142 
143 
144 /**	Default whitespaces set.
145 */
146 static dk3_c32_t const c32_def_whsp[] = {
147   0x00000020UL, 0x00000009UL, 0x0000000AUL, 0x0000000DUL, 0UL
148 };
149 
150 /**	The dot is the current directory.
151 */
152 static dk3_c32_t const c32_dot[] = {
153   0x0000002EUL, 0UL
154 };
155 
156 /**	The dot dot is the parent directory.
157 */
158 static dk3_c32_t const c32_dot_dot[] = {
159   0x0000002EUL, 0x0000002EUL, 0UL
160 };
161 
162 /**	File name separator (slash or backslash).
163 */
164 static dk3_c32_t const c32_fnsep[] = {
165 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
166 0x0000005CUL,
167 #else
168 0x0000002FUL,
169 #endif
170 0U
171 };
172 
173 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
174 /**	File name separator for 32-bit character strings.
175 */
176 #define	FNS_C32		0x0000005CUL
177 /**	Not a file name separator for 32-bit character strings.
178 */
179 #define NO_FNS_C32	0x0000002FUL
180 #else
181 /**	File name separator for 32-bit character strings.
182 */
183 #define FNS_C32		0x0000002FUL
184 /**	Not a file name separator for 32-bit character strings.
185 */
186 #define NO_FNS_C32	0x0000005CUL
187 #endif
188 
189 
190 
191 size_t
dk3str_c8_len(char const * s)192 dk3str_c8_len(char const *s)
193 {
194   register size_t back;		/* Function result. */
195 #if DK3_HAVE_STRLEN
196   back = strlen(s);
197 #else
198   register char const *ptr;	/* Pointer to traverse s. */
199   back = 0; ptr = s;
200   while(*(ptr++)) back++;
201 #endif
202   return back;
203 }
204 
205 
206 
207 size_t
dk3str_c16_len(dk3_c16_t const * s)208 dk3str_c16_len(dk3_c16_t const *s)
209 {
210   register size_t back;
211 #if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
212   back = wcslen(s);
213 #else
214 #if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
215   back = _wcslen(s);
216 #else
217   register dk3_c16_t const *ptr;	/* Traverse string. */
218   back = 0; ptr = s;
219   while(*(ptr++)) back++;
220 #endif
221 #endif
222   return back;
223 }
224 
225 
226 
227 size_t
dk3str_c32_len(dk3_c32_t const * s)228 dk3str_c32_len(dk3_c32_t const *s)
229 {
230   register size_t back;
231 #if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
232   back = wcslen(s);
233 #else
234 #if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
235   back = _wcslen(s);
236 #else
237   register dk3_c32_t const *ptr;	/* Traverse source string. */
238   back = 0; ptr = s;
239   while(*(ptr++)) back++;
240 #endif
241 #endif
242   return back;
243 }
244 
245 
246 
247 size_t
dk3str_len(dkChar const * s)248 dk3str_len(dkChar const *s)
249 {
250 #if DK3_CHAR_SIZE > 1
251 #if DK3_CHAR_SIZE > 2
252   return(dk3str_c32_len(s));
253 #else
254   return(dk3str_c16_len(s));
255 #endif
256 #else
257   return(dk3str_c8_len(s));
258 #endif
259 }
260 
261 
262 
263 int
dk3str_c8_cmp(char const * s1,char const * s2)264 dk3str_c8_cmp(char const *s1, char const *s2)
265 {
266   register int back;		/* Function result. */
267 #if DK3_HAVE_STRCMP
268   back = strcmp(s1, s2);
269 #else
270   register char const *p1;	/* Pointer to traverse s1. */
271   register char const *p2;	/* Pointer to traverse s2. */
272   register int  cc;		/* Flag: Can continue. */
273   back = 0; p1 = s1; p2 = s2; cc = 1;
274   while((cc) && (back == 0)) {
275     if(*p1 > *p2) {
276       back = 1;
277     } else {
278       if(*p1 < *p2) {
279         back = -1;
280       } else {
281         if((*p1) && (*p2)) {
282 	  p1++; p2++;
283 	} else {
284 	  cc = 0;
285 	}
286       }
287     }
288   }
289 #endif
290   return back;
291 }
292 
293 
294 
295 int
dk3str_c16_cmp(dk3_c16_t const * s1,dk3_c16_t const * s2)296 dk3str_c16_cmp(dk3_c16_t const *s1, dk3_c16_t const *s2)
297 {
298   register int back;
299 #if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
300   back = wcscmp(s1, s2);
301 #else
302 #if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
303   back = _wcscmp(s1, s2);
304 #else
305   register dk3_c16_t const *p1;	/* Traverse left string. */
306   register dk3_c16_t const *p2;	/* Traverse right string. */
307   register int cc;		/* Flag: Can continue. */
308 
309   back = 0; p1 = s1; p2 = s2; cc = 1;
310   while((cc) && (back == 0)) {
311     if(*p1 > *p2) {
312       back = 1;
313     } else {
314       if(*p1 < *p2) {
315         back = -1;
316       } else {
317         if((*p1) && (*p2)) {
318 	  p1++; p2++;
319 	} else {
320 	  cc = 0;
321 	}
322       }
323     }
324   }
325 #endif
326 #endif
327   return back;
328 }
329 
330 
331 
332 int
dk3str_c32_cmp(dk3_c32_t const * s1,dk3_c32_t const * s2)333 dk3str_c32_cmp(dk3_c32_t const *s1, dk3_c32_t const *s2)
334 {
335   register int back;
336 #if (DK3_HAVE_WCSCMP) && (DK3_SIZEOF_WCHAR_T == 4)
337   back = wcscmp(s1, s2);
338 #else
339 #if (DK3_HAVE__WCSCMP) && (DK3_SIZEOF_WCHAR_T == 4)
340   back = _wcscmp(s1, s2);
341 #else
342   register dk3_c32_t const *p1;	/* Traverse left string. */
343   register dk3_c32_t const *p2;	/* Traverse right string. */
344   register int cc;		/* Flag: Can continue. */
345 
346   back = 0; p1 = s1; p2 = s2; cc = 1;
347   while((cc) && (back == 0)) {
348     if(*p1 > *p2) {
349       back = 1;
350     } else {
351       if(*p1 < *p2) {
352         back = -1;
353       } else {
354         if((*p1) && (*p2)) {
355 	  p1++; p2++;
356 	} else {
357 	  cc = 0;
358 	}
359       }
360     }
361   }
362 #endif
363 #endif
364   return back;
365 }
366 
367 
368 
369 int
dk3str_cmp(dkChar const * s1,dkChar const * s2)370 dk3str_cmp(dkChar const *s1, dkChar const *s2)
371 {
372 #if DK3_CHAR_SIZE > 1
373 #if DK3_CHAR_SIZE > 2
374   return(dk3str_c32_cmp(s1, s2));
375 #else
376   return(dk3str_c16_cmp(s1, s2));
377 #endif
378 #else
379   return(dk3str_c8_cmp(s1, s2));
380 #endif
381 }
382 
383 
384 
385 int
dk3str_c8_casecmp(char const * s1,char const * s2)386 dk3str_c8_casecmp(char const *s1, char const *s2)
387 {
388   register int back;		/* Function result. */
389 #if DK3_HAVE_STRCASECMP
390   back = strcasecmp(s1, s2);
391 #else
392 #if DK3_HAVE_STRICMP && (!DK3_ON_WINDOWS)
393   back = stricmp(s1, s2);
394 #else
395 #if DK3_HAVE__STRICMP || DK3_ON_WINDOWS
396   back = _stricmp(s1, s2);
397 #else
398   register char const *p1;	/* Pointer to traverse s1. */
399   register char const *p2;	/* Pointer to traverse s2. */
400   register char c1;		/* Current character from s1. */
401   register char c2;		/* Current character from s2. */
402   register int cc;		/* Flag: Can continue. */
403   back = 0; p1 = s1; p2 = s2; cc = 1;
404   while((cc) && (back == 0)) {
405     c1 = *p1; c2 = *p2;
406     if((c1 >= 'A') && (c1 <= 'Z')) { c1 = 'a' + (c1 - 'A'); }
407     if((c2 >= 'A') && (c2 <= 'Z')) { c2 = 'a' + (c2 - 'A'); }
408     if(c1 > c2) {
409       back = 1;
410     } else {
411       if(c1 < c2) {
412         back = -1;
413       } else {
414         if((c1) && (c2)) {
415 	  p1++; p2++;
416 	} else {
417 	  cc = 0;
418 	}
419       }
420     }
421   }
422 #endif
423 #endif
424 #endif
425   return back;
426 }
427 
428 
429 
430 int
dk3str_c16_casecmp(dk3_c16_t const * s1,dk3_c16_t const * s2)431 dk3str_c16_casecmp(dk3_c16_t const *s1, dk3_c16_t const *s2)
432 {
433   register int back;
434 #if (DK3_HAVE_WCSICMP) && (DK3_SIZEOF_WCHAR_T == 2)
435   back = wcsicmp(s1, s2);
436 #else
437 #if (DK3_HAVE__WCSICMP) && (DK3_SIZEOF_WCHAR_T == 2)
438   back = _wcsicmp(s1, s2);
439 #else
440   register dk3_c16_t const *p1;	/* Traverse left string. */
441   register dk3_c16_t const *p2;	/* Traverse right string. */
442   register dk3_c16_t c1;	/* Left character. */
443   register dk3_c16_t c2;	/* Right character. */
444   register int cc;		/* Flag: Can continue. */
445 
446   back = 0; p1 = s1; p2 = s2; cc = 1;
447   while((cc) && (back == 0)) {
448     c1 = *p1; c2 = *p2;
449     if((c1 >= 0x0041U) && (c1 <= 0x005AU)) {
450       c1 = (dk3_c16_t)(0x0061U + (c1 - 0x0041U));
451     }
452     if((c2 >= 0x0041U) && (c2 <= 0x005AU)) {
453       c2 = (dk3_c16_t)(0x0061U + (c2 - 0x0041U));
454     }
455     if(c1 > c2) {
456       back = 1;
457     } else {
458       if(c1 < c2) {
459         back = -1;
460       } else {
461         if((c1) && (c2)) {
462 	  p1++; p2++;
463 	} else {
464 	  cc = 0;
465 	}
466       }
467     }
468   }
469 #endif
470 #endif
471   return back;
472 }
473 
474 
475 
476 int
dk3str_c32_casecmp(dk3_c32_t const * s1,dk3_c32_t const * s2)477 dk3str_c32_casecmp(dk3_c32_t const *s1, dk3_c32_t const *s2)
478 {
479   register int back;
480 #if (DK3_HAVE_WCSICMP) && (DK3_SIZEOF_WCHAR_T == 4)
481   back = wcsicmp(s1, s2);
482 #else
483 #if (DK3_HAVE__WCSICMP) && (DK3_SIZEOF_WCHAR_T == 4)
484   back = _wcsicmp(s1, s2);
485 #else
486   register dk3_c32_t const *p1;	/* Traverse left string. */
487   register dk3_c32_t const *p2;	/* Traverse right string. */
488   register dk3_c32_t c1;	/* Left character. */
489   register dk3_c32_t c2;	/* Right character. */
490   register int cc;		/* Flag: Can continue. */
491 
492   back = 0; p1 = s1; p2 = s2; cc = 1;
493   while((cc) && (back == 0)) {
494     c1 = *p1; c2 = *p2;
495     if((c1 >= (dk3_c32_t)0x00000041UL) && (c1 <= (dk3_c32_t)0x0000005AUL)) {
496       c1 = (dk3_c32_t)(0x00000061UL + ((unsigned long)c1 - 0x00000041UL));
497     }
498     if((c2 >= (dk3_c32_t)0x00000041UL) && (c2 <= (dk3_c32_t)0x0000005AUL)) {
499       c2 = (dk3_c32_t)(0x00000061UL + ((unsigned long)c2 - 0x00000041UL));
500     }
501     if(c1 > c2) {
502       back = 1;
503     } else {
504       if(c1 < c2) {
505         back = -1;
506       } else {
507         if((c1) && (c2)) {
508 	  p1++; p2++;
509 	} else {
510 	  cc = 0;
511 	}
512       }
513     }
514   }
515 #endif
516 #endif
517   return back;
518 }
519 
520 
521 
522 int
dk3str_casecmp(dkChar const * s1,dkChar const * s2)523 dk3str_casecmp(dkChar const *s1, dkChar const *s2)
524 {
525 #if DK3_CHAR_SIZE > 1
526 #if DK3_CHAR_SIZE > 2
527   return(dk3str_c32_casecmp(s1, s2));
528 #else
529   return(dk3str_c16_casecmp(s1, s2));
530 #endif
531 #else
532   return(dk3str_c8_casecmp(s1, s2));
533 #endif
534 }
535 
536 
537 
538 int
dk3str_fncmp(dkChar const * s1,dkChar const * s2)539 dk3str_fncmp(dkChar const *s1, dkChar const *s2)
540 {
541 #if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
542   return(dk3str_casecmp(s1, s2));
543 #else
544   return(dk3str_cmp(s1, s2));
545 #endif
546 }
547 
548 
549 int
dk3str_c8_ncmp(char const * s1,char const * s2,size_t n)550 dk3str_c8_ncmp(char const *s1, char const *s2, size_t n)
551 {
552   register int back;		/* Function result. */
553 #if DK3_HAVE_STRNCMP
554   back = strncmp(s1, s2, n);
555 #else
556   register char const *p1;	/* Pointer to traverse s1. */
557   register char const *p2;	/* Pointer to traverse s2. */
558   register size_t max;		/* Register copy of n. */
559   register size_t used;		/* Number of chars already used. */
560   back = 0; p1 = s1; p2 = s2; max = n; used = 0;
561   while((used < max) && (back == 0)) {
562     if(*p1 > *p2) {
563       back = 1;
564     } else {
565       if(*p1 < *p2) {
566         back = -1;
567       } else {
568         if((*p1) && (*p2)) {
569 	  p1++; p2++; used++;
570 	} else {
571 	  used = max;
572 	}
573       }
574     }
575   }
576 #endif
577   return back;
578 }
579 
580 
581 
582 int
dk3str_c16_ncmp(dk3_c16_t const * s1,dk3_c16_t const * s2,size_t n)583 dk3str_c16_ncmp(dk3_c16_t const *s1, dk3_c16_t const *s2, size_t n)
584 {
585   register int back;
586 #if (DK3_HAVE_WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 2)
587   back = wcsncmp(s1, s2, n);
588 #else
589 #if (DK3_HAVE__WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 2)
590   back = _wcsncmp(s1, s2, n);
591 #else
592   register dk3_c16_t const *p1;	/* Traverse left string. */
593   register dk3_c16_t const *p2;	/* Traverse right string. */
594   register size_t max;		/* Maximum number of characters to compare. */
595   register size_t used;		/* Number of characters already compared. */
596 
597   back = 0; p1 = s1; p2 = s2; max = n; used = 0;
598   while((used < max) && (back == 0)) {
599     if(*p1 > *p2) {
600       back = 1;
601     } else {
602       if(*p1 < *p2) {
603         back = -1;
604       } else {
605         if((*p1) && (*p2)) {
606 	  p1++; p2++; used++;
607 	} else {
608 	  used = max;
609 	}
610       }
611     }
612   }
613 #endif
614 #endif
615   return back;
616 }
617 
618 
619 
620 int
dk3str_c32_ncmp(dk3_c32_t const * s1,dk3_c32_t const * s2,size_t n)621 dk3str_c32_ncmp(dk3_c32_t const *s1, dk3_c32_t const *s2, size_t n)
622 {
623   register int back;
624 #if (DK3_HAVE_WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 4)
625   back = wcsncmp(s1, s2, n);
626 #else
627 #if (DK3_HAVE__WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 4)
628   back = _wcsncmp(s1, s2, n);
629 #else
630   register dk3_c32_t const *p1;	/* Traverse left string. */
631   register dk3_c32_t const *p2;	/* Traverse right string. */
632   register size_t max;		/* Maximum number of characters to compare. */
633   register size_t used;		/* Number of characters used. */
634 
635   back = 0; p1 = s1; p2 = s2; max = n; used = 0;
636   while((used < max) && (back == 0)) {
637     if(*p1 > *p2) {
638       back = 1;
639     } else {
640       if(*p1 < *p2) {
641         back = -1;
642       } else {
643         if((*p1) && (*p2)) {
644 	  p1++; p2++; used++;
645 	} else {
646 	  used = max;
647 	}
648       }
649     }
650   }
651 #endif
652 #endif
653   return back;
654 }
655 
656 
657 
658 int
dk3str_ncmp(dkChar const * s1,dkChar const * s2,size_t n)659 dk3str_ncmp(dkChar const *s1, dkChar const *s2, size_t n)
660 {
661 #if DK3_CHAR_SIZE > 1
662 #if DK3_CHAR_SIZE > 2
663   return(dk3str_c32_ncmp(s1, s2, n));
664 #else
665   return(dk3str_c16_ncmp(s1, s2, n));
666 #endif
667 #else
668   return(dk3str_c8_ncmp(s1, s2, n));
669 #endif
670 }
671 
672 
673 
674 char *
dk3str_c8_chr(char const * s,char c)675 dk3str_c8_chr(char const *s, char c)
676 {
677   register char *back;		/* Function result. */
678 #if DK3_HAVE_STRCHR
679 #ifdef	__cplusplus
680   back = (char *)strchr(s, c);
681 #else
682   back = strchr(s, c);
683 #endif
684 #else
685   register char const *ptr;	/* Pointer to traverse s. */
686   register char chr;		/* Register copy of c. */
687   back = NULL; ptr = s; chr = c;
688   while((*ptr) && (back == NULL)) {
689     if(*ptr == chr) { back = (char *)ptr; } else { ptr++; }
690   }
691 #endif
692   return back;
693 }
694 
695 
696 
697 dk3_c16_t *
dk3str_c16_chr(dk3_c16_t const * s,dk3_c16_t c)698 dk3str_c16_chr(dk3_c16_t const *s, dk3_c16_t c)
699 {
700   register dk3_c16_t *back;
701 #if (DK3_HAVE_WCSCHR) && (DK3_SIZEOF_WCHAR_T == 2)
702   back = wcschr(s, c);
703 #else
704 #if (DK3_HAVE__WCSCHR) && (DK3_SIZEOF_WCHAR_T == 2)
705   back = _wcschr(s, c);
706 #else
707   register dk3_c16_t const *ptr;	/* Traverse source string. */
708   register dk3_c16_t chr;		/* Character to search for. */
709   back = NULL; ptr = s; chr = c;
710   while((*ptr) && (back == NULL)) {
711     if(*ptr == chr) { back = (dk3_c16_t *)ptr; } else { ptr++; }
712   }
713 #endif
714 #endif
715   return back;
716 }
717 
718 
719 
720 dk3_c32_t *
dk3str_c32_chr(dk3_c32_t const * s,dk3_c32_t c)721 dk3str_c32_chr(dk3_c32_t const *s, dk3_c32_t c)
722 {
723   register dk3_c32_t *back;
724 #if (DK3_HAVE_WCSCHR) && (DK3_SIZEOF_WCHAR_T == 4)
725 #ifdef __cplusplus
726   back = (dk3_c32_t *)wcschr(s, c);
727 #else
728   back = wcschr(s, c);
729 #endif
730 #else
731 #if (DK3_HAVE__WCSCHR) && (DK3_SIZEOF_WCHAR_T == 4)
732   back = _wcschr(s, c);
733 #else
734   register dk3_c32_t const *ptr;	/* Traverse source string. */
735   register dk3_c32_t chr;		/* Character to find. */
736 
737   back = NULL; ptr = s; chr = c;
738   while((*ptr) && (back == NULL)) {
739     if(*ptr == chr) { back = (dk3_c32_t *)ptr; } else { ptr++; }
740   }
741 #endif
742 #endif
743   return back;
744 }
745 
746 
747 
748 dkChar *
dk3str_chr(dkChar const * s,dkChar c)749 dk3str_chr(dkChar const *s, dkChar c)
750 {
751 #if DK3_CHAR_SIZE > 1
752 #if DK3_CHAR_SIZE > 2
753   return(dk3str_c32_chr(s, c));
754 #else
755   return(dk3str_c16_chr(s, c));
756 #endif
757 #else
758   return(dk3str_c8_chr(s, c));
759 #endif
760 }
761 
762 
763 char *
dk3str_c8_rchr(char const * s,char c)764 dk3str_c8_rchr(char const *s, char c)
765 {
766   register char *back;		/* Function result. */
767 #if DK3_HAVE_STRRCHR
768 #ifdef	__cplusplus
769   back = (char *)strrchr(s, c);
770 #else
771   back = strrchr(s, c);
772 #endif
773 #else
774   register char const *ptr;	/* Pointer to traverse s. */
775   register char chr;		/* Register copy of c. */
776   back = NULL; ptr = s; chr = c;
777   while(*ptr) {
778     if(*ptr == chr) { back = (char *)ptr; }
779     ptr++;
780   }
781 #endif
782   return back;
783 }
784 
785 
786 
787 
788 dk3_c16_t *
dk3str_c16_rchr(dk3_c16_t const * s,dk3_c16_t c)789 dk3str_c16_rchr(dk3_c16_t const *s, dk3_c16_t c)
790 {
791   register dk3_c16_t *back;
792 #if (DK3_HAVE_WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 2)
793   back = wcsrchr(s, c);
794 #else
795 #if (DK3_HAVE__WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 2)
796   back = _wcsrchr(s, c);
797 #else
798   register dk3_c16_t const *ptr;	/* Traverse the string. */
799   register dk3_c16_t chr;		/* Character to search for. */
800   back = NULL; ptr = s; chr = c;
801   while(*ptr) {
802     if(*ptr == chr) { back = (dk3_c16_t *)ptr; }
803     ptr++;
804   }
805 #endif
806 #endif
807   return back;
808 }
809 
810 
811 
812 dk3_c32_t *
dk3str_c32_rchr(dk3_c32_t const * s,dk3_c32_t c)813 dk3str_c32_rchr(dk3_c32_t const *s, dk3_c32_t c)
814 {
815   register dk3_c32_t *back;
816 #if (DK3_HAVE_WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 4)
817 #ifdef	__cplusplus
818   back = (dk3_c32_t *)wcsrchr(s, c);
819 #else
820   back = wcsrchr(s, c);
821 #endif
822 #else
823 #if (DK3_HAVE__WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 4)
824 #ifdef	__cplusplus
825   back = (dk4_c32_t *)_wcsrchr(s, c);
826 #else
827   back = _wcsrchr(s, c);
828 #endif
829 #else
830   register dk3_c32_t const *ptr;	/* Traverse source string. */
831   register dk3_c32_t chr;		/* Character to search for. */
832 
833   back = NULL; ptr = s; chr = c;
834   while(*ptr) {
835     if(*ptr == chr) { back = (dk3_c32_t *)ptr; }
836     ptr++;
837   }
838 #endif
839 #endif
840   return back;
841 }
842 
843 
844 
845 dkChar *
dk3str_rchr(dkChar const * s,dkChar c)846 dk3str_rchr(dkChar const *s, dkChar c)
847 {
848 #if DK3_CHAR_SIZE > 1
849 #if DK3_CHAR_SIZE > 2
850   return(dk3str_c32_rchr(s, c));
851 #else
852   return(dk3str_c16_rchr(s, c));
853 #endif
854 #else
855   return(dk3str_c8_rchr(s, c));
856 #endif
857 }
858 
859 
860 void
dk3str_c8_cpy(char * d,char const * s)861 dk3str_c8_cpy(char *d, char const *s)
862 {
863   register char *dp;		/* Destination buffer pointer. */
864   register char const *sp;	/* Source buffer pointer. */
865   register char x;
866   dp = d; sp = s;
867   while(*sp) { x = *(sp++); *(dp++) = x; }
868   *dp = '\0';
869 }
870 
871 
872 
873 void
dk3str_c16_cpy(dk3_c16_t * d,dk3_c16_t const * s)874 dk3str_c16_cpy(dk3_c16_t *d, dk3_c16_t const *s)
875 {
876   register dk3_c16_t *dp;	/* Destination pointer. */
877   register dk3_c16_t const *sp;	/* Source pointer. */
878   register dk3_c16_t x;		/* Current character. */
879 
880   dp = d; sp = s;
881   while(*sp) { x = *(sp++); *(dp++) = x; }
882   *dp = 0U;
883 }
884 
885 
886 
887 void
dk3str_c32_cpy(dk3_c32_t * d,dk3_c32_t const * s)888 dk3str_c32_cpy(dk3_c32_t *d, dk3_c32_t const *s)
889 {
890   register dk3_c32_t *dp;	/* Destination pointer. */
891   register dk3_c32_t const *sp;	/* Source pointer. */
892   register dk3_c32_t x;		/* Current character. */
893   dp = d; sp = s;
894   while(*sp) { x = *(sp++); *(dp++) = x; }
895   *dp = 0UL;
896 }
897 
898 
899 
900 void
dk3str_cpy(dkChar * d,dkChar const * s)901 dk3str_cpy(dkChar *d, dkChar const *s)
902 {
903 #if DK3_CHAR_SIZE > 1
904 #if DK3_CHAR_SIZE > 2
905   dk3str_c32_cpy(d, s);
906 #else
907   dk3str_c16_cpy(d, s);
908 #endif
909 #else
910   dk3str_c8_cpy(d, s);
911 #endif
912 }
913 
914 
915 void
dk3str_c8_cpy_not_overlapped(char * d,char const * s)916 dk3str_c8_cpy_not_overlapped(char *d, char const *s)
917 {
918 #if DK3_HAVE_STRCPY
919   strcpy(d, s);
920 #else
921 #if DK3_HAVE_STRLEN
922   size_t	sz;
923   int		ec	=	0;
924   sz = dk3mem_add_size_t(1, strlen(s), &ec);
925   if((0 != sz) && (0 == ec)) {
926     dk3mem_cpy(d,s,sz);
927   } else {
928     dk3str_c8_cpy(d, s);
929   }
930 #else
931   dk3str_c8_cpy(d, s);
932 #endif
933 #endif
934 }
935 
936 
937 
938 void
dk3str_c16_cpy_not_overlapped(dk3_c16_t * d,dk3_c16_t const * s)939 dk3str_c16_cpy_not_overlapped(dk3_c16_t *d, dk3_c16_t const *s)
940 {
941 #if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
942   wcscpy(d, s);
943 #else
944 #if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
945   _wcscpy(d, s);
946 #else
947 #if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
948   size_t	sz;
949   int		ec	= 0;
950   sz = dk3mem_mul_size_t(2, dk3mem_add_size_t(1, wcslen(s), &ec), &ec);
951   if((0 != sz) && (0 == ec)) {
952     dk3mem_cpy(d, s, sz);
953   } else {
954     dk3str_c16_cpy(d,s);
955   }
956 #else
957 #if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
958   size_t	sz;
959   int		ec	= 0;
960   sz = dk3mem_mul_size_t(2, dk3mem_add_size_t(1, _wcslen(s), &ec), &ec);
961   if((0 != sz) && (0 == ec)) {
962     dk3mem_cpy(d, s, sz);
963   } else {
964     dk3str_c16_cpy(d,s);
965   }
966 #else
967   dk3str_c16_cpy(d,s);
968 #endif
969 #endif
970 #endif
971 #endif
972 }
973 
974 
975 
976 void
dk3str_c32_cpy_not_overlapped(dk3_c32_t * d,dk3_c32_t const * s)977 dk3str_c32_cpy_not_overlapped(dk3_c32_t *d, dk3_c32_t const *s)
978 {
979 #if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 4)
980   wcscpy(d, s);
981 #else
982 #if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 4)
983   _wcscpy(d, s);
984 #else
985 #if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
986   size_t	sz;
987   int		ec	= 0;
988   sz = dk3mem_mul_size_t(4, dk3mem_add_size_t(1, wcslen(s), &ec), &ec);
989   if((0 != sz) && (0 == ec)) {
990     dk3mem_cpy(d, s, sz);
991   } else {
992     dk3str_c32_cpy(d,s);
993   }
994 #else
995 #if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
996   size_t	sz;
997   int		ec	= 0;
998   sz = dk3mem_mul_size_t(4, dk3mem_add_size_t(1, _wcslen(s), &ec), &ec);
999   if((0 != sz) && (0 == ec)) {
1000     dk3mem_cpy(d, s, sz);
1001   } else {
1002     dk3str_c32_cpy(d,s);
1003   }
1004 #else
1005   dk3str_c32_cpy(d,s);
1006 #endif
1007 #endif
1008 #endif
1009 #endif
1010 }
1011 
1012 
1013 
1014 void
dk3str_cpy_not_overlapped(dkChar * d,dkChar const * s)1015 dk3str_cpy_not_overlapped(dkChar *d, dkChar const *s)
1016 {
1017 #if DK3_CHAR_SIZE > 1
1018 #if DK3_CHAR_SIZE > 2
1019   dk3str_c32_cpy_not_overlapped(d, s);
1020 #else
1021   dk3str_c16_cpy_not_overlapped(d, s);
1022 #endif
1023 #else
1024   dk3str_c8_cpy_not_overlapped(d, s);
1025 #endif
1026 }
1027 
1028 
1029 void
dk3str_c8_ncpy(char * d,char const * s,size_t n)1030 dk3str_c8_ncpy(char *d, char const *s, size_t n)
1031 {
1032 #if DK3_HAVE_STRNCPY
1033   strncpy(d,s,n);
1034   d[n-1] = '\0';
1035 #else
1036   register char *dp;		/* Destination buffer pointer. */
1037   register char const *sp;	/* Source buffer pointer. */
1038   register size_t max;		/* Register copy of n. */
1039   register size_t used;		/* Number of characters already copied. */
1040   register char	  x;
1041   dp = d; sp = s; max = n; used = 0;
1042   while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x;  used++; }
1043   if(used < max) { *dp = '\0'; }
1044   else		 { d[max - 1] = '\0'; }
1045 #endif
1046 }
1047 
1048 
1049 
1050 void
dk3str_c16_ncpy(dk3_c16_t * d,dk3_c16_t const * s,size_t n)1051 dk3str_c16_ncpy(dk3_c16_t *d, dk3_c16_t const *s, size_t n)
1052 {
1053 #if (DK3_HAVE_WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 2)
1054   wcsncpy(d,s,n);
1055   d[n-1] = 0U;
1056 #else
1057 #if (DK3_HAVE__WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 2)
1058   _wcsncpy(d,s,n);
1059   d[n-1] = 0U;
1060 #else
1061   register dk3_c16_t *dp;	/* Destionation pointer. */
1062   register dk3_c16_t const *sp;	/* Source pointer. */
1063   register dk3_c16_t x;		/* Current character. */
1064   register size_t max;		/* Maximum number of characters to copy. */
1065   register size_t used;		/* Characters already copied. */
1066 
1067   dp = d; sp = s; max = n; used = 0;
1068   while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
1069   if(used < max) { *dp = 0U; }
1070   else { d[max - 1] = 0U; }
1071 #endif
1072 #endif
1073 }
1074 
1075 
1076 
1077 void
dk3str_c32_ncpy(dk3_c32_t * d,dk3_c32_t const * s,size_t n)1078 dk3str_c32_ncpy(dk3_c32_t *d, dk3_c32_t const *s, size_t n)
1079 {
1080 #if (DK3_HAVE_WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 4)
1081   wcsncpy(d,s,n);
1082   d[n-1] = 0UL;
1083 #else
1084 #if (DK3_HAVE__WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 4)
1085   _wcsncpy(d,s,n);
1086   d[n-1] = 0UL;
1087 #else
1088   register dk3_c32_t *dp;	/* Destination pointer. */
1089   register dk3_c32_t const *sp;	/* Source pointer. */
1090   register dk3_c32_t x;		/* Current character. */
1091   register size_t max;		/* Maximum number of characters to copy. */
1092   register size_t used;		/* Number of characters copied. */
1093 
1094   dp = d; sp = s; max = n; used = 0;
1095   while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
1096   if(used < max) { *dp = 0UL; }
1097   else { d[max - 1] = 0UL; }
1098 #endif
1099 #endif
1100 }
1101 
1102 
1103 
1104 void
dk3str_ncpy(dkChar * d,dkChar const * s,size_t n)1105 dk3str_ncpy(dkChar *d, dkChar const *s, size_t n)
1106 {
1107 #if DK3_CHAR_SIZE > 1
1108 #if DK3_CHAR_SIZE > 2
1109   dk3str_c32_ncpy(d, s, n);
1110 #else
1111   dk3str_c16_ncpy(d, s, n);
1112 #endif
1113 #else
1114   dk3str_c8_ncpy(d, s, n);
1115 #endif
1116 }
1117 
1118 
1119 
1120 void
dk3str_c8_cat(char * d,char const * s)1121 dk3str_c8_cat(char *d, char const *s)
1122 {
1123 #if DK3_HAVE_STRCAT
1124   strcat(d, s);
1125 #else
1126   register char *dp;		/* Destination buffer pointer. */
1127   register char const *sp;	/* Source buffer pointer. */
1128   register char x;
1129   dp = d; sp = s;
1130   while(*dp) dp++;
1131   while(*sp) { x = *(sp++); *(dp++) = x; }
1132   *dp = '\0';
1133 #endif
1134 }
1135 
1136 
1137 
1138 void
dk3str_c16_cat(dk3_c16_t * d,dk3_c16_t const * s)1139 dk3str_c16_cat(dk3_c16_t *d, dk3_c16_t const *s)
1140 {
1141 #if (DK3_HAVE_WCSCAT) && (DK3_SIZEOF_WCHAR_T == 2)
1142   wcscat(d, s);
1143 #else
1144 #if (DK3_HAVE__WCSCAT) && (DK3_SIZEOF_WCHAR_T == 2)
1145   _wcscat(d, s);
1146 #else
1147   register dk3_c16_t *dp;	/* Destination pointer. */
1148   register dk3_c16_t const *sp;	/* Source pointer. */
1149   register dk3_c16_t x;		/* Current character. */
1150   dp = d; sp = s;
1151   while(*dp) dp++;
1152   while(*sp) { x = *(sp++); *(dp++) = x;  }
1153   *dp = 0U;
1154 #endif
1155 #endif
1156 }
1157 
1158 
1159 
1160 void
dk3str_c32_cat(dk3_c32_t * d,dk3_c32_t const * s)1161 dk3str_c32_cat(dk3_c32_t *d, dk3_c32_t const *s)
1162 {
1163 #if (DK3_HAVE_WCSCAT) && (DK3_SIZEOF_WCHAR_T == 4)
1164   wcscat(d, s);
1165 #else
1166 #if (DK3_HAVE__WCSCAT) && (DK3_SIZEOF_WCHAR_T == 4)
1167   _wcscat(d, s);
1168 #else
1169   register dk3_c32_t *dp;	/* Destination pointer. */
1170   register dk3_c32_t const *sp;	/* Source pointer. */
1171   register dk3_c32_t x;		/* Current character. */
1172 
1173   dp = d; sp = s;
1174   while(*dp) dp++;
1175   while(*sp) { x = *(sp++); *(dp++) = x; }
1176   *dp = 0UL;
1177 #endif
1178 #endif
1179 }
1180 
1181 
1182 
1183 void
dk3str_cat(dkChar * d,dkChar const * s)1184 dk3str_cat(dkChar *d, dkChar const *s)
1185 {
1186 #if DK3_CHAR_SIZE > 1
1187 #if DK3_CHAR_SIZE > 2
1188   dk3str_c32_cat(d, s);
1189 #else
1190   dk3str_c16_cat(d, s);
1191 #endif
1192 #else
1193   dk3str_c8_cat(d, s);
1194 #endif
1195 }
1196 
1197 
1198 
1199 /**	Report memory allocation error.
1200 	@param	app	Application structure.
1201 	@param	elsize	Size of one character.
1202 	@param	nelem	Number of characters required.
1203 */
1204 static
1205 void
dk3str_memory_error(dk3_app_t * app,size_t elsize,size_t nelem)1206 dk3str_memory_error(dk3_app_t *app, size_t elsize, size_t nelem)
1207 {
1208 #if VERSION_BEFORE_20140716
1209   dkChar	bu1[64];
1210   unsigned long	prod;
1211   prod = (unsigned long)elsize * (unsigned long)nelem;
1212   dk3sf_sprintf3(bu1, dkT("%lu"), prod);
1213   dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, bu1);
1214 #else
1215   dkChar	bu1[64];
1216   dk3_um_t	prod;
1217   int		mec = 0;
1218   prod = dk3ma_um_mul_ok((dk3_um_t)elsize, (dk3_um_t)nelem, &mec);
1219   if (0 == mec) {
1220     if (dk3ma_um_to_string(bu1, DK3_SIZEOF(bu1,dkChar), (dk3_um_t)prod)) {
1221       dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, bu1);
1222     }
1223   } else {
1224     /* Math overflow in size calculation */
1225     dk3app_log_i1(app, DK3_LL_ERROR, 15);
1226   }
1227 #endif
1228 }
1229 
1230 
1231 
1232 char *
dk3str_c8_dup_app(char const * s,dk3_app_t * app)1233 dk3str_c8_dup_app(char const *s, dk3_app_t *app)
1234 {
1235   char	*back;
1236 #if DK3_HAVE_STRDUP && (!DK3_ON_WINDOWS)
1237   back = strdup(s);
1238   if(!(back)) {
1239     if(app) {
1240       dk3str_memory_error(app, 1, (1+strlen(s)));
1241     }
1242   }
1243 #else
1244 #if DK3_HAVE__STRDUP || DK3_ON_WINDOWS
1245   back = _strdup(s);
1246   if(!(back)) {
1247     if(app) {
1248       dk3str_memory_error(app, 1, (1+strlen(s)));
1249     }
1250   }
1251 #else
1252   size_t sz;
1253   sz = 1 + dk3str_c8_len(s);
1254   if(app) {
1255     back = dk3_new_app(char,sz,app);
1256   } else {
1257     back = dk3_new(char,sz);
1258   }
1259   if(back) {
1260     dk3str_c8_cpy_not_overlapped(back, s);
1261   }
1262 #endif
1263 #endif
1264   return back;
1265 }
1266 
1267 
1268 
1269 dk3_c16_t *
dk3str_c16_dup_app(dk3_c16_t const * s,dk3_app_t * app)1270 dk3str_c16_dup_app(dk3_c16_t const *s, dk3_app_t *app)
1271 {
1272   dk3_c16_t *back;
1273 #if (DK3_HAVE_WCSDUP) && (DK3_SIZEOF_WCHAR_T == 2)
1274   back = wcsdup(s);
1275   if(!(back)) {
1276     if(app) {
1277       dk3str_memory_error(app, 2, (1 + dk3str_c16_len(s)));
1278     }
1279   }
1280 #else
1281 #if (DK3_HAVE__WCSDUP) && (DK3_SIZEOF_WCHAR_T == 2)
1282   back = _wcsdup(s);
1283   if(!(back)) {
1284     if(app) {
1285       dk3str_memory_error(app, 2, (1 + dk3str_c16_len(s)));
1286     }
1287   }
1288 #else
1289   size_t sz;
1290   sz = 1 + dk3str_c16_len(s);
1291   if(app) {
1292     back = dk3_new_app(dk3_c16_t,sz,app);
1293   } else {
1294     back = dk3_new(dk3_c16_t,sz);
1295   }
1296   if(back) {
1297     dk3str_c16_cpy_not_overlapped(back, s);
1298   }
1299 #endif
1300 #endif
1301   return back;
1302 }
1303 
1304 
1305 
1306 dk3_c32_t *
dk3str_c32_dup_app(dk3_c32_t const * s,dk3_app_t * app)1307 dk3str_c32_dup_app(dk3_c32_t const *s, dk3_app_t *app)
1308 {
1309   dk3_c32_t *back;
1310 #if (DK3_HAVE_WCSDUP) && (DK3_SIZEOF_WCHAR_T == 4)
1311   back = wcsdup(s);
1312   if(!(back)) {
1313     if(app) {
1314       dk3str_memory_error(app, 4, (1 + dk3str_c32_len(s)));
1315     }
1316   }
1317 #else
1318 #if (DK3_HAVE__WCSDUP) && (DK3_SIZEOF_WCHAR_T == 4)
1319   back = _wcsdup(s);
1320   if(!(back)) {
1321     if(app) {
1322       dk3str_memory_error(app, 4, (1 + dk3str_c32_len(s)));
1323     }
1324   }
1325 #else
1326   size_t sz;
1327   sz = 1 + dk3str_c32_len(s);
1328   if(app) {
1329     back = dk3_new_app(dk3_c32_t,sz,app);
1330   } else {
1331     back = dk3_new(dk3_c32_t,sz);
1332   }
1333   if(back) {
1334     dk3str_c32_cpy(back, s);
1335   }
1336 #endif
1337 #endif
1338   return back;
1339 }
1340 
1341 
1342 
1343 dkChar *
dk3str_dup_app(dkChar const * s,dk3_app_t * app)1344 dk3str_dup_app(dkChar const *s, dk3_app_t *app)
1345 {
1346 #if DK3_CHAR_SIZE > 1
1347 #if DK3_CHAR_SIZE > 2
1348   return(dk3str_c32_dup_app(s, app));
1349 #else
1350   return(dk3str_c16_dup_app(s, app));
1351 #endif
1352 #else
1353   return(dk3str_c8_dup_app(s, app));
1354 #endif
1355 }
1356 
1357 
1358 char
dk3str_c8_tolower(char c)1359 dk3str_c8_tolower(char c)
1360 {
1361   char back;		/* Function result. */
1362   back = c;
1363   if((back >= 'A') && (back <= 'Z')) {
1364     back = (char)('a' + (back - 'A'));
1365   }
1366   return back;
1367 }
1368 
1369 
1370 
1371 dk3_c16_t
dk3str_c16_tolower(dk3_c16_t c)1372 dk3str_c16_tolower(dk3_c16_t c)
1373 {
1374   dk3_c16_t back;
1375   back = c;
1376   if((back >= 0x0041U) && (back <= 0x005AU)) {
1377     back = (dk3_c16_t)(0x0061U + (back - 0x0041U));
1378   }
1379   return back;
1380 }
1381 
1382 
1383 
1384 dk3_c32_t
dk3str_c32_tolower(dk3_c32_t c)1385 dk3str_c32_tolower(dk3_c32_t c)
1386 {
1387   dk3_c32_t back;
1388   back = c;
1389   if((back >= (dk3_c32_t)0x00000041UL) && (back <= (dk3_c32_t)0x0000005AUL)) {
1390     back = (dk3_c32_t)0x00000061UL + (back - (dk3_c32_t)0x00000041UL);
1391   }
1392   return back;
1393 }
1394 
1395 
1396 
1397 dkChar
dk3str_tolower(dkChar c)1398 dk3str_tolower(dkChar c)
1399 {
1400 #if DK3_CHAR_SIZE > 1
1401 #if DK3_CHAR_SIZE > 2
1402   return(dk3str_c32_tolower(c));
1403 #else
1404   return(dk3str_c16_tolower(c));
1405 #endif
1406 #else
1407   return(dk3str_c8_tolower(c));
1408 #endif
1409 }
1410 
1411 
1412 
1413 char
dk3str_c8_toupper(char c)1414 dk3str_c8_toupper(char c)
1415 {
1416   char back;		/* Function result. */
1417   back = c;
1418   if((back >= 'a') && (back <= 'z')) {
1419     back = (char)('A' + (back - 'a'));
1420   }
1421   return back;
1422 }
1423 
1424 
1425 
1426 dk3_c16_t
dk3str_c16_toupper(dk3_c16_t c)1427 dk3str_c16_toupper(dk3_c16_t c)
1428 {
1429   dk3_c16_t back;
1430   back = c;
1431   if((back >= 0x0061U) && (back <= 0x007AU)) {
1432     back = (dk3_c16_t)(0x0041U + (back - 0x0061U));
1433   }
1434   return back;
1435 }
1436 
1437 
1438 
1439 dk3_c32_t
dk3str_c32_toupper(dk3_c32_t c)1440 dk3str_c32_toupper(dk3_c32_t c)
1441 {
1442   dk3_c32_t back;
1443   back = c;
1444   if((back >= (dk3_c32_t)0x00000061UL) && (back <= (dk3_c32_t)0x0000007AUL)) {
1445     back = (dk3_c32_t)0x00000041UL + (back - (dk3_c32_t)0x00000061UL);
1446   }
1447   return back;
1448 }
1449 
1450 
1451 
1452 dkChar
dk3str_toupper(dkChar c)1453 dk3str_toupper(dkChar c)
1454 {
1455 #if DK3_CHAR_SIZE > 1
1456 #if DK3_CHAR_SIZE > 2
1457   return(dk3str_c32_toupper(c));
1458 #else
1459   return(dk3str_c16_toupper(c));
1460 #endif
1461 #else
1462   return(dk3str_c8_toupper(c));
1463 #endif
1464 }
1465 
1466 
1467 
1468 char *
dk3str_c8_start(char const * str,char const * whsp)1469 dk3str_c8_start(char const *str, char const *whsp)
1470 {
1471   char *back = NULL;	/* Function result. */
1472   char const *ptr;	/* Pointer to traverse str. */
1473   char const *wh;	/* Whitespaces set. */
1474 
1475   if(str) {
1476     wh = (whsp ? whsp : dk3str_c8_def_whsp);
1477     ptr = str;
1478     while((*ptr) && (!(back))) {
1479       if(dk3str_c8_chr(wh,*ptr)) {
1480 	ptr++;
1481       } else {
1482 	back = (char *)ptr;
1483       }
1484     }
1485   }
1486   return back;
1487 }
1488 
1489 
1490 
1491 dk3_c16_t *
dk3str_c16_start(dk3_c16_t const * str,dk3_c16_t const * whsp)1492 dk3str_c16_start(dk3_c16_t const *str, dk3_c16_t const *whsp)
1493 {
1494   dk3_c16_t *back = NULL;
1495   dk3_c16_t const *ptr;		/* Pointer into string. */
1496   dk3_c16_t const *wh;		/* Whitespaces set. */
1497 
1498   if(str) {
1499     wh = (whsp ? whsp : c16_def_whsp);
1500     ptr = str;
1501     while((*ptr) && (!(back))) {
1502       if(dk3str_c16_chr(wh, *ptr)) {
1503         ptr++;
1504       } else {
1505         back = (dk3_c16_t *)ptr;
1506       }
1507     }
1508   }
1509   return back;
1510 }
1511 
1512 
1513 
1514 dk3_c32_t *
dk3str_c32_start(dk3_c32_t const * str,dk3_c32_t const * whsp)1515 dk3str_c32_start(dk3_c32_t const *str, dk3_c32_t const *whsp)
1516 {
1517   dk3_c32_t *back = NULL;
1518   dk3_c32_t const *ptr = NULL;	/* Current character. */
1519   dk3_c32_t const *wh = NULL;	/* Whitespaces set. */
1520 
1521   if(str) {
1522     wh = (whsp ? whsp : c32_def_whsp);
1523     ptr = str;
1524     while((*ptr) && (!(back))) {
1525       if(dk3str_c32_chr(wh, *ptr)) {
1526         ptr++;
1527       } else {
1528         back = (dk3_c32_t *)ptr;
1529       }
1530     }
1531   }
1532   return back;
1533 }
1534 
1535 
1536 
1537 dkChar *
dk3str_start(dkChar const * str,dkChar const * whsp)1538 dk3str_start(dkChar const *str, dkChar const *whsp)
1539 {
1540 #if DK3_CHAR_SIZE > 1
1541 #if DK3_CHAR_SIZE > 2
1542   return(dk3str_c32_start(str, whsp));
1543 #else
1544   return(dk3str_c16_start(str, whsp));
1545 #endif
1546 #else
1547   return(dk3str_c8_start(str, whsp));
1548 #endif
1549 }
1550 
1551 
1552 
1553 char    *
dk3str_c8_next(char * str,char const * whsp)1554 dk3str_c8_next(char *str, char const *whsp)
1555 {
1556   char *back = NULL;		/* Function result. */
1557   char *ptr = NULL;		/* Pointer to traverse str. */
1558   char const *wh = NULL;	/* Whitespaces set to use. */
1559   int state = 0;		/* Current processing state. */
1560 
1561   if(str) {
1562     ptr = str;
1563     wh = (whsp ? whsp : dk3str_c8_def_whsp);
1564     state = 0;
1565     while((state < 2) && (*ptr)) {
1566       if(dk3str_c8_chr(wh, *ptr)) {
1567 	if(state == 1) {
1568 	  state = 2;
1569 	  *(ptr++) = '\0';
1570 	  back = dk3str_c8_start(ptr, wh);
1571 	} else {
1572 	  ptr++;
1573 	}
1574       } else {
1575 	state = 1;
1576 	ptr++;
1577       }
1578     }
1579   }
1580   return back;
1581 }
1582 
1583 
1584 
1585 dk3_c16_t *
dk3str_c16_next(dk3_c16_t * str,dk3_c16_t const * whsp)1586 dk3str_c16_next(dk3_c16_t *str, dk3_c16_t const *whsp)
1587 {
1588   dk3_c16_t *back = NULL;
1589   dk3_c16_t *ptr;		/* Pointer into string. */
1590   dk3_c16_t const *wh;		/* Whitespaces set. */
1591   int state;			/* Current state. */
1592 
1593   if(str) {
1594     ptr = str;
1595     wh = (whsp ? whsp : c16_def_whsp);
1596     state = 0;
1597     while((state < 2) && (*ptr)) {
1598       if(dk3str_c16_chr(wh, *ptr)) {
1599         if(state == 1) {
1600 	  state = 2;
1601 	  *(ptr++) = 0U;
1602 	  back = dk3str_c16_start(ptr, wh);
1603 	} else {
1604 	  ptr++;
1605 	}
1606       } else {
1607         state = 1; ptr++;
1608       }
1609     }
1610   }
1611   return back;
1612 }
1613 
1614 
1615 
1616 dk3_c32_t *
dk3str_c32_next(dk3_c32_t * str,dk3_c32_t const * whsp)1617 dk3str_c32_next(dk3_c32_t *str, dk3_c32_t const *whsp)
1618 {
1619   dk3_c32_t *back = NULL;
1620   dk3_c32_t *ptr = NULL;	/* Pointer into string. */
1621   dk3_c32_t const *wh = NULL;	/* Whitespaces. */
1622   int state = 0;		/* Current processing state. */
1623 
1624   if(str) {
1625     ptr = str;
1626     wh = (whsp ? whsp : c32_def_whsp);
1627     state = 0;
1628     while((state < 2) && (*ptr)) {
1629       if(dk3str_c32_chr(wh, *ptr)) {
1630         if(state == 1) {
1631 	  state = 2;
1632 	  *(ptr++) = 0UL;
1633 	  back = dk3str_c32_start(ptr, wh);
1634 	} else {
1635 	  ptr++;
1636 	}
1637       } else {
1638         state = 1; ptr++;
1639       }
1640     }
1641   }
1642   return back;
1643 }
1644 
1645 
1646 
1647 dkChar *
dk3str_next(dkChar * str,dkChar const * whsp)1648 dk3str_next(dkChar *str, dkChar const *whsp)
1649 {
1650 #if DK3_CHAR_SIZE > 1
1651 #if DK3_CHAR_SIZE > 2
1652   return(dk3str_c32_next(str, whsp));
1653 #else
1654   return(dk3str_c16_next(str, whsp));
1655 #endif
1656 #else
1657   return(dk3str_c8_next(str, whsp));
1658 #endif
1659 }
1660 
1661 
1662 
1663 void
dk3str_c8_chomp(char * str,char const * whsp)1664 dk3str_c8_chomp(char *str, char const *whsp)
1665 {
1666   char const *wh;	/* Whitespaces set to use. */
1667   char *ptr;		/* Pointer to traverse str. */
1668   char *x;		/* Start position of final space sequence. */
1669 
1670   if(str) {
1671     wh = (whsp ? whsp : dk3str_c8_def_whsp);
1672     x = NULL; ptr = str;
1673     while(*ptr) {
1674       if(dk3str_c8_chr(wh, *ptr)) {
1675 	if(!(x)) { x = ptr; }
1676       } else {
1677 	x = NULL;
1678       }
1679       ptr++;
1680     }
1681     if(x) { *x = '\0'; }
1682   }
1683 
1684 }
1685 
1686 
1687 
1688 void
dk3str_c16_chomp(dk3_c16_t * str,dk3_c16_t const * whsp)1689 dk3str_c16_chomp(dk3_c16_t *str, dk3_c16_t const *whsp)
1690 {
1691   dk3_c16_t const *wh;	/* Whitespaces set. */
1692   dk3_c16_t *ptr;	/* Pointer into string. */
1693   dk3_c16_t *x;		/* Test pointer for whitespaces set. */
1694 
1695   if(str) {
1696     wh = (whsp ? whsp : c16_def_whsp);
1697     x = NULL; ptr = str;
1698     while(*ptr) {
1699       if(dk3str_c16_chr(wh, *ptr)) {
1700         if(!(x)) x = ptr;
1701       } else {
1702         x = NULL;
1703       }
1704       ptr++;
1705     }
1706     if(x) { *x = 0U; }
1707   }
1708 }
1709 
1710 
1711 
1712 void
dk3str_c32_chomp(dk3_c32_t * str,dk3_c32_t const * whsp)1713 dk3str_c32_chomp(dk3_c32_t *str, dk3_c32_t const *whsp)
1714 {
1715   dk3_c32_t const *wh = NULL;	/* Whitespaces set. */
1716   dk3_c32_t *ptr = NULL;	/* Pointer into string. */
1717   dk3_c32_t *x = NULL;		/* For whitespace-set test. */
1718 
1719   if(str) {
1720     wh = (whsp ? whsp : c32_def_whsp);
1721     x = NULL; ptr = str;
1722     while(*ptr) {
1723       if(dk3str_c32_chr(wh, *ptr)) {
1724         if(!(x)) x = ptr;
1725       } else {
1726         x = NULL;
1727       }
1728       ptr++;
1729     }
1730     if(x) { *x = 0UL; }
1731   }
1732 }
1733 
1734 
1735 
1736 void
dk3str_chomp(dkChar * str,dkChar const * whsp)1737 dk3str_chomp(dkChar *str, dkChar const *whsp)
1738 {
1739 #if DK3_CHAR_SIZE > 1
1740 #if DK3_CHAR_SIZE > 2
1741   dk3str_c32_chomp(str, whsp);
1742 #else
1743   dk3str_c16_chomp(str, whsp);
1744 #endif
1745 #else
1746   dk3str_c8_chomp(str, whsp);
1747 #endif
1748 }
1749 
1750 
1751 
1752 void
dk3str_c8_delnl(char * str)1753 dk3str_c8_delnl(char *str)
1754 {
1755   char *ptr;
1756   if(str) {
1757     ptr = str;
1758     while(*ptr) {
1759       if(*ptr == 0x0D) {
1760         if(ptr[1] == 0x0A) {
1761 	  *ptr = '\0';
1762 	} else {
1763 	  ptr++;
1764 	}
1765       } else {
1766         if(*ptr == 0x0A) {
1767 	  *ptr = '\0';
1768 	} else {
1769 	  ptr++;
1770 	}
1771       }
1772     }
1773   }
1774 }
1775 
1776 
1777 
1778 void
dk3str_c16_delnl(dk3_c16_t * str)1779 dk3str_c16_delnl(dk3_c16_t *str)
1780 {
1781   dk3_c16_t *ptr;
1782   if(str) {
1783     ptr = str;
1784     while(*ptr) {
1785       if(*ptr == 0x000DU) {
1786         if(ptr[1] == 0x000AU) {
1787 	  *ptr = (dk3_c16_t)0U;
1788 	} else {
1789 	  ptr++;
1790 	}
1791       } else {
1792         if(*ptr == 0x000AU) {
1793 	  *ptr = (dk3_c16_t)0U;
1794 	} else {
1795 	  ptr++;
1796 	}
1797       }
1798     }
1799   }
1800 }
1801 
1802 
1803 
1804 void
dk3str_c32_delnl(dk3_c32_t * str)1805 dk3str_c32_delnl(dk3_c32_t *str)
1806 {
1807   dk3_c32_t	*ptr;
1808   if(str) {
1809     ptr = str;
1810     while(*ptr) {
1811       if(*ptr == 0x0000000DUL) {
1812         if(ptr[1] == 0x0000000AUL) {
1813 	  *ptr = (dk3_c32_t)0UL;
1814 	} else {
1815 	  ptr++;
1816 	}
1817       } else {
1818         if(*ptr == 0x0000000AUL) {
1819 	  *ptr = (dk3_c32_t)0UL;
1820 	} else {
1821 	  ptr++;
1822 	}
1823       }
1824     }
1825   }
1826 }
1827 
1828 
1829 
1830 void
dk3str_delnl(dkChar * str)1831 dk3str_delnl(dkChar *str)
1832 {
1833 #if DK3_CHAR_SIZE > 1
1834 #if DK3_CHAR_SIZE > 2
1835   dk3str_c32_delnl(str);
1836 #else
1837   dk3str_c16_delnl(str);
1838 #endif
1839 #else
1840   dk3str_c8_delnl(str);
1841 #endif
1842 }
1843 
1844 
1845 
1846 int
dk3str_c8_array_index(char const * const * a,char const * s,int c)1847 dk3str_c8_array_index(char const * const *a, char const *s, int c)
1848 {
1849   int back = -1;		/* Function result. */
1850   int ci;			/* Current array index for test. */
1851   char const * const *ap;	/* Pointer to traverse array a. */
1852   if((a) && (s)) {
1853     ap = a; ci = 0;
1854     while((*ap) && (back == -1)) {
1855       if(c) {
1856         if(dk3str_c8_cmp(*ap, s) == 0) back = ci;
1857       } else {
1858         if(dk3str_c8_casecmp(*ap, s) == 0) back = ci;
1859       }
1860       if(back == -1) { ap++; ci++; }
1861     }
1862   }
1863   return back;
1864 }
1865 
1866 
1867 
1868 int
dk3str_c16_array_index(dk3_c16_t const * const * a,dk3_c16_t const * s,int c)1869 dk3str_c16_array_index(dk3_c16_t const * const *a, dk3_c16_t const *s, int c)
1870 {
1871   int back = -1;
1872   int ci;			/* Current index. */
1873   dk3_c16_t const * const *ap;	/* Pointer into array. */
1874   if((a) && (s)) {
1875     ap = a; ci = 0;
1876     while((*ap) && (back == -1)) {
1877       if(c) {
1878         if(dk3str_c16_cmp(*ap, s) == 0) back = ci;
1879       } else {
1880         if(dk3str_c16_casecmp(*ap, s) == 0) back = ci;
1881       }
1882       if(back == -1) { ap++; ci++; }
1883     }
1884   }
1885   return back;
1886 }
1887 
1888 
1889 
1890 int
dk3str_c32_array_index(dk3_c32_t const * const * a,dk3_c32_t const * s,int c)1891 dk3str_c32_array_index(dk3_c32_t const * const *a, dk3_c32_t const *s, int c)
1892 {
1893   int back = -1;
1894   int ci;			/* Current index. */
1895   dk3_c32_t const * const *ap;	/* Pointer into array. */
1896 
1897   if((a) && (s)) {
1898     ap = a; ci = 0;
1899     while((*ap) && (back == -1)) {
1900       if(c) {
1901         if(dk3str_c32_cmp(*ap, s) == 0) back = ci;
1902       } else {
1903         if(dk3str_c32_casecmp(*ap, s) == 0) back = ci;
1904       }
1905       if(back == -1) { ap++; ci++; }
1906     }
1907   }
1908   return back;
1909 }
1910 
1911 
1912 
1913 int
dk3str_array_index(dkChar const * const * a,dkChar const * s,int c)1914 dk3str_array_index(dkChar const * const *a, dkChar const *s, int c)
1915 {
1916 #if DK3_CHAR_SIZE > 1
1917 #if DK3_CHAR_SIZE > 2
1918   return(dk3str_c32_array_index(a, s, c));
1919 #else
1920   return(dk3str_c16_array_index(a, s, c));
1921 #endif
1922 #else
1923   return(dk3str_c8_array_index(a, s, c));
1924 #endif
1925 }
1926 
1927 
1928 
1929 int
dk3str_c8_is_abbr(char const * line,char const * pattern,char spec,int cs)1930 dk3str_c8_is_abbr(char const *line,char const *pattern,char spec,int cs)
1931 {
1932   int back = 0;			/* Function result. */
1933   char cl;			/* Current character from line. */
1934   char cp;			/* Current character from pattern. */
1935   char const *lptr = NULL;	/* Pointer to traverse line. */
1936   char const *pptr = NULL;	/* Pointer to traverse pattern. */
1937   int afterspec = 0;		/* Flag: cs was already found in the pattern. */
1938   int cc = 0;			/* Flag: Can continue. */
1939 
1940   if((line) && (pattern)) {
1941     lptr = line; pptr = pattern; afterspec = 0; cc = 1;
1942     while(cc) {
1943       if(*pptr) {
1944         if((!afterspec) && (*pptr == spec)) {
1945 	  afterspec = 1; pptr++;
1946 	} else {
1947 	  if(*lptr) {
1948 	    cl = *lptr; cp = *pptr;
1949 	    if(!cs) {
1950 	      cl = dk3str_c8_toupper(cl);
1951 	      cp = dk3str_c8_toupper(cp);
1952 	    }
1953 	    if(cl == cp) {
1954 	      lptr++; pptr++;
1955 	    } else {
1956 	      cc = 0; back = 0;
1957 	    }
1958 	  } else {
1959 	    cc = 0;
1960 	    if(afterspec) back = 1;
1961 	  }
1962 	}
1963       } else {
1964         cc = 0;
1965 	if(!(*lptr)) {
1966 	  back = 1;
1967 	}
1968       }
1969     }
1970   }
1971 
1972   return back;
1973 }
1974 
1975 
1976 
1977 int
dk3str_c16_is_abbr(dk3_c16_t const * line,dk3_c16_t const * pattern,dk3_c16_t spec,int cs)1978 dk3str_c16_is_abbr(dk3_c16_t const *line, dk3_c16_t const *pattern, dk3_c16_t spec, int cs)
1979 {
1980   int back = 0;
1981   dk3_c16_t cl;			/* Current character from line. */
1982   dk3_c16_t cp;			/* Current character from pattern. */
1983   dk3_c16_t const *lptr;	/* Input text to check. */
1984   dk3_c16_t const *pptr;	/* Pattern. */
1985   int afterspec;		/* Flag: Abbreviation inidicator found. */
1986   int cc;			/* Flag: Can continue. */
1987 
1988   if((line) && (pattern)) {
1989     lptr = line; pptr = pattern; afterspec = 0; cc = 1;
1990     while(cc) {
1991       if(*pptr) {
1992         if((!afterspec) && (*pptr == spec)) {
1993 	  afterspec = 1; pptr++;
1994 	} else {
1995 	  if(*lptr) {
1996 	    cl = *lptr; cp = *pptr;
1997 	    if(!cs) {
1998 	      cl = dk3str_c16_toupper(cl);
1999 	      cp = dk3str_c16_toupper(cp);
2000 	    }
2001 	    if(cl == cp) {
2002 	      lptr++; pptr++;
2003 	    } else {
2004 	      cc = 0; back = 0;
2005 	    }
2006 	  } else {
2007 	    cc = 0;
2008 	    if(afterspec) back = 1;
2009 	  }
2010 	}
2011       } else {
2012         cc = 0;
2013 	if(!(*lptr)) {
2014 	  back = 1;
2015 	}
2016       }
2017     }
2018   }
2019   return back;
2020 }
2021 
2022 
2023 
2024 int
dk3str_c32_is_abbr(dk3_c32_t const * line,dk3_c32_t const * pattern,dk3_c32_t spec,int cs)2025 dk3str_c32_is_abbr(dk3_c32_t const *line, dk3_c32_t const *pattern, dk3_c32_t spec, int cs)
2026 {
2027   int back = 0;
2028   dk3_c32_t cl = 0UL;		/* Text character. */
2029   dk3_c32_t cp = 0UL;		/* Pattern character. */
2030   dk3_c32_t const *lptr = NULL;	/* Pointer into text. */
2031   dk3_c32_t const *pptr = NULL;	/* Pointer into pattern. */
2032   int afterspec = 0;		/* Flag: Abbreviation indicator was found. */
2033   int cc = 0;			/* Flag: Can continue. */
2034 
2035   if((line) && (pattern)) {
2036     lptr = line; pptr = pattern; afterspec = 0; cc = 1;
2037     while(cc) {
2038       if(*pptr) {
2039         if((!afterspec) && (*pptr == spec)) {
2040 	  afterspec = 1; pptr++;
2041 	} else {
2042 	  if(*lptr) {
2043 	    cl = *lptr; cp = *pptr;
2044 	    if(!cs) {
2045 	      cl = dk3str_c32_toupper(cl);
2046 	      cp = dk3str_c32_toupper(cp);
2047 	    }
2048 	    if(cl == cp) {
2049 	      lptr++; pptr++;
2050 	    } else {
2051 	      cc = 0; back = 0;
2052 	    }
2053 	  } else {
2054 	    cc = 0;
2055 	    if(afterspec) back = 1;
2056 	  }
2057 	}
2058       } else {
2059         cc = 0;
2060 	if(!(*lptr)) { back = 1; }
2061       }
2062     }
2063   }
2064   return back;
2065 }
2066 
2067 
2068 
2069 int
dk3str_is_abbr(dkChar const * line,dkChar const * pattern,dkChar spec,int cs)2070 dk3str_is_abbr(dkChar const *line, dkChar const *pattern, dkChar spec, int cs)
2071 {
2072 #if DK3_CHAR_SIZE > 1
2073 #if DK3_CHAR_SIZE > 2
2074   return(dk3str_c32_is_abbr(line, pattern, spec, cs));
2075 #else
2076   return(dk3str_c16_is_abbr(line, pattern, spec, cs));
2077 #endif
2078 #else
2079   return(dk3str_c8_is_abbr(line, pattern, spec, cs));
2080 #endif
2081 }
2082 
2083 
2084 
2085 int
dk3str_c8_array_abbr(char const * const * ar,char const * str,char sp,int cs)2086 dk3str_c8_array_abbr(char const * const *ar, char const *str, char sp, int cs)
2087 {
2088   int back = -1;		/* Function result. */
2089   char const * const *ptr;	/* Pointer to traverse array ar. */
2090   int i;			/* Current index of ptr in ar. */
2091 
2092   if((ar) && (str)) {
2093     i = 0; ptr = ar;
2094     while((*ptr) && (back == -1)) {
2095 
2096       if(dk3str_c8_is_abbr(str, *ptr, sp, cs)) {
2097         back = i;
2098       }
2099       if(back == -1) {
2100 	ptr++; i++;
2101       }
2102 
2103     }
2104   }
2105   return back;
2106 }
2107 
2108 
2109 
2110 int
dk3str_c16_array_abbr(dk3_c16_t const * const * arr,dk3_c16_t const * str,dk3_c16_t sp,int cs)2111 dk3str_c16_array_abbr(dk3_c16_t const * const *arr, dk3_c16_t const *str, dk3_c16_t sp, int cs)
2112 {
2113   int back = -1;
2114   dk3_c16_t const * const *ptr;	/* Pointer into array. */
2115   int i;			/* Current index. */
2116 
2117   if((arr) && (str)) {
2118     i = 0; ptr = arr;
2119     while((*ptr) && (back == -1)) {
2120       if(dk3str_c16_is_abbr(str, *ptr, sp, cs)) {
2121         back = i;
2122       } else {
2123       }
2124       if(back == -1) {
2125         ptr++; i++;
2126       }
2127     }
2128   }
2129   return back;
2130 }
2131 
2132 
2133 
2134 int
dk3str_c32_array_abbr(dk3_c32_t const * const * arr,dk3_c32_t const * str,dk3_c32_t sp,int cs)2135 dk3str_c32_array_abbr(dk3_c32_t const * const *arr, dk3_c32_t const *str, dk3_c32_t sp, int cs)
2136 {
2137   int back = -1;
2138   dk3_c32_t const * const *ptr = NULL;	/* Pointer into array. */
2139   int i = 0;				/* Current index. */
2140 
2141   if((arr) && (str)) {
2142     i = 0; ptr = arr;
2143     while((*ptr) && (back == -1)) {
2144       if(dk3str_c32_is_abbr(str, *ptr, sp, cs)) {
2145         back = i;
2146       }
2147       if(back == -1) {
2148         ptr++; i++;
2149       }
2150     }
2151   }
2152   return back;
2153 }
2154 
2155 
2156 
2157 int
dk3str_array_abbr(dkChar const * const * ar,dkChar const * str,dkChar sp,int cs)2158 dk3str_array_abbr(dkChar const * const *ar,dkChar const *str,dkChar sp,int cs)
2159 {
2160 #if DK3_CHAR_SIZE > 1
2161 #if DK3_CHAR_SIZE > 2
2162   return(dk3str_c32_array_abbr(ar, str, sp, cs));
2163 #else
2164   return(dk3str_c16_array_abbr(ar, str, sp, cs));
2165 #endif
2166 #else
2167   return(dk3str_c8_array_abbr(ar, str, sp, cs));
2168 #endif
2169 }
2170 
2171 
2172 
2173 int
dk3str_c8_is_bool(char const * str)2174 dk3str_c8_is_bool(char const *str)
2175 {
2176   int back = 0;	/* Function result. */
2177 
2178   if(str) {
2179     if(dk3str_c8_array_abbr(dk3str_c8_bool_kw,str,'$',0) >= 0) {
2180       back = 1;
2181     }
2182   }
2183   return back;
2184 }
2185 
2186 
2187 
2188 int
dk3str_c16_is_bool(dk3_c16_t const * str)2189 dk3str_c16_is_bool(dk3_c16_t const *str)
2190 {
2191   int back = 0;
2192   char	mytest[256];	/* 8-bit version of the str text. */
2193   if(str) {
2194 #if VERSION_BEFORE_20130928
2195     if(dk3str_c16_to_c8_simple(mytest, sizeof(mytest), str)) {
2196       back = dk3str_c8_is_bool(mytest);
2197     }
2198 #else
2199     if(dk3str_cnv_c16_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
2200       back = dk3str_c8_is_bool(mytest);
2201     }
2202 #endif
2203   }
2204   return back;
2205 }
2206 
2207 
2208 
2209 int
dk3str_c32_is_bool(dk3_c32_t const * str)2210 dk3str_c32_is_bool(dk3_c32_t const *str)
2211 {
2212   int back = 0;
2213   char mytest[256];	/* 8-bit text copy of str. */
2214   if(str) {
2215 #if VERSION_BEFORE_20130928
2216     if(dk3str_c32_to_c8_simple(mytest, sizeof(mytest), str)) {
2217       back = dk3str_c8_is_bool(mytest);
2218     }
2219 #else
2220     if(dk3str_cnv_c32_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
2221       back = dk3str_c8_is_bool(mytest);
2222     }
2223 #endif
2224   }
2225   return back;
2226 }
2227 
2228 
2229 
2230 int
dk3str_is_bool(dkChar const * str)2231 dk3str_is_bool(dkChar const *str)
2232 {
2233 #if DK3_CHAR_SIZE > 1
2234 #if DK3_CHAR_SIZE > 2
2235   return(dk3str_c32_is_bool(str));
2236 #else
2237   return(dk3str_c16_is_bool(str));
2238 #endif
2239 #else
2240   return(dk3str_c8_is_bool(str));
2241 #endif
2242 }
2243 
2244 
2245 
2246 int
dk3str_c8_is_on(char const * str)2247 dk3str_c8_is_on(char const *str)
2248 {
2249   int back = 0;	/* Function result. */
2250 
2251   if(str) {
2252     if(dk3str_c8_array_abbr(dk3str_c8_bool_kw,str,'$',0) >= INDEX_OF_FIRST_BOOLEAN_TRUE) {
2253       back = 1;
2254     }
2255   }
2256   return back;
2257 }
2258 
2259 
2260 
2261 int
dk3str_c16_is_on(dk3_c16_t const * str)2262 dk3str_c16_is_on(dk3_c16_t const *str)
2263 {
2264   int back = 0;
2265   char	mytest[256];	/* 8-bit version of the str text. */
2266   if(str) {
2267 #if VERSION_BEFORE_20130928
2268     if(dk3str_c16_to_c8_simple(mytest, sizeof(mytest), str)) {
2269       back = dk3str_c8_is_on(mytest);
2270     }
2271 #else
2272     if(dk3str_cnv_c16_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
2273       back = dk3str_c8_is_on(mytest);
2274     }
2275 #endif
2276   }
2277   return back;
2278 }
2279 
2280 
2281 
2282 int
dk3str_c32_is_on(dk3_c32_t const * str)2283 dk3str_c32_is_on(dk3_c32_t const *str)
2284 {
2285   int back = 0;
2286   char mytest[256];	/* 8-bit copy of str text. */
2287   if(str) {
2288 #if VERSION_BEFORE_20130928
2289     if(dk3str_c32_to_c8_simple(mytest, sizeof(mytest), str)) {
2290       back = dk3str_c8_is_on(mytest);
2291     }
2292 #else
2293     if(dk3str_cnv_c32_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
2294       back = dk3str_c8_is_on(mytest);
2295     }
2296 #endif
2297   }
2298   return back;
2299 }
2300 
2301 
2302 
2303 int
dk3str_is_on(dkChar const * str)2304 dk3str_is_on(dkChar const *str)
2305 {
2306 #if DK3_CHAR_SIZE > 1
2307 #if DK3_CHAR_SIZE > 2
2308   return(dk3str_c32_is_on(str));
2309 #else
2310   return(dk3str_c16_is_on(str));
2311 #endif
2312 #else
2313   return(dk3str_c8_is_on(str));
2314 #endif
2315 }
2316 
2317 
2318 
2319 size_t
dk3str_c8_explode(char ** array,size_t sz,char * str,char const * whsp)2320 dk3str_c8_explode(char **array, size_t sz, char *str, char const *whsp)
2321 {
2322   size_t	back = 0;	/* Function result. */
2323   char const	*wh = NULL;	/* White spaces set to use. */
2324   char		*current = NULL; /* Current text word to process. */
2325   char		*next = NULL;	/* Remaining text after processing the word. */
2326   char		**ptr = NULL;	/* Pointer to current array element. */
2327   size_t 	i = 0;		/* Number of remaining usable array elements. */
2328   if((array) && (sz > 1) && (str)) {
2329     wh = (whsp ? whsp : dk3str_c8_def_whsp);
2330     ptr = array; i = sz;
2331     while(i--) { *(ptr++) = NULL; }
2332     ptr = array; i = 0;
2333     current = dk3str_c8_start(str, wh);
2334     while((current) && (i < (sz - 1))) {
2335       next = dk3str_c8_next(current,wh);
2336       *(ptr++) = current; i++; back++;
2337       current = next;
2338     }
2339   }
2340   return back;
2341 }
2342 
2343 
2344 
2345 size_t
dk3str_c16_explode(dk3_c16_t ** array,size_t sz,dk3_c16_t * str,dk3_c16_t const * whsp)2346 dk3str_c16_explode(dk3_c16_t **array, size_t sz, dk3_c16_t *str, dk3_c16_t const *whsp)
2347 {
2348   size_t		back = 0;
2349   dk3_c16_t const	*wh = NULL;	/* Whitespaces set. */
2350   dk3_c16_t		*current = NULL;	/* Start of current word. */
2351   dk3_c16_t		*next = NULL;	/* Start of next word after current. */
2352   dk3_c16_t		**ptr = NULL;	/* Pointer into array. */
2353   size_t		i = 0;		/* Number of words found. */
2354 
2355   if((array) && (sz > 1) && (str)) {
2356     wh = (whsp ? whsp : c16_def_whsp);
2357     ptr = array; i = sz;
2358     while(i--) { *(ptr++) = NULL; }
2359     ptr = array; i = 0;
2360     current = dk3str_c16_start(str, wh);
2361     while((current) && (i < (sz - 1))) {
2362       next = dk3str_c16_next(current, wh);
2363       *(ptr++) = current; i++; back++;
2364       current = next;
2365     }
2366   }
2367   return back;
2368 }
2369 
2370 
2371 
2372 size_t
dk3str_c32_explode(dk3_c32_t ** array,size_t sz,dk3_c32_t * str,dk3_c32_t const * whsp)2373 dk3str_c32_explode(dk3_c32_t **array, size_t sz, dk3_c32_t *str, dk3_c32_t const *whsp)
2374 {
2375   size_t		back = 0;
2376   dk3_c32_t const	*wh = NULL;	/* Whitespace set. */
2377   dk3_c32_t		*current = NULL;	/* Current word. */
2378   dk3_c32_t		*next = NULL;	/* Next word. */
2379   dk3_c32_t		**ptr = NULL;	/* Pointer into destination array. */
2380   size_t		i = 0;		/* Current index. */
2381   if((array) && (sz > 1) && (str)) {
2382     wh = (whsp ? whsp : c32_def_whsp);
2383     ptr = array; i = sz;
2384     while(i--) { *(ptr++) = NULL; }
2385     ptr = array; i = 0;
2386     current = dk3str_c32_start(str, wh);
2387     while((current) && (i < (sz - 1))) {
2388       next = dk3str_c32_next(current, wh);
2389       *(ptr++) = current; i++; back++;
2390       current = next;
2391     }
2392   }
2393   return back;
2394 }
2395 
2396 
2397 
2398 size_t
dk3str_explode(dkChar ** array,size_t sz,dkChar * str,dkChar const * whsp)2399 dk3str_explode(dkChar **array, size_t sz, dkChar *str, dkChar const *whsp)
2400 {
2401 #if DK3_CHAR_SIZE > 1
2402 #if DK3_CHAR_SIZE > 2
2403   return(dk3str_c32_explode(array, sz, str, whsp));
2404 #else
2405   return(dk3str_c16_explode(array, sz, str, whsp));
2406 #endif
2407 #else
2408   return(dk3str_c8_explode(array, sz, str, whsp));
2409 #endif
2410 }
2411 
2412 
2413 
2414 void
dk3str_c8_normalize(char * l,char const * w,char s)2415 dk3str_c8_normalize(char *l, char const *w, char s)
2416 {
2417   char		*parts[256];	/* All the text words. */
2418   char		*dp = NULL;	/* Destination pointer. */
2419   char		*sp = NULL;	/* Source pointer. */
2420   size_t	np = 0;		/* Number of parts used. */
2421   size_t	i = 0;		/* Current word to process. */
2422   if(l) {
2423     np = dk3str_c8_explode(parts, 255, l, w);
2424     if(np > 0) {
2425       dp = l;
2426       for(i = 0; i < np; i++) {
2427         sp = parts[i];
2428 	if(i) { *(dp++) = s; }
2429 	while(*sp) { *(dp++) = *(sp++); }
2430       }
2431       *dp = '\0';
2432     }
2433   }
2434 }
2435 
2436 
2437 
2438 void
dk3str_c16_normalize(dk3_c16_t * l,dk3_c16_t const * w,dk3_c16_t s)2439 dk3str_c16_normalize(dk3_c16_t *l, dk3_c16_t const *w, dk3_c16_t s)
2440 {
2441   dk3_c16_t		*parts[256];	/* Pointers to the words. */
2442   dk3_c16_t		*dp = NULL;	/* Destination pointer. */
2443   dk3_c16_t		*sp = NULL;	/* Source pointer. */
2444   size_t		np = 0;		/* Number of parts. */
2445   size_t		i = 0;		/* Index of current part. */
2446 
2447   if(l) {
2448     np = dk3str_c16_explode(parts, 255, l, w);
2449     if(np > 0) {
2450       dp = l;
2451       for(i = 0; i < np; i++) {
2452         sp = parts[i];
2453 	if(i) { *(dp++) = s; }
2454 	while(*sp) { *(sp++) = *(dp++); }
2455       }
2456       *dp = 0U;
2457     }
2458   }
2459 }
2460 
2461 
2462 
2463 void
dk3str_c32_normalize(dk3_c32_t * l,dk3_c32_t const * w,dk3_c32_t s)2464 dk3str_c32_normalize(dk3_c32_t *l, dk3_c32_t const *w, dk3_c32_t s)
2465 {
2466   dk3_c32_t	*parts[256];	/* Words. */
2467   dk3_c32_t	*dp = NULL;	/* Destination pointer. */
2468   dk3_c32_t	*sp = NULL;	/* Source pointer. */
2469   size_t	np = 0;	/* Number of words. */
2470   size_t	i = 0;		/* Index of current word. */
2471   if(l) {
2472     np = dk3str_c32_explode(parts, 255, l, w);
2473     if(np > 0) {
2474       dp = l;
2475       for(i = 0; i < np; i++) {
2476         sp = parts[i];
2477 	if(i) { *(dp++) = s; }
2478 	while(*sp) { *(dp++) = *(sp++); }
2479       }
2480       *dp = 0UL;
2481     }
2482   }
2483 }
2484 
2485 
2486 
2487 void
dk3str_normalize(dkChar * l,dkChar const * w,dkChar s)2488 dk3str_normalize(dkChar *l, dkChar const *w, dkChar s)
2489 {
2490 #if DK3_CHAR_SIZE > 1
2491 #if DK3_CHAR_SIZE > 2
2492   dk3str_c32_normalize(l, w, s);
2493 #else
2494   dk3str_c16_normalize(l, w, s);
2495 #endif
2496 #else
2497   dk3str_c8_normalize(l, w, s);
2498 #endif
2499 }
2500 
2501 
2502 
2503 void
dk3str_c8_correct_filename(char * n)2504 dk3str_c8_correct_filename(char *n)
2505 {
2506   register char *p;
2507   p = n;
2508   while(*p) { if(*p == NO_FNS_C8) { *p = FNS_C8; } p++; }
2509 }
2510 
2511 
2512 
2513 void
dk3str_c16_correct_filename(dk3_c16_t * n)2514 dk3str_c16_correct_filename(dk3_c16_t *n)
2515 {
2516   register dk3_c16_t *p;
2517   p = n;
2518   while(*p) { if(*p == NO_FNS_C16) { *p = FNS_C16; } p++;}
2519 }
2520 
2521 
2522 
2523 void
dk3str_c32_correct_filename(dk3_c32_t * n)2524 dk3str_c32_correct_filename(dk3_c32_t *n)
2525 {
2526   register dk3_c32_t *p;	/* Pointer into text. */
2527   p = n;
2528   while(*p) { if(*p == NO_FNS_C32) { *p = FNS_C32; } p++;}
2529 }
2530 
2531 
2532 
2533 void
dk3str_correct_filename(dkChar * n)2534 dk3str_correct_filename(dkChar *n)
2535 {
2536 #if DK3_CHAR_SIZE > 1
2537 #if DK3_CHAR_SIZE > 2
2538   dk3str_c32_correct_filename(n);
2539 #else
2540   dk3str_c16_correct_filename(n);
2541 #endif
2542 #else
2543   dk3str_c8_correct_filename(n);
2544 #endif
2545 }
2546 
2547 
2548 
2549 int
dk3str_c8_is_abs_path(char const * n)2550 dk3str_c8_is_abs_path(char const *n)
2551 {
2552   int back = 0;
2553   if(n) {
2554     if(*n == FNS_C8) {
2555       back = 1;
2556     } else {
2557 #if DK3_ON_WINDOWS
2558       if(((*n >= 'A') && (*n <= 'Z')) || ((*n >= 'a') && (*n <= 'z'))) {
2559         if(n[1] == ':') {
2560 	  if(n[2] == FNS_C8) {
2561 	    back = 1;
2562 	  }
2563 	}
2564       }
2565 #endif
2566     }
2567   }
2568   return back;
2569 }
2570 
2571 
2572 
2573 int
dk3str_c16_is_abs_path(dk3_c16_t const * n)2574 dk3str_c16_is_abs_path(dk3_c16_t const *n)
2575 {
2576   int back = 0;
2577   if(n) {
2578     if(*n == FNS_C16) {
2579       back = 1;
2580     } else {
2581 #if DK3_ON_WINDOWS
2582       if(((*n >= 0x0061U) && (*n <= 0x007AU))
2583          || ((*n >= 0x0041U) && (*n <= 0x005AU)))
2584       {
2585         if(n[1] == 0x003AU) {
2586 	  if(n[2] == FNS_C16) {
2587 	    back = 1;
2588 	  }
2589 	}
2590       }
2591 #endif
2592     }
2593   }
2594   return back;
2595 }
2596 
2597 
2598 
2599 int
dk3str_c32_is_abs_path(dk3_c32_t const * n)2600 dk3str_c32_is_abs_path(dk3_c32_t const *n)
2601 {
2602   int back = 0;
2603 
2604   if(n) {
2605     if(*n == FNS_C32) {
2606       back = 1;
2607     } else {
2608 #if DK3_ON_WINDOWS
2609       if(((*n >= 0x00000061UL) && (*n <= 0x0000007AUL))
2610         || ((*n >= 0x00000041UL) && (*n <= 0x0000005AUL)))
2611       {
2612         if(n[1] == 0x0000003AUL) {
2613 	  if(n[2] == FNS_C32) {
2614 	    back = 1;
2615 	  }
2616 	}
2617       }
2618 #endif
2619     }
2620   }
2621   return back;
2622 }
2623 
2624 
2625 
2626 int
dk3str_is_abs_path(dkChar const * n)2627 dk3str_is_abs_path(dkChar const *n)
2628 {
2629 #if DK3_CHAR_SIZE > 1
2630 #if DK3_CHAR_SIZE > 2
2631   return(dk3str_c32_is_abs_path(n));
2632 #else
2633   return(dk3str_c16_is_abs_path(n));
2634 #endif
2635 #else
2636   return(dk3str_c8_is_abs_path(n));
2637 #endif
2638 }
2639 
2640 
2641 
2642 int
dk3str_c8_append_path_app(char * d,size_t sz,char const * n,dk3_app_t * app)2643 dk3str_c8_append_path_app(char *d, size_t sz, char const *n, dk3_app_t *app)
2644 {
2645   int		 back = 0;		/* Function result. */
2646   char		 myn[DK3_MAX_PATH];	/* My editable copy of n. */
2647   char 		*p1 = NULL;		/* Current name part. */
2648   char 		*p2 = NULL;		/* Remaining text. */
2649   char		*p3 = NULL;		/* Used to delete one part from path. */
2650   size_t	 tsz;			/* Size for tests. */
2651   if((d) && (sz) && (n)) {
2652     if(dk3str_c8_is_abs_path(n)) {	/* Absolute path, copy. */
2653       if(dk3str_c8_len(n) < sz) {
2654         dk3str_c8_cpy(d,n);
2655 	back = 1;
2656       } else {
2657         if(app) {
2658 	  /* ERROR: Name n too long! */
2659 	  dk3app_log_i1(app, DK3_LL_ERROR, 109);
2660 	}
2661       }
2662     } else {				/* Relative path, append. */
2663       if(dk3str_c8_len(n) < sizeof(myn)) {
2664         back = 1;
2665         dk3str_c8_cpy(myn,n);
2666 	p1 = myn;
2667 	while((p1) && (back)) {
2668 	  p2 = dk3str_c8_chr(p1,FNS_C8);
2669 	  if(p2) { *(p2++) = '\0'; }
2670 	  if(dk3str_c8_cmp(dk3str_c8_dot,p1)) {
2671 	    if(dk3str_c8_cmp(dk3str_c8_dot_dot,p1)) {	/* Add another part. */
2672 	      tsz =	dk3str_c8_len(d) + dk3str_c8_len(dk3str_c8_fnsep)
2673 	      		+ dk3str_c8_len(p1);
2674 	      if(tsz < sz) {
2675 	        dk3str_c8_cat(d,dk3str_c8_fnsep);
2676 		dk3str_c8_cat(d,p1);
2677 	      } else {
2678 	        if(app) {
2679 		  /* ERROR: Result too long for destination buffer! */
2680 		  dk3app_log_i1(app, DK3_LL_ERROR, 38);
2681 		}
2682 	      }
2683 	    } else {			/* Remove last part. */
2684 	      p3 = dk3str_c8_rchr(d,FNS_C8);
2685 	      if(p3) {
2686 	        *p3 = '\0';
2687 	      } else {
2688 	        if(app) {
2689 		  /* ERROR: Too many ".." entries! */
2690 #if DK3_CHAR_SIZE == 1
2691 		  dk3app_log_i3(app, DK3_LL_ERROR, 110, 111, n);
2692 #else
2693 		  dk3app_log_i1(app, DK3_LL_ERROR, 126);
2694 #endif
2695 		}
2696 	      }
2697 	    }
2698 	  }
2699 	  p1 = p2;
2700 	}
2701       } else {
2702         if(app) {
2703 	  /* ERROR: Name n too long! */
2704 	  dk3app_log_i1(app, DK3_LL_ERROR, 109);
2705 	}
2706       }
2707     }
2708   }
2709   return back;
2710 }
2711 
2712 
2713 
2714 int
dk3str_c16_append_path_app(dk3_c16_t * d,size_t sz,dk3_c16_t const * n,dk3_app_t * app)2715 dk3str_c16_append_path_app(dk3_c16_t *d, size_t sz, dk3_c16_t const *n, dk3_app_t *app)
2716 {
2717   int back = 0;
2718   dk3_c16_t	myn[DK3_MAX_PATH];
2719   dk3_c16_t	*p1 = NULL;		/* Path component to process. */
2720   dk3_c16_t	*p2 = NULL;		/* Remainder of path. */
2721   dk3_c16_t	*p3 = NULL;		/* Last path component to remove. */
2722   size_t	 tsz;			/* Test size. */
2723 
2724   if((d) && (sz) && (n)) {
2725     if(dk3str_c16_is_abs_path(n)) {
2726       if(dk3str_c16_len(n) < sz) {
2727         dk3str_c16_cpy(d,n) ;
2728 	back = 1;
2729       } else {
2730         if(app) {
2731 	  /* ERROR: Name n too long! */
2732 	  dk3app_log_i1(app, DK3_LL_ERROR, 109);
2733 	}
2734       }
2735     } else {
2736       if(dk3str_c16_len(n) < DK3_SIZEOF(myn,dk3_c16_t)) {
2737         back = 1;
2738 	dk3str_c16_cpy(myn,n) ;
2739 	p1 = myn;
2740 	while((p1) && (back)) {
2741 	  p2 = dk3str_c16_chr(p1, FNS_C16);
2742 	  if(p2) { *(p2++) = 0U; }
2743 	  if(dk3str_c16_cmp(c16_dot,p1)) {
2744 	    if(dk3str_c16_cmp(c16_dot_dot,p1)) {
2745 	      tsz =	dk3str_c16_len(d) + dk3str_c16_len(c16_fnsep)
2746 	      		+ dk3str_c16_len(p1);
2747 	      if(tsz < sz) {
2748 	        dk3str_c16_cat(d,c16_fnsep);
2749 		dk3str_c16_cat(d,p1);
2750 	      } else {
2751 	        if(app) {
2752 		  /* ERROR: Result too long for destination buffer! */
2753 		  dk3app_log_i1(app, DK3_LL_ERROR, 38);
2754 		}
2755 	      }
2756 	    } else {
2757 	      p3 = dk3str_c16_rchr(d,FNS_C16);
2758 	      if(p3) {
2759 	        *p3 = 0U;
2760 	      } else {
2761 	        if(app) {
2762 		  /* ERROR: Too many ".." entries! */
2763 #if DK3_CHAR_SIZE == 2
2764 		  dk3app_log_i3(app, DK3_LL_ERROR, 110, 111, n);
2765 #else
2766 		  dk3app_log_i1(app, DK3_LL_ERROR, 126);
2767 #endif
2768 		}
2769 	      }
2770 	    }
2771 	  }
2772 	  p1 = p2;
2773 	}
2774       } else {
2775         if(app) {
2776 	  /* ERROR: Name n too long! */
2777 	  dk3app_log_i1(app, DK3_LL_ERROR, 109);
2778 	}
2779       }
2780     }
2781   }
2782   return back;
2783 }
2784 
2785 
2786 
2787 int
dk3str_c32_append_path_app(dk3_c32_t * d,size_t sz,dk3_c32_t const * n,dk3_app_t * app)2788 dk3str_c32_append_path_app(dk3_c32_t *d, size_t sz, dk3_c32_t const *n, dk3_app_t *app)
2789 {
2790   int back = 0;
2791   dk3_c32_t	myn[DK3_MAX_PATH];	/* My editable copy of n. */
2792   dk3_c32_t	*p1 = NULL;		/* Current name part. */
2793   dk3_c32_t	*p2 = NULL;		/* Remaining text. */
2794   dk3_c32_t	*p3 = NULL;		/* Used to delete one part from path. */
2795   size_t	 tsz;			/* Test size. */
2796 
2797 
2798   if((d) && (sz) && (n)) {
2799     if(dk3str_c32_is_abs_path(n)) {
2800       if(dk3str_c32_len(n) < sz) {
2801         dk3str_c32_cpy(d,n) ;
2802 	back = 1;
2803       } else {
2804         if(app) {
2805 	  /* ERROR: Name n too long! */
2806 	  dk3app_log_i1(app, DK3_LL_ERROR, 109);
2807 	}
2808       }
2809     } else {
2810       if(dk3str_c32_len(n) < DK3_SIZEOF(myn,dk3_c32_t)) {
2811         back = 1;
2812 	dk3str_c32_cpy(myn,n) ;
2813 	p1 = myn;
2814 	while((p1) && (back)) {
2815 	  p2 = dk3str_c32_chr(p1,FNS_C32);
2816 	  if(p2) { *(p2++) = 0UL; }
2817 	  if(dk3str_c32_cmp(c32_dot,p1)) {
2818 	    if(dk3str_c32_cmp(c32_dot_dot,p1)) {
2819 	      tsz =	dk3str_c32_len(d) + dk3str_c32_len(c32_fnsep)
2820 	      		+ dk3str_c32_len(p1);
2821 	      if(tsz < sz) {
2822 	        dk3str_c32_cat(d,c32_fnsep);
2823 		dk3str_c32_cat(d,p1);
2824 	      } else {
2825 	        if(app) {
2826 		  /* ERROR: Result too long for destination buffer! */
2827 		  dk3app_log_i1(app, DK3_LL_ERROR, 38);
2828 		}
2829 	      }
2830 	    } else {
2831 	      p3 = dk3str_c32_rchr(d,FNS_C32);
2832 	      if(p3) {
2833 	        *p3 = 0UL;
2834 	      } else {
2835 	        if(app) {
2836 		  /* ERROR: Too many ".." entries! */
2837 		  dk3app_log_i1(app, DK3_LL_ERROR, 110);
2838 		}
2839 	      }
2840 	    }
2841 	  }
2842 	  p1 = p2;
2843 	}
2844       } else {
2845         if(app) {
2846 	  /* ERROR: Name n too long! */
2847 	  dk3app_log_i1(app, DK3_LL_ERROR, 109);
2848 	}
2849       }
2850     }
2851   }
2852   if(back) {
2853   }
2854   return back;
2855 }
2856 
2857 
2858 
2859 int
dk3str_append_path_app(dkChar * d,size_t sz,dkChar const * n,dk3_app_t * app)2860 dk3str_append_path_app(dkChar *d, size_t sz, dkChar const *n, dk3_app_t *app)
2861 {
2862 #if DK3_CHAR_SIZE > 1
2863 #if DK3_CHAR_SIZE > 2
2864   return(dk3str_c32_append_path_app(d, sz, n, app));
2865 #else
2866   return(dk3str_c16_append_path_app(d, sz, n, app));
2867 #endif
2868 #else
2869   return(dk3str_c8_append_path_app(d, sz, n, app));
2870 #endif
2871 }
2872 
2873 
2874 
2875 char *
dk3str_c8_get_suffix(char const * s)2876 dk3str_c8_get_suffix(char const *s)
2877 {
2878   char *back = NULL;
2879   char const *ptr;
2880   if(s) {
2881     ptr = s;
2882     while(*ptr) {
2883       if(*ptr == '.') {
2884         back = (char *)ptr;
2885       } else {
2886 	if(*ptr == FNS_C8) {
2887 	  back = NULL;
2888 	}
2889       }
2890       ptr++;
2891     }
2892   }
2893   return back;
2894 }
2895 
2896 
2897 
2898 dk3_c16_t *
dk3str_c16_get_suffix(dk3_c16_t const * s)2899 dk3str_c16_get_suffix(dk3_c16_t const *s)
2900 {
2901   dk3_c16_t *back = NULL;
2902   dk3_c16_t const *ptr;
2903 
2904   if(s) {
2905     ptr = s;
2906     while(*ptr) {
2907       if(*ptr == 0x002EU) {
2908         back = (dk3_c16_t *)ptr;
2909       } else {
2910         if(*ptr == FNS_C16) {
2911 	  back = NULL;
2912 	}
2913       }
2914       ptr++;
2915     }
2916   }
2917   return back;
2918 }
2919 
2920 
2921 
2922 dk3_c32_t *
dk3str_c32_get_suffix(dk3_c32_t const * s)2923 dk3str_c32_get_suffix(dk3_c32_t const *s)
2924 {
2925   dk3_c32_t *back = NULL;
2926   dk3_c32_t const *ptr;
2927   if(s) {
2928     ptr = s;
2929     while(*ptr) {
2930       if(*ptr == 0x0000002EUL) {
2931         back = (dk3_c32_t *)ptr;
2932       } else {
2933         if(*ptr == FNS_C32) {
2934 	  back = NULL;
2935 	}
2936       }
2937       ptr++;
2938     }
2939   }
2940   return back;
2941 }
2942 
2943 
2944 
2945 dkChar *
dk3str_get_suffix(dkChar const * s)2946 dk3str_get_suffix(dkChar const *s)
2947 {
2948 #if DK3_CHAR_SIZE > 1
2949 #if DK3_CHAR_SIZE > 2
2950   return(dk3str_c32_get_suffix(s));
2951 #else
2952   return(dk3str_c16_get_suffix(s));
2953 #endif
2954 #else
2955   return(dk3str_c8_get_suffix(s));
2956 #endif
2957 }
2958 
2959 
2960 
2961 int
dk3str_c32_to_c8_simple_app(char * d,size_t sz,dk3_c32_t const * s,dk3_app_t * app)2962 dk3str_c32_to_c8_simple_app(char *d, size_t sz, dk3_c32_t const *s, dk3_app_t *app)
2963 {
2964   int back = 0;
2965   dk3_c32_t const *ptr = NULL;	/* Pointer into source string. */
2966   dk3_c32_t c = 0UL;		/* Source character. */
2967   unsigned char uc = 0x00;	/* Destination character. */
2968   char *dptr = NULL;		/* Destination pointer. */
2969 
2970   if((d) && (sz) && (s)) {
2971     if(dk3str_c32_len(s) < sz) {
2972       back = 1; ptr = s; dptr = d;
2973       while(0UL != (c = *ptr)) {
2974         if(c < (dk3_c32_t)0x00000100UL) {
2975 	  uc = (unsigned char)c;
2976 	  *(dptr++) = (char)uc;
2977 	} else {
2978 	  if((back == 1) && (app)) {
2979 	    /* ERROR: Illegal character(s) in source string! */
2980 	    dk3app_log_i1(app, DK3_LL_ERROR, 112);
2981 	  }
2982 	  back = 0;
2983 	}
2984 	ptr++;
2985       }
2986       *dptr = '\0';
2987     } else {
2988       d[0] = '\0';
2989       if(app) {
2990         /* ERROR: Source string too long! */
2991 	dk3app_log_i1(app, DK3_LL_ERROR, 108);
2992       }
2993     }
2994   }
2995   return back;
2996 }
2997 
2998 
2999 
3000 
3001 
3002 
3003 
3004 /**	Convert 8-bit plain text to other encodings.
3005 	@param	d	Destination buffer (NULL to just count result elements).
3006 	@param	s	Source string.
3007 	@param	app	Application structure for diagnostics, may be NULL.
3008 	@param	enc	Destination encoding (DK3_ENCODING_xxx).
3009 	@return	Number of destination elements created.
3010 */
3011 static
3012 size_t
dk3str_i_cnv_c8p(void * d,char const * s,dk3_app_t * app,int enc)3013 dk3str_i_cnv_c8p(void *d, char const *s, dk3_app_t *app, int enc)
3014 {
3015   size_t	back = 0;
3016   int		error = 0;	/* Flag: Error occured. */
3017   char const	*sptr = NULL;	/* Source pointer. */
3018   char 		*dp8 = NULL;	/* Pointer to 8-bit destination. */
3019   dk3_c16_t	*dp16 = NULL;	/* Pointer to 16-bit destination. */
3020   dk3_c32_t	*dp32 = NULL;	/* Pointer to 32-bit destination. */
3021   char		c = 0x00;	/* Current source character to process. */
3022   unsigned char	uc = 0x00;	/* Destination byte. */
3023   dk3_c32_t	ul = 0UL;	/* Conversion result. */
3024   unsigned char	myuc[16];	/* Conversion result buffer. */
3025   dk3_c16_t	myc16[16];	/* Conversion result buffer. */
3026   size_t	u8u = 0;	/* UTF-8 bytes used for encoding. */
3027   size_t	u16u = 0;	/* UTF-16 characters used for encoding. */
3028   size_t	sl = 0;		/* Number of remaining characters in source. */
3029   size_t	i = 0;		/* Copy converted characters to destination. */
3030 
3031   if(s) {
3032     sptr = s; sl = dk3str_c8_len(s);
3033     if(d) {
3034       switch(enc) {
3035         case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
3036 	case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
3037 	case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
3038 	default: {
3039 	  if(app) {
3040 	    /* ERROR: Illegal destination encoding! */
3041 	    dk3app_log_i1(app, DK3_LL_ERROR, 114);
3042 	  }
3043 	} break;
3044       }
3045     }
3046     while((sl) && (0 == error)) {
3047       c = *(sptr++); sl--;
3048       uc = (unsigned char)c;
3049       ul = (dk3_c32_t)uc;
3050       ul &= 0x000000FFUL;
3051       switch(enc) {
3052         case DK3_ENCODING_UTF8: {
3053 	  u8u = dk3enc_uc2utf8(ul, myuc, 16);
3054 	  if(u8u) {
3055 	    back = dk3mem_add_size_t(back, u8u, &error);
3056 	    if(d) {
3057 	      for(i = 0; i < u8u; i++) { *(dp8++) = (char)(myuc[i]); }
3058 	    }
3059 	  } else {
3060 	    if(0 == error) {
3061 	      if(app) {
3062 	        /* ERROR: Conversion to UTF-8 failed! */
3063 		dk3app_log_i1(app, DK3_LL_ERROR, 115);
3064 	      }
3065 	    } error = 1;
3066 	  }
3067 	} break;
3068 	case DK3_ENCODING_UTF16: {
3069 	  u16u = dk3enc_uc2utf16(ul, myc16, 16);
3070 	  if(u16u) {
3071 	    back = dk3mem_add_size_t(back, u16u, &error);
3072 	    if(d) {
3073 	      for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
3074 	    }
3075 	  } else {
3076 	    if(0 == error) {
3077 	      if(app) {
3078 	        /* ERROR: Conversion to UTF-16 failed! */
3079 		dk3app_log_i1(app, DK3_LL_ERROR, 116);
3080 	      }
3081 	    } error = 1;
3082 	  }
3083 	} break;
3084 	case DK3_ENCODING_UNICODE: {
3085 	  back = dk3mem_add_size_t(back, 1, &error);
3086 	  if(d) { *(dp32++) = ul; }
3087 	} break;
3088       }
3089     }
3090     if(d) {
3091       switch(enc) {
3092         case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
3093 	case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
3094 	case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
3095       }
3096     }
3097     back = dk3mem_add_size_t(back, 1, &error);
3098     if(error) {
3099       back = 0;
3100       if(error == DK3_ERROR_MATH_OVERFLOW) {
3101         if(app) {
3102 	  /* ERROR: Input string too long for conversion! */
3103 	  dk3app_log_i1(app, DK3_LL_ERROR, 108);
3104 	}
3105       }
3106     }
3107   }
3108   return back;
3109 }
3110 
3111 
3112 
3113 
3114 size_t
dk3str_cnvsz_c8p_to_c8u_app(char const * s,dk3_app_t * app)3115 dk3str_cnvsz_c8p_to_c8u_app(char const *s, dk3_app_t *app)
3116 {
3117   size_t back = 0;
3118   if(s) {
3119     back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
3120   }
3121   return back;
3122 }
3123 
3124 
3125 int
dk3str_cnv_c8p_to_c8u_app(char * d,size_t ds,char const * s,dk3_app_t * app)3126 dk3str_cnv_c8p_to_c8u_app(char *d, size_t ds, char const *s, dk3_app_t *app)
3127 {
3128   int		back = 0;
3129   size_t	sz;		/* Number of chars produced. */
3130   if((d) && (ds) && (s)) {
3131     sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
3132     if(sz) {
3133       if(ds >= sz) {
3134         if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UTF8)) {
3135 	  back = 1;
3136 	}
3137       } else {
3138         if(app) {
3139 	  /* ERROR: Destination buffer too small! */
3140 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3141 	}
3142       }
3143     }
3144   }
3145   return back;
3146 }
3147 
3148 
3149 
3150 char *
dk3str_cnvnew_c8p_to_c8u_app(char const * s,dk3_app_t * app)3151 dk3str_cnvnew_c8p_to_c8u_app(char const *s, dk3_app_t *app)
3152 {
3153   char		*back = NULL;
3154   size_t	sz;		/* Number of characters produced. */
3155   if(s) {
3156     sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
3157     if(sz) {
3158       back = dk3_new_app(char,sz,app);
3159       if(back) {
3160         if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UTF8)) {
3161 	  dk3_delete(back); back = NULL;
3162 	}
3163       }
3164     }
3165   }
3166   return back;
3167 }
3168 
3169 
3170 
3171 size_t
dk3str_cnvsz_c8p_to_c16_app(char const * s,dk3_app_t * app)3172 dk3str_cnvsz_c8p_to_c16_app(char const *s, dk3_app_t *app)
3173 {
3174   size_t back = 0;
3175   if(s) {
3176     back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
3177   }
3178   return back;
3179 }
3180 
3181 
3182 
3183 int
dk3str_cnv_c8p_to_c16_app(dk3_c16_t * d,size_t ds,char const * s,dk3_app_t * app)3184 dk3str_cnv_c8p_to_c16_app(dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app)
3185 {
3186   int		back = 0;
3187   size_t	sz;		/* Destination buffer length needed. */
3188   if((d) && (ds) && (s)) {
3189     sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
3190     if(sz) {
3191       if(ds >= sz) {
3192         if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UTF16)) {
3193 	  back = 1;
3194 	}
3195       } else {
3196         if(app) {
3197 	  /* ERROR: Destination buffer too small! */
3198 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3199 	}
3200       }
3201     }
3202   }
3203   return back;
3204 }
3205 
3206 
3207 
3208 dk3_c16_t *
dk3str_cnvnew_c8p_to_c16_app(char const * s,dk3_app_t * app)3209 dk3str_cnvnew_c8p_to_c16_app(char const *s, dk3_app_t *app)
3210 {
3211   dk3_c16_t	*back = NULL;
3212   size_t	sz;		/* Destination buffer length needed. */
3213   if(s) {
3214     sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
3215     if(sz) {
3216       back = dk3_new_app(dk3_c16_t,sz,app);
3217       if(back) {
3218         if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UTF16)) {
3219 	  dk3_delete(back); back = NULL;
3220 	}
3221       }
3222     }
3223   }
3224   return back;
3225 }
3226 
3227 
3228 
3229 size_t
dk3str_cnvsz_c8p_to_c32_app(char const * s,dk3_app_t * app)3230 dk3str_cnvsz_c8p_to_c32_app(char const *s, dk3_app_t *app)
3231 {
3232   size_t back = 0;
3233   if(s) {
3234     back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
3235   }
3236   return back;
3237 }
3238 
3239 
3240 
3241 int
dk3str_cnv_c8p_to_c32_app(dk3_c32_t * d,size_t ds,char const * s,dk3_app_t * app)3242 dk3str_cnv_c8p_to_c32_app(dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app)
3243 {
3244   int		back = 0;
3245   size_t	sz;		/* Destination buffer length needed. */
3246   if((d) && (ds) && (s)) {
3247     sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
3248     if(sz) {
3249       if(ds >= sz) {
3250         if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UNICODE)) {
3251 	  back = 1;
3252 	}
3253       } else {
3254         if(app) {
3255 	  /* ERROR: Destination buffer too small! */
3256 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3257 	}
3258       }
3259     }
3260   }
3261   return back;
3262 }
3263 
3264 
3265 
3266 dk3_c32_t *
dk3str_cnvnew_c8p_to_c32_app(char const * s,dk3_app_t * app)3267 dk3str_cnvnew_c8p_to_c32_app(char const *s, dk3_app_t *app)
3268 {
3269   dk3_c32_t	*back = NULL;
3270   size_t	sz;		/* Destination buffer length needed. */
3271   if(s) {
3272     sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
3273     if(sz) {
3274       back = dk3_new_app(dk3_c32_t,sz,app);
3275       if(back) {
3276         if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UNICODE)) {
3277 	  dk3_delete(back); back = NULL;
3278 	}
3279       }
3280     }
3281   }
3282   return back;
3283 }
3284 
3285 
3286 
3287 /**	Convert UTF-8 string to other encodings.
3288 	@param	d	Destination pointer, may be NULL.
3289 	@param	s	Source string.
3290 	@param	app	Application structure for diagnostics, may be NULL.
3291 	@param	enc	Destination encoding.
3292 	@return	Buffer length used (d!=NULL) or needed (d==NULL).
3293 */
3294 static
3295 size_t
dk3str_i_cnv_c8u(void * d,char const * s,dk3_app_t * app,int enc)3296 dk3str_i_cnv_c8u(void *d, char const *s, dk3_app_t *app, int enc)
3297 {
3298   size_t		back = 0;
3299   int			error = 0;	/* Flag: Error occued. */
3300   char			*dp8 = NULL;	/* Pointer to 8-bit destination. */
3301   dk3_c16_t		*dp16 = NULL;	/* Pointer to 16-bit destination. */
3302   dk3_c32_t		*dp32 = NULL;	/* Pointer to 32-bit destination. */
3303   dk3_c16_t		myc16[16];	/* Conversion result buffer. */
3304   dk3_c32_t		c32 = 0UL;	/* Conversion result. */
3305   unsigned char		uc = 0x00;	/* Result character. */
3306   char			c = 0x00;	/* Current character to process. */
3307   unsigned char const	*sptr = NULL;	/* Source ponter. */
3308   size_t		u8u = 0;	/* Number of UTF-8 bytes used. */
3309   size_t		u16u = 0;	/* Number of UTF-16 chars produced. */
3310   size_t		i = 0;		/* Copy buffer to destination. */
3311   size_t		sl = 0;		/* Remaining source string length. */
3312 
3313   if(s) {
3314     /* Initialize variables */
3315     sptr = (unsigned char const *)s; sl = dk3str_c8_len(s);
3316     if(d) {
3317       switch(enc) {
3318         case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
3319 	case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
3320 	case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
3321 	default: {
3322 	  if(0 == error) {
3323 	    if(app) {
3324 	      /* ERROR: Illegal output encoding! */
3325 	      dk3app_log_i1(app, DK3_LL_ERROR, 114);
3326 	    }
3327 	  } error = 1;
3328 	} break;
3329       }
3330     }
3331     /* Process input */
3332     while((sl) && (0 == error)) {
3333       u8u = 0;
3334       if(dk3enc_utf82uc(&c32, sptr, sl, &u8u)) {
3335         if(u8u) {
3336 	  switch(enc) {
3337             case DK3_ENCODING_PLAIN: {
3338 	      if(c32 < (dk3_c32_t)0x00000100UL) {
3339 		back = dk3mem_add_size_t(back, 1, &error);
3340 		if(d) {
3341 	          uc = (unsigned char)c32;
3342 		  c = (char)uc;
3343 		  *(dp8++) = c;
3344 		}
3345 	      } else {
3346 	        if(0 == error) {
3347 		  if(app) {
3348 		    /* ERROR: Result character out of range! */
3349 		    dk3app_log_i1(app, DK3_LL_ERROR, 117);
3350 		  }
3351 		} error = 1;
3352 	      }
3353 	    } break;
3354 	    case DK3_ENCODING_UTF16: {
3355 	      u16u = dk3enc_uc2utf16(c32, myc16, 16);
3356 	      if(u16u) {
3357 		back = dk3mem_add_size_t(back, u16u, &error);
3358 		if(d) {
3359 		  for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
3360 		}
3361 	      } else {
3362 	        if(0 == error) {
3363 		  if(app) {
3364 		    /* ERROR: Conversion to UTF-16 failed! */
3365 		    dk3app_log_i1(app, DK3_LL_ERROR, 116);
3366 		  }
3367 		} error = 1;
3368 	      }
3369 	    } break;
3370 	    case DK3_ENCODING_UNICODE: {
3371 	      back = dk3mem_add_size_t(back, 1, &error);
3372 	      if(d) { *(dp32++) = c32; }
3373 	    } break;
3374 	  }
3375 	  if(sl >= u8u) {
3376 	    sl = sl - u8u;
3377 	    sptr = &(sptr[u8u]);
3378 	  } else {
3379 	    sl = 0;
3380 	  }
3381 	} else {
3382 	  if(0 == error) {
3383 	    if(app) {
3384 	      /* ERROR: UTF-8 decode operation failed! */
3385 	      dk3app_log_i1(app, DK3_LL_ERROR, 118);
3386 	    }
3387 	  } error = 1;
3388 	}
3389       } else {
3390         if(0 == error) {
3391 	  if(app) {
3392 	    /* ERROR: UTF-8 decode operation failed! */
3393 	    dk3app_log_i1(app, DK3_LL_ERROR, 118);
3394 	  }
3395 	} error = 1;
3396       }
3397     }
3398     /* Finalize output */
3399     back = dk3mem_add_size_t(back, 1, &error);
3400     if(d) {
3401       switch(enc) {
3402         case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
3403 	case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
3404 	case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
3405       }
3406     }
3407     if(error) {
3408       back = 0;
3409       if(error == DK3_ERROR_MATH_OVERFLOW) {
3410         if(app) {
3411 	  /* ERROR: Input string too long for conversion! */
3412 	  dk3app_log_i1(app, DK3_LL_ERROR, 108);
3413 	}
3414       }
3415     }
3416   }
3417   return back;
3418 }
3419 
3420 
3421 
3422 size_t
dk3str_cnvsz_c8u_to_c8p_app(char const * s,dk3_app_t * app)3423 dk3str_cnvsz_c8u_to_c8p_app(char const *s, dk3_app_t *app)
3424 {
3425   size_t back = 0;
3426   if(s) {
3427     back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
3428   }
3429   return back;
3430 }
3431 
3432 
3433 
3434 int
dk3str_cnv_c8u_to_c8p_app(char * d,size_t ds,char const * s,dk3_app_t * app)3435 dk3str_cnv_c8u_to_c8p_app(char *d, size_t ds, char const *s, dk3_app_t *app)
3436 {
3437   int		back = 0;
3438   size_t	sz;		/* Destination buffer length needed. */
3439   if((d) && (ds) && (s)) {
3440     sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
3441     if(sz) {
3442       if(ds >= sz) {
3443         if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_PLAIN)) {
3444 	  back = 1;
3445 	}
3446       } else {
3447         if(app) {
3448 	  /* ERROR: Destination buffer too small! */
3449 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3450 	}
3451       }
3452     }
3453   }
3454   return back;
3455 }
3456 
3457 
3458 char *
dk3str_cnvnew_c8u_to_c8p_app(char const * s,dk3_app_t * app)3459 dk3str_cnvnew_c8u_to_c8p_app(char const *s, dk3_app_t *app)
3460 {
3461   char		*back = NULL;
3462   size_t	sz;		/* Destination buffer length needed. */
3463   if(s) {
3464     sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
3465     if(sz) {
3466       back = dk3_new_app(char,sz,app);
3467       if(back) {
3468         if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_PLAIN)) {
3469 	  dk3_delete(back); back = NULL;
3470 	}
3471       }
3472     }
3473   }
3474   return back;
3475 }
3476 
3477 
3478 
3479 
3480 size_t
dk3str_cnvsz_c8u_to_c16_app(char const * s,dk3_app_t * app)3481 dk3str_cnvsz_c8u_to_c16_app(char const *s, dk3_app_t *app)
3482 {
3483   size_t back = 0;
3484   if(s) {
3485     back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
3486   }
3487   return back;
3488 }
3489 
3490 
3491 
3492 int
dk3str_cnv_c8u_to_c16_app(dk3_c16_t * d,size_t ds,char const * s,dk3_app_t * app)3493 dk3str_cnv_c8u_to_c16_app(dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app)
3494 {
3495   int		back = 0;
3496   size_t	sz;		/* Destination buffer length needed. */
3497   if((d) && (ds) && (s)) {
3498     sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
3499     if(sz) {
3500       if(ds >= sz) {
3501         if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_UTF16)) {
3502 	  back = 1;
3503 	}
3504       } else {
3505         if(app) {
3506 	  /* ERROR: Destination buffer too small! */
3507 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3508 	}
3509       }
3510     }
3511   }
3512   return back;
3513 }
3514 
3515 
3516 
3517 dk3_c16_t *
dk3str_cnvnew_c8u_to_c16_app(char const * s,dk3_app_t * app)3518 dk3str_cnvnew_c8u_to_c16_app(char const *s, dk3_app_t *app)
3519 {
3520   dk3_c16_t	*back = NULL;
3521   size_t	sz;		/* Destination buffer length needed. */
3522   if(s) {
3523     sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
3524     if(sz) {
3525       back = dk3_new_app(dk3_c16_t,sz,app);
3526       if(back) {
3527         if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_UTF16)) {
3528 	  dk3_delete(back); back = NULL;
3529 	}
3530       }
3531     }
3532   }
3533   return back;
3534 }
3535 
3536 
3537 
3538 size_t
dk3str_cnvsz_c8u_to_c32_app(char const * s,dk3_app_t * app)3539 dk3str_cnvsz_c8u_to_c32_app(char const *s, dk3_app_t *app)
3540 {
3541   size_t back = 0;
3542 
3543   if(s) {
3544     back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
3545   }
3546   return back;
3547 }
3548 
3549 
3550 
3551 int
dk3str_cnv_c8u_to_c32_app(dk3_c32_t * d,size_t ds,char const * s,dk3_app_t * app)3552 dk3str_cnv_c8u_to_c32_app(dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app)
3553 {
3554   int		back = 0;
3555   size_t	sz;		/* Destination buffer length needed. */
3556   if((d) && (ds) && (s)) {
3557     sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
3558     if(sz) {
3559       if(ds >= sz) {
3560         if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_UNICODE)) {
3561 	  back = 1;
3562 	}
3563       } else {
3564         if(app) {
3565 	  /* ERROR: Destination buffer too small! */
3566 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3567 	}
3568       }
3569     }
3570   }
3571   return back;
3572 }
3573 
3574 
3575 
3576 dk3_c32_t *
dk3str_cnvnew_c8u_to_c32_app(char const * s,dk3_app_t * app)3577 dk3str_cnvnew_c8u_to_c32_app(char const *s, dk3_app_t *app)
3578 {
3579   dk3_c32_t	*back = NULL;
3580   size_t	sz;		/* Destination buffer length needed. */
3581   if(s) {
3582     sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
3583     if(sz) {
3584       back = dk3_new_app(dk3_c32_t,sz,app);
3585       if(back) {
3586         if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_UNICODE)) {
3587 	  dk3_delete(back); back = NULL;
3588 	}
3589       }
3590     }
3591   }
3592   return back;
3593 }
3594 
3595 
3596 
3597 /**	Convert 16-bit character string to other encodings.
3598 	@param	d	Destination pointer (NULL for size check).
3599 	@param	s	Source string.
3600 	@param	app	Application structure for diagnostics.
3601 	@param	enc	Destination encoding.
3602 	@return	Number of destination characters needed/produced.
3603 */
3604 static
3605 size_t
dk3str_i_cnv_c16(void * d,dk3_c16_t const * s,dk3_app_t * app,int enc)3606 dk3str_i_cnv_c16(void *d, dk3_c16_t const *s, dk3_app_t *app, int enc)
3607 {
3608   size_t		back = 0;
3609   int			error = 0;	/* Flag: Error occured. */
3610   char			*dp8 = NULL;	/* Pointer to 8-bit destination. */
3611   dk3_c32_t		*dp32 = NULL;	/* Pointer to 32-bit destination. */
3612   dk3_c16_t const	*sptr = NULL;	/* Source pointer. */
3613   dk3_c32_t		c32 = 0UL;	/* Conversion result. */
3614   unsigned char		uc = 0x00;	/* Current output character. */
3615   char			c = 0x00;	/* Current output character. */
3616   unsigned char		myuc[16];	/* Conversion result buffer. */
3617   size_t		sl = 0;		/* Remaining string length. */
3618   size_t		u16u = 0;	/* Number of U16 characters used. */
3619   size_t		u8u = 0;	/* Number of 8-bit chars produced. */
3620   size_t		i = 0;		/* Copy buffer to destination. */
3621   if(s) {
3622     /* Initialize variables */
3623     sptr = s; sl = dk3str_c16_len(s);
3624     if(d) {
3625       switch(enc) {
3626         case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
3627 	case DK3_ENCODING_UTF8:	{ dp8 = (char *)d; } break;
3628 	case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
3629 	default: {
3630 	  if(0 == error) {
3631 	    if(app) {
3632 	      /* ERROR: Illegal output encoding! */
3633 	      dk3app_log_i1(app, DK3_LL_ERROR, 114);
3634 	    }
3635 	  } error = 1;
3636 	} break;
3637       }
3638     }
3639     /* Process input */
3640     while((sl) && (0 == error)) {
3641       u16u = 0;
3642       if(dk3enc_utf162uc(&c32, sptr, sl, &u16u)) {
3643         if(u16u) {
3644 	  if(sl >= u16u) {
3645 	    switch(enc) {
3646               case DK3_ENCODING_PLAIN: {
3647 	        if(c32 < (dk3_c32_t)0x00000100UL) {
3648 		  back = dk3mem_add_size_t(back, 1, &error);
3649 		  if(d) {
3650 		    uc = (unsigned char)c32; c = (char)uc;
3651 		    *(dp8++) = c;
3652 		  }
3653 		} else {
3654 		  if(0 == error) {
3655 		    if(app) {
3656 		      /* ERROR: Result character out of range! */
3657 		      dk3app_log_i1(app, DK3_LL_ERROR, 117);
3658 		    }
3659 		  } error = 1;
3660 		}
3661 	      } break;
3662 	      case DK3_ENCODING_UTF8:	{
3663 	        u8u = dk3enc_uc2utf8(c32, myuc, 16);
3664 		if(u8u) {
3665 		  back = dk3mem_add_size_t(back, u8u, &error);
3666 		  if(d) {
3667 		    for(i = 0; i < u8u; i++) { *(dp8++) = (char)(myuc[i]); }
3668 		  }
3669 		} else {
3670 		  if(0 == error) {
3671 		    if(app) {
3672 		      /* ERROR: Conversion to UTF-8 failed! */
3673 		      dk3app_log_i1(app, DK3_LL_ERROR, 115);
3674 		    }
3675 		  } error = 1;
3676 		}
3677 	      } break;
3678 	      case DK3_ENCODING_UNICODE: {
3679 		back = dk3mem_add_size_t(back, 1, &error);
3680 		if(d) { *(dp32++) = c32; }
3681 	      } break;
3682 	    }
3683 	    sl = sl - u16u;
3684 	    sptr = &(sptr[u16u]);
3685 	  } else {
3686 	    sl = 0;
3687 	  }
3688 	} else {
3689 	  if(0 == error) {
3690 	    if(app) {
3691 	      /* ERROR: UTF-16 decode operation failed! */
3692 	      dk3app_log_i1(app, DK3_LL_ERROR, 119);
3693 	    }
3694 	  } error = 1;
3695 	}
3696       } else {
3697         if(0 == error) {
3698 	  if(app) {
3699 	    /* ERROR: UTF-16 decode operation failed! */
3700 	    dk3app_log_i1(app, DK3_LL_ERROR, 119);
3701 	  }
3702 	} error = 1;
3703       }
3704     }
3705     /* Finalize output */
3706     back = dk3mem_add_size_t(back, 1, &error);
3707     if(d) {
3708       switch(enc) {
3709         case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
3710 	case DK3_ENCODING_UTF8:	{ *dp8 = '\0'; } break;
3711 	case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
3712       }
3713     }
3714     if(error) {
3715       back = 0;
3716       if(error == DK3_ERROR_MATH_OVERFLOW) {
3717         if(app) {
3718 	  /* ERROR: Input string too long for conversion! */
3719 	  dk3app_log_i1(app, DK3_LL_ERROR, 108);
3720 	}
3721       }
3722     }
3723   }
3724   return back;
3725 }
3726 
3727 
3728 
3729 size_t
dk3str_cnvsz_c16_to_c8p_app(dk3_c16_t const * s,dk3_app_t * app)3730 dk3str_cnvsz_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app)
3731 {
3732   size_t back = 0;
3733   if(s) {
3734     back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
3735   }
3736   return back;
3737 }
3738 
3739 
3740 
3741 int
dk3str_cnv_c16_to_c8p_app(char * d,size_t ds,dk3_c16_t const * s,dk3_app_t * app)3742 dk3str_cnv_c16_to_c8p_app(char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
3743 {
3744   int		back = 0;
3745   size_t	sz;		/* Destination buffer size needed. */
3746   if((d) && (ds) && (s)) {
3747     sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
3748     if(sz) {
3749       if(ds >= sz) {
3750         if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_PLAIN)) {
3751 	  back = 1;
3752 	}
3753       } else {
3754         if(app) {
3755 	  /* ERROR: Result buffer too small! */
3756 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3757 	}
3758       }
3759     }
3760   }
3761   return back;
3762 }
3763 
3764 
3765 
3766 char *
dk3str_cnvnew_c16_to_c8p_app(dk3_c16_t const * s,dk3_app_t * app)3767 dk3str_cnvnew_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app)
3768 {
3769   char		*back = NULL;
3770   size_t	sz;		/* Destination buffer size needed. */
3771   if(s) {
3772     sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
3773     if(sz) {
3774       back = dk3_new_app(char,sz,app);
3775       if(back) {
3776         if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_PLAIN)) {
3777 	  dk3_delete(back); back = NULL;
3778 	}
3779       }
3780     }
3781   }
3782   return back;
3783 }
3784 
3785 
3786 
3787 size_t
dk3str_cnvsz_c16_to_c8u_app(dk3_c16_t const * s,dk3_app_t * app)3788 dk3str_cnvsz_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app)
3789 {
3790   size_t back = 0;
3791   if(s) {
3792     back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
3793   }
3794   return back;
3795 }
3796 
3797 
3798 
3799 int
dk3str_cnv_c16_to_c8u_app(char * d,size_t ds,dk3_c16_t const * s,dk3_app_t * app)3800 dk3str_cnv_c16_to_c8u_app(char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
3801 {
3802   int		back = 0;
3803   size_t	sz;		/* Destination buffer size needed. */
3804   if((d) && (ds) && (s)) {
3805     sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
3806     if(sz) {
3807       if(ds >= sz) {
3808         if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_UTF8)) {
3809 	  back = 1;
3810 	}
3811       } else {
3812         if(app) {
3813 	  /* ERROR: Result buffer too small! */
3814 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3815 	}
3816       }
3817     }
3818   }
3819   return back;
3820 }
3821 
3822 
3823 char *
dk3str_cnvnew_c16_to_c8u_app(dk3_c16_t const * s,dk3_app_t * app)3824 dk3str_cnvnew_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app)
3825 {
3826   char		*back = NULL;
3827   size_t	sz;		/* Destination buffer size needed. */
3828   if(s) {
3829     sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
3830     if(sz) {
3831       back = dk3_new_app(char,sz,app);
3832       if(back) {
3833         if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_UTF8)) {
3834 	  dk3_delete(back); back = NULL;
3835 	}
3836       }
3837     }
3838   }
3839   return back;
3840 }
3841 
3842 
3843 
3844 int
dk3str_c16_to_c8_simple_app(char * d,size_t sz,dk3_c16_t const * s,dk3_app_t * app)3845 dk3str_c16_to_c8_simple_app(
3846   char *d, size_t sz, dk3_c16_t const *s, dk3_app_t *app
3847 )
3848 {
3849   int back = 0;
3850   dk3_c16_t const *ptr;	/* Source pointer. */
3851   dk3_c16_t c;		/* Source character. */
3852   unsigned char uc;	/* Destination character. */
3853   char *dptr;		/* Destination pointer. */
3854 
3855   if((d) && (sz) && (s)) {
3856     if(dk3str_c16_len(s) < sz) {
3857       back = 1; ptr = s; dptr = d;
3858       while(0U != (c = *ptr)) {
3859         if(c < 0x0100U) {
3860 	  uc = (unsigned char)c;
3861 	  *(dptr++) = (char)uc;
3862 	} else {
3863 	  if((back == 1) && (app)) {
3864 	    /* ERROR: Illegal character(s) in source string! */
3865 	    dk3app_log_i1(app, DK3_LL_ERROR, 112);
3866 	  }
3867 	  back = 0;
3868 	}
3869         ptr++;
3870       }
3871       *dptr = '\0';
3872     } else {
3873       d[0] = '\0';
3874       if(app) {
3875         /* ERROR: Source string too long! */
3876 	dk3app_log_i1(app, DK3_LL_ERROR, 108);
3877       }
3878     }
3879   }
3880   return back;
3881 }
3882 
3883 
3884 size_t
dk3str_cnvsz_c16_to_c32_app(dk3_c16_t const * s,dk3_app_t * app)3885 dk3str_cnvsz_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app)
3886 {
3887   size_t back = 0;
3888   if(s) {
3889     back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
3890   }
3891   return back;
3892 }
3893 
3894 
3895 
3896 int
dk3str_cnv_c16_to_c32_app(dk3_c32_t * d,size_t ds,dk3_c16_t const * s,dk3_app_t * app)3897 dk3str_cnv_c16_to_c32_app(dk3_c32_t *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
3898 {
3899   int		back = 0;
3900   size_t	sz;		/* Destination buffer size needed. */
3901   if((d) && (ds) && (s)) {
3902     sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
3903     if(sz) {
3904       if(ds >= sz) {
3905         if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_UNICODE)) {
3906 	  back = 1;
3907 	}
3908       } else {
3909         if(app) {
3910 	  /* ERROR: Result buffer too small! */
3911 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
3912 	}
3913       }
3914     }
3915   }
3916   return back;
3917 }
3918 
3919 
3920 
3921 dk3_c32_t *
dk3str_cnvnew_c16_to_c32_app(dk3_c16_t const * s,dk3_app_t * app)3922 dk3str_cnvnew_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app)
3923 {
3924   dk3_c32_t	*back = NULL;
3925   size_t	sz;		/* Destination buffer size needed. */
3926   if(s) {
3927     sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
3928     if(sz) {
3929       back = dk3_new_app(dk3_c32_t,sz,app);
3930       if(back) {
3931         if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_UNICODE)) {
3932 	  dk3_delete(back); back = NULL;
3933 	}
3934       }
3935     }
3936   }
3937   return back;
3938 }
3939 
3940 
3941 
3942 /**	Convert 32-bit character string to other encodings.
3943 	@param	d	Destination buffer pointer (may be NULL for size check).
3944 	@param	s	Source string.
3945 	@param	app	Application structure for diagnostics.
3946 	@param	enc	Output encoding.
3947 	@return	Number of destination characters produced/needed.
3948 */
3949 static
3950 size_t
dk3str_i_cnv_c32(void * d,dk3_c32_t const * s,dk3_app_t * app,int enc)3951 dk3str_i_cnv_c32(void *d, dk3_c32_t const *s, dk3_app_t *app, int enc)
3952 {
3953   size_t		back = 0;
3954   int			error = 0;	/* Flag: Error occured. */
3955   char			*dp8 = NULL;	/* Pointer to 8-bit destination. */
3956   dk3_c16_t		*dp16 = NULL;	/* Pointer to 16-bit destination. */
3957   dk3_c32_t const	*sptr = NULL;	/* Source pointer. */
3958   dk3_c32_t		c32 = 0UL;	/* Current character to process. */
3959   dk3_c16_t		myc16[16];	/* Conversion result buffer. */
3960   unsigned char		myuc[16];	/* Conversion result buffer. */
3961   unsigned char		uc = 0x00;	/* Output character. */
3962   char			c = 0x00;	/* Output character. */
3963   size_t		sl = 0;		/* Remaining string length. */
3964   size_t		u8u = 0;	/* Number of UTF-8 chars produced. */
3965   size_t		u16u = 0;	/* Numer of UTF-16 chars produced. */
3966   size_t		i = 0;		/* Copy buffer to destination. */
3967 
3968   if(s) {
3969     /* Initialize variables */
3970     sptr = s; sl = dk3str_c32_len(s);
3971     if(d) {
3972       switch(enc) {
3973         case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
3974 	case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
3975 	case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
3976 	default: {
3977 	  if(0 == error) {
3978 	    if(app) {
3979 	      /* ERROR: Illegal output encoding! */
3980 	      dk3app_log_i1(app, DK3_LL_ERROR, 114);
3981 	    }
3982 	  } error = 1;
3983 	} break;
3984       }
3985     }
3986     /* Process input */
3987     while((sl) && (0 == error)) {
3988       c32 = *(sptr++); sl--;
3989       switch(enc) {
3990         case DK3_ENCODING_PLAIN: {
3991 	  if(c32 < (dk3_c32_t)0x00000100UL) {
3992 	    back = dk3mem_add_size_t(back, 1, &error);
3993 	    if(d) {
3994 	      uc = (unsigned char)c32; c = (char)uc;
3995 	      *(dp8++) = c;
3996 	    }
3997 	  } else {
3998 	    if(0 == error) {
3999 	      if(app) {
4000 	        /* ERROR: Output character out of range! */
4001 		dk3app_log_i1(app, DK3_LL_ERROR, 117);
4002 	      }
4003 	    } error = 1;
4004 	  }
4005 	} break;
4006 	case DK3_ENCODING_UTF8: {
4007 	  u8u = dk3enc_uc2utf8(c32, myuc, 16);
4008 	  if(u8u) {
4009 	    back = dk3mem_add_size_t(back, u8u, &error);
4010 	    if(d) {
4011 	      for(i = 0; i < u8u; i++) { *(dp8++) = (char)(myuc[i]); }
4012 	    }
4013 	  } else {
4014 	    if(0 == error) {
4015 	      if(app) {
4016 	        /* ERROR: UTF-8 encoding failed! */
4017 		dk3app_log_i1(app, DK3_LL_ERROR, 115);
4018 	      }
4019 	    } error = 1;
4020 	  }
4021 	} break;
4022 	case DK3_ENCODING_UTF16: {
4023 	  u16u = dk3enc_uc2utf16(c32, myc16, 16);
4024 	  if(u16u) {
4025 	    back = dk3mem_add_size_t(back, u16u, &error);
4026 	    if(d) {
4027 	      for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
4028 	    }
4029 	  } else {
4030 	    if(0 == error) {
4031 	      if(app) {
4032 	        /* ERROR: Conversion to UTF-16 failed! */
4033 		dk3app_log_i1(app, DK3_LL_ERROR, 116);
4034 	      }
4035 	    } error = 1;
4036 	  }
4037 	} break;
4038       }
4039     }
4040     /* Finalize output */
4041     back = dk3mem_add_size_t(back, 1, &error);
4042     if(d) {
4043       switch(enc) {
4044         case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
4045 	case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
4046 	case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
4047       }
4048     }
4049     if(error) {
4050       back = 0;
4051       if(error == DK3_ERROR_MATH_OVERFLOW) {
4052         if(app) {
4053 	  /* ERROR: Input string too long for conversion! */
4054 	  dk3app_log_i1(app, DK3_LL_ERROR, 108);
4055 	}
4056       }
4057     }
4058   }
4059   return back;
4060 }
4061 
4062 
4063 
4064 size_t
dk3str_cnvsz_c32_to_c8p_app(dk3_c32_t const * s,dk3_app_t * app)4065 dk3str_cnvsz_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app)
4066 {
4067   size_t back = 0;
4068   if(s) {
4069     back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
4070   }
4071   return back;
4072 }
4073 
4074 
4075 
4076 int
dk3str_cnv_c32_to_c8p_app(char * d,size_t ds,dk3_c32_t const * s,dk3_app_t * app)4077 dk3str_cnv_c32_to_c8p_app(char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
4078 {
4079   int		back = 0;
4080   size_t	sz;		/* Destination buffer size needed. */
4081   if((d) && (ds) && (s)) {
4082     sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
4083     if(sz) {
4084       if(ds >= sz) {
4085         if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_PLAIN)) {
4086 	  back = 1;
4087 	}
4088       } else {
4089         if(app) {
4090 	  /* ERROR: Destination buffer too small! */
4091 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
4092 	}
4093       }
4094     }
4095   }
4096   return back;
4097 }
4098 
4099 
4100 
4101 char *
dk3str_cnvnew_c32_to_c8p_app(dk3_c32_t const * s,dk3_app_t * app)4102 dk3str_cnvnew_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app)
4103 {
4104   char		*back = NULL;
4105   size_t	sz;		/* Destination buffer size needed. */
4106   if(s) {
4107     sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
4108     if(sz) {
4109       back = dk3_new_app(char,sz,app);
4110       if(back) {
4111         if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_PLAIN)) {
4112 	  dk3_delete(back); back = NULL;
4113 	}
4114       }
4115     }
4116   }
4117   return back;
4118 }
4119 
4120 
4121 
4122 size_t
dk3str_cnvsz_c32_to_c8u_app(dk3_c32_t const * s,dk3_app_t * app)4123 dk3str_cnvsz_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app)
4124 {
4125   size_t back = 0;
4126   if(s) {
4127     back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
4128   }
4129   return back;
4130 }
4131 
4132 
4133 
4134 int
dk3str_cnv_c32_to_c8u_app(char * d,size_t ds,dk3_c32_t const * s,dk3_app_t * app)4135 dk3str_cnv_c32_to_c8u_app(char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
4136 {
4137   int		back = 0;
4138   size_t	sz;		/* Destination buffer size needed. */
4139   if((d) && (ds) && (s)) {
4140     sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
4141     if(sz) {
4142       if(ds >= sz) {
4143         if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_UTF8)) {
4144 	  back = 1;
4145 	}
4146       } else {
4147         if(app) {
4148 	  /* ERROR: Destination buffer too small! */
4149 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
4150 	}
4151       }
4152     }
4153   }
4154   return back;
4155 }
4156 
4157 
4158 
4159 char *
dk3str_cnvnew_c32_to_c8u_app(dk3_c32_t const * s,dk3_app_t * app)4160 dk3str_cnvnew_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app)
4161 {
4162   char		*back = NULL;
4163   size_t	sz;		/* Destination buffer size needed. */
4164   if(s) {
4165     sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
4166     if(sz) {
4167       back = dk3_new_app(char,sz,app);
4168       if(back) {
4169         if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_UTF8)) {
4170 	  dk3_delete(back); back = NULL;
4171 	}
4172       }
4173     }
4174   }
4175   return back;
4176 }
4177 
4178 
4179 
4180 size_t
dk3str_cnvsz_c32_to_c16_app(dk3_c32_t const * s,dk3_app_t * app)4181 dk3str_cnvsz_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app)
4182 {
4183   size_t back = 0;
4184   if(s) {
4185     back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
4186   }
4187   return back;
4188 }
4189 
4190 
4191 
4192 int
dk3str_cnv_c32_to_c16_app(dk3_c16_t * d,size_t ds,dk3_c32_t const * s,dk3_app_t * app)4193 dk3str_cnv_c32_to_c16_app(dk3_c16_t *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
4194 {
4195   int		back = 0;
4196   size_t	sz;		/* Destination buffer size needed. */
4197   if((d) && (ds) && (s)) {
4198     sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
4199     if(sz) {
4200       if(ds >= sz) {
4201         if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_UTF16)) {
4202 	  back = 1;
4203 	}
4204       } else {
4205         if(app) {
4206 	  /* ERROR: Destination buffer too small! */
4207 	  dk3app_log_i1(app, DK3_LL_ERROR, 38);
4208 	}
4209       }
4210     }
4211   }
4212   return back;
4213 }
4214 
4215 
4216 
4217 dk3_c16_t *
dk3str_cnvnew_c32_to_c16_app(dk3_c32_t const * s,dk3_app_t * app)4218 dk3str_cnvnew_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app)
4219 {
4220   dk3_c16_t	*back = NULL;
4221   size_t	sz;		/* Destination buffer size needed. */
4222   if(s) {
4223     sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
4224     if(sz) {
4225       back = dk3_new_app(dk3_c16_t,sz,app);
4226       if(back) {
4227         if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_UTF16)) {
4228 	  dk3_delete(back); back = NULL;
4229 	}
4230       }
4231     }
4232   }
4233   return back;
4234 }
4235 
4236 
4237 
4238 int
dk3str_cnv_c8_to_str_app(dkChar * d,size_t sz,char const * s,dk3_app_t * app)4239 dk3str_cnv_c8_to_str_app(dkChar *d, size_t sz, char const *s, dk3_app_t *app)
4240 {
4241   register int		back = 0;
4242   register size_t	l;		/* Number of destination chars used. */
4243   register char const	*sptr;		/* Source pointer. */
4244   register dkChar	*dptr;		/* Destination pointer. */
4245   register char		x = 0x00;	/* Current character to process. */
4246 
4247   if((d) && (sz) && (s)) {
4248     sptr = s; dptr = d; l = 0; back = 1;
4249     while((*sptr) && (l < (sz - 1))) {
4250       x = *(sptr++);
4251       *(dptr++) = (dkChar)x;
4252       l++;
4253     }
4254     *dptr = (dkChar)'\0';
4255     if(*sptr) {
4256       back = 0;
4257       if(app) {
4258         /* ERROR: Destination buffer too small! */
4259 	dk3app_log_i1(app, DK3_LL_ERROR, 38);
4260       }
4261     }
4262   }
4263   return back;
4264 }
4265 
4266 
4267 
4268 int
dk3str_string_to_c8_simple_app(char * db,size_t sz,dkChar const * s,dk3_app_t * ap)4269 dk3str_string_to_c8_simple_app(char *db,size_t sz,dkChar const *s,dk3_app_t *ap)
4270 {
4271   int			back = 0;
4272   register dkChar const	*sptr;		/* Source pointer. */
4273   register dkChar	x;		/* Current source character. */
4274   register char		*dptr;		/* Destination pointer. */
4275 
4276   if((db) && (sz) && (s)) {
4277     if(dk3str_len(s) < sz) {
4278       back = 1;
4279       sptr = s; dptr = db;
4280       while(*sptr) {
4281         x = *(sptr++);
4282 	*(dptr++) = (char)x;
4283 #if DK3_CHAR_SIZE > 1
4284 	if(x > (dkChar)0xFF) {
4285 	  back = 0;
4286 	}
4287 #endif
4288       }
4289       *dptr = '\0';
4290       if(!(back)) {
4291         if(ap) {
4292 	  /* ERROR: Non-ISO-LATIN-1 characters found! */
4293 	  dk3app_log_i1(ap, DK3_LL_ERROR, 219);
4294 	}
4295       }
4296     } else {
4297       if(ap) {
4298         /* ERROR: Destination buffer too short! */
4299 	dk3app_log_i1(ap, DK3_LL_ERROR, 38);
4300       }
4301     }
4302   }
4303   return back;
4304 }
4305 
4306 
4307 
4308 void
dk3str_string_tolower(dkChar * s)4309 dk3str_string_tolower(dkChar *s)
4310 {
4311   dkChar *ptr;	/* Pointer into string. */
4312   if(s) {
4313     ptr = s;
4314     while(*ptr) {
4315       *ptr = dk3str_tolower(*ptr);
4316       ptr++;
4317     }
4318   }
4319 }
4320 
4321 
4322 
4323 int
dk3str_c8_to_str_simple_app(dkChar * dp,size_t ds,char const * sp,dk3_app_t * app)4324 dk3str_c8_to_str_simple_app(
4325   dkChar *dp, size_t ds, char const *sp, dk3_app_t *app
4326 )
4327 {
4328   int		 back = 0;
4329   char const	*sptr;		/* Pointer into source buffer. */
4330   dkChar	*dptr;		/* Pointer into destination buffer. */
4331   size_t	 sz;		/* Required destination size. */
4332   if((dp) && (ds) && (sp)) {
4333     sz = dk3str_c8_len(sp);
4334     if(ds > sz) {
4335       back = 1; sptr = sp; dptr = dp;
4336       while(*sptr) { *(dptr++) = (dkChar)(*(sptr++)); }
4337       *dptr = dkT('\0');
4338     } else {
4339       if(app) {
4340         /* ERROR: Destination buffer too short! */
4341 	dk3app_log_i1(app, DK3_LL_ERROR, 38);
4342       }
4343     }
4344   }
4345   return back;
4346 }
4347 
4348 
4349 
4350 int
dk3str_to_c8p_app(char * dp,size_t sz,dkChar const * src,int DK3_ARG_UNUSED (ie),dk3_app_t * app)4351 dk3str_to_c8p_app(
4352   char		 *dp,
4353   size_t	 sz,
4354   dkChar const	*src,
4355 #if DK3_CHAR_SIZE > 1
4356   int		 DK3_ARG_UNUSED(ie),
4357 #else
4358   int		 ie,
4359 #endif
4360   dk3_app_t	*app
4361 )
4362 {
4363   int back = 0;
4364 #if DK3_CHAR_SIZE > 1
4365   DK3_UNUSED_ARG(ie)
4366 #endif
4367   if((dp) && (sz) && (src)) {
4368 #if DK3_CHAR_SIZE > 1
4369 #if DK3_CHAR_SIZE > 2
4370     back = dk3str_cnv_c32_to_c8p_app(dp, sz, src, app);
4371 #else
4372     back = dk3str_cnv_c16_to_c8p_app(dp, sz, src, app);
4373 #endif
4374 #else
4375     if(ie == DK3_ENCODING_PLAIN) {
4376       if(sz > dk3str_c8_len(src)) {
4377         dk3str_c8_cpy(dp, src);
4378 	back = 1;
4379       }
4380     } else {
4381       back = dk3str_cnv_c8u_to_c8p_app(dp, sz, src, app);
4382     }
4383 #endif
4384   }
4385   return back;
4386 }
4387 
4388 
4389 
4390 int
dk3str_to_c8u_app(char * dp,size_t sz,dkChar const * src,int DK3_ARG_UNUSED (ie),dk3_app_t * app)4391 dk3str_to_c8u_app(
4392   char		*dp,
4393   size_t	 sz,
4394   dkChar const	*src,
4395 #if DK3_CHAR_SIZE > 1
4396   int		 DK3_ARG_UNUSED(ie),
4397 #else
4398   int		 ie,
4399 #endif
4400   dk3_app_t	*app
4401 )
4402 {
4403   int back = 0;
4404 #if DK3_CHAR_SIZE > 1
4405   DK3_UNUSED_ARG(ie)
4406 #endif
4407   if((dp) && (sz) && (src)) {
4408 #if DK3_CHAR_SIZE > 1
4409 #if DK3_CHAR_SIZE > 2
4410     back = dk3str_cnv_c32_to_c8u_app(dp, sz, src, app);
4411 #else
4412     back = dk3str_cnv_c16_to_c8u_app(dp, sz, src, app);
4413 #endif
4414 #else
4415     if(ie == DK3_ENCODING_PLAIN) {
4416       back = dk3str_cnv_c8p_to_c8u_app(dp, sz, src, app);
4417     } else {
4418       if(sz > dk3str_c8_len(src)) {
4419         dk3str_c8_cpy(dp, src);
4420 	back = 1;
4421       }
4422     }
4423 #endif
4424   }
4425   return back;
4426 }
4427 
4428 
4429 
4430 int
dk3str_str_to_c8u_app(char * d,size_t dsz,dkChar const * s,int DK3_ARG_UNUSED (se),dk3_app_t * app)4431 dk3str_str_to_c8u_app(
4432   char		*d,
4433   size_t	 dsz,
4434   dkChar const	*s,
4435 #if DK3_CHAR_SIZE > 1
4436   int		 DK3_ARG_UNUSED(se),
4437 #else
4438   int		 se,
4439 #endif
4440   dk3_app_t	*app
4441 )
4442 {
4443   int		back = 0;
4444 #if DK3_CHAR_SIZE > 1
4445   DK3_UNUSED_ARG(se)
4446 #if DK3_CHAR_SIZE > 2
4447   back = dk3str_cnv_c32_to_c8u_app(d, dsz, s, app);
4448 #else
4449   back = dk3str_cnv_c16_to_c8u_app(d, dsz, s, app);
4450 #endif
4451 #else
4452   switch(se) {
4453     case DK3_ENCODING_UTF8: {
4454       if(dk3str_c8_len(s) < dsz) {
4455         dk3str_c8_cpy(d, s);
4456 	back = 1;
4457       } else {
4458         if(app) {
4459 	  /* ERROR: String too long! */
4460 	  dk3app_log_i1(app, DK3_LL_ERROR, 108);
4461 	}
4462       }
4463     } break;
4464     default: {
4465       back = dk3str_cnv_c8p_to_c8u_app(d, dsz, s, app);
4466     } break;
4467   }
4468 #endif
4469   return back;
4470 }
4471 
4472 
4473 
4474 int
dk3str_c8u_to_str_app(dkChar * d,size_t dsz,int DK3_ARG_UNUSED (de),char const * s,dk3_app_t * app)4475 dk3str_c8u_to_str_app(
4476   dkChar 		*d,
4477   size_t		 dsz,
4478 #if DK3_CHAR_SIZE > 1
4479   int			 DK3_ARG_UNUSED(de),
4480 #else
4481   int			 de,
4482 #endif
4483   char const		*s,
4484   dk3_app_t		*app
4485 )
4486 {
4487   int		 back = 0;
4488 
4489 #if DK3_CHAR_SIZE > 1
4490   DK3_UNUSED_ARG(de)
4491 #endif
4492   if((d) && (dsz) && (s)) {
4493 #if DK3_CHAR_SIZE > 1
4494 #if DK3_CHAR_SIZE > 2
4495 
4496     back = dk3str_cnv_c8u_to_c32_app(d, dsz, s, app);
4497 #else
4498 
4499     back = dk3str_cnv_c8u_to_c16_app(d, dsz, s, app);
4500 #endif
4501 #else
4502     switch(de) {
4503       case DK3_ENCODING_UTF8: {
4504 
4505         if(dsz > dk3str_c8_len(s)) {
4506 	  dk3str_c8_cpy(d, s);
4507 	  back = 1;
4508 	} else {
4509 	  if(app) {
4510 	    /* ERROR: Source string too long! */
4511 	    dk3app_log_i1(app, DK3_LL_ERROR, 108);
4512 	  }
4513 	}
4514       } break;
4515       default: {
4516 
4517         back = dk3str_cnv_c8u_to_c8p_app(d, dsz, s, app);
4518       } break;
4519     }
4520 #endif
4521   }
4522   return back;
4523 }
4524 
4525 
4526 
4527 int
dk3str_to_c8_app(char * dp,size_t szdp,dkChar const * src,dk3_app_t * app)4528 dk3str_to_c8_app(char *dp, size_t szdp, dkChar const *src, dk3_app_t *app)
4529 {
4530   int		 back = 0;
4531 
4532   if((dp) && (szdp) && (src)) {
4533 #if DK3_CHAR_SIZE > 1
4534 #if DK3_CHAR_SIZE > 2
4535     back = dk3str_cnv_c32_to_c8p_app(dp, szdp, src, app);
4536 #else
4537     back = dk3str_cnv_c16_to_c8p_app(dp, szdp, src, app);
4538 #endif
4539 #else
4540     if(strlen(src) < szdp) {
4541       strcpy(dp, src);
4542       back = 1;
4543     } else {
4544       /* ERROR: Destination buffer too small! */
4545       dk3app_log_i1(app, DK3_LL_ERROR, 38);
4546     }
4547 #endif
4548   }
4549   return back;
4550 }
4551 
4552 
4553 
4554 
4555 
4556 
4557 /* vim: set ai sw=2 : */
4558 
4559