diff options
Diffstat (limited to 'support/dktools/dk4str8.ctr')
-rw-r--r-- | support/dktools/dk4str8.ctr | 1305 |
1 files changed, 1305 insertions, 0 deletions
diff --git a/support/dktools/dk4str8.ctr b/support/dktools/dk4str8.ctr new file mode 100644 index 0000000000..8b5bcd1fa5 --- /dev/null +++ b/support/dktools/dk4str8.ctr @@ -0,0 +1,1305 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% header + +/** @file + Additional string functions for + 8 bit characters. + + Although some of the functions in this module duplicate + functionality from string.h functions, you should use + the functions from this module. + With DK4DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT defined to non-zero + these functions call Windows API functions like + lstrcmpA() ... instead of CRT functions. +*/ + +#ifndef DK4CONF_H_INCLUDED +#include "dk4conf.h" +#endif + +#ifndef DK4TYPES_H_INCLUDED +#include "dk4types.h" +#endif + +#ifndef DK4ERROR_H_INCLUDED +#include "dk4error.h" +#endif + +#ifndef STDLIB_H_INCLUDED +#include <stdlib.h> +#define STDLIB_H_INCLUDED 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** Copy string, check destination buffer size. + + CRT on Windows: Optional. + @param dst Destination buffer address. + @param sz Destination buffer size. + @param src Source string. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if dst or src is NULL or sz is 0, + - DK4_E_BUFFER_TOO_SMALL<br> + if the dst buffer is too small. +*/ +int +dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp); + +/** Concatenate strings, check destination buffer size. + + CRT on Windows: Optional. + @param dst Destination buffer address. + @param sz Destination buffer size. + @param src Source string. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if dst or src is NULL or sz is 0, + - DK4_E_MATH_OVERFLOW<br> + if a mathematical overflow occured in size calculation, + - DK4_E_BUFFER_TOO_SMALL<br> + if the concatenated string doest not fit into the buffer. +*/ +int +dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp); + +/** Copy characters within a string from right to left. + This copy operation is intended for moving characters within + one string from right to left, making the string shorter + as is. This function does not check buffer size or report + any error. + For normal string copy operations, use the dk4str8_cpy_s() + function instead. + + CRT on Windows: Not used. + @param dst Destination buffer address. + @param src Source string. +*/ +void +dk4str8_cpy_to_left(char *dst, const char *src); + +/** Find string length. + + CRT on Windows: Optional. + @param src Source string. + @return String length. +*/ +size_t +dk4str8_len(const char *src); + +/** Compare two strings. + + CRT on Windows: Optional. + @param s1 Left string, may be NULL. + @param s2 Right string, may be NULL. + @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2. +*/ +int +dk4str8_cmp(const char *s1, const char *s2); + +/** Compare two strings. + + CRT on Windows: Optional, disabling CRT probably degrades performance. + @param s1 Left string, may be NULL. + @param s2 Right string, may be NULL. + @param n Maximum number of characters to compare. + @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2. +*/ +int +dk4str8_ncmp(const char *s1, const char *s2, size_t n); + +/** Compare two strings, case-insensitive comparison. + + CRT on Windows: Optional. + @param s1 Left string, may be NULL. + @param s2 Right string, may be NULL. + @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2. +*/ +int +dk4str8_casecmp(const char *s1, const char *s2); + +/** Compare two file path names. + + CRT on Windows: Optional. + @param s1 Left string, may be NULL. + @param s2 Right string, may be NULL. + @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2. +*/ +int +dk4str8_pathcmp(const char *s1, const char *s2); + +/** Find first occurance of character c in string s. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param s String to search for c. + @param c Character to find. + @return Pointer to first occurance if found, NULL otherwise. +*/ +char * +dk4str8_chr(const char *s, char c); + +/** Find last occurance of character c in string s. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param s String to search for c. + @param c Character to find. + @return Pointer to last occurance if found, NULL otherwise. +*/ +char * +dk4str8_rchr(const char *s, char c); + +/** Retrieve first token from *stringp. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param stringp Adress of string pointer. + @param delim String containing the delimiter set, + my be NULL to use the default delimiter + set (space, tabulator, carriage return and newline). + @return Pointer to first token on success, NULL if no (further) + token found. +*/ +char * +dk4str8_sep(char **stringp, const char *delim); + +/** Find first token in string. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param src String to search for tokens. + @param delim String containing the delimiter characters, + may be NULL to use the default delimiter set. + @return Pointer to first token if found, NULL otherwise. +*/ +char * +dk4str8_start(const char *src, const char *delim); + +/** Cut string after first token, find start of second token in string. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param src String to search for tokens, + normally the result of dk4str8_start() or a + previous dk4str8_next() call. + @param delim String containing the delimiter characters, + may be NULL to use the default delimiter set. + @return Pointer to second token if found, NULL otherwise. +*/ +char * +dk4str8_next(char *src, const char *delim); + +/** Split a string into tokens. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param dpp Pointer to string pointer array. + @param szdpp Size of destination string pointer array. + @param src Source string to process. + @param delim String containing delimiter characters, + may be NULL to use the default delimiter set. + @param erp Error report, may be NULL. + @return Number of tokens found on success, 0 if no token + found or on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + for invalid function arguments, + - DK4_E_BUFFER_TOO_SMALL<br> + with dt.mem.nelem set to the number of tokens in string if the dpp + array is too short. +*/ +size_t +dk4str8_tokenize( + char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp +); + +/** Normalize a string (remove leading and trailing delimiters, + replace delimiter sequences by just one delimiter). + + CRT on Windows: Optional, disabling CRT degrades performance. + @param src Buffer containing the string to normalize. + @param delim String containing delimiter characters, + may be NULL to use the default delimiter set. +*/ +void +dk4str8_normalize(char *src, const char *delim); + +/** Find index of a string in an array of strings. + + CRT on Windows: Optional. + @param arr Array of strings. + @param str String to find in array. + @param cs Flag: Case-sensitive search (0=no, other=yes). + @return Non-negative index value on success, -1 on error. +*/ +int +dk4str8_array_index(const char * const *arr, const char *str, int cs); + +/** Find index of a string in an array of strings. + + CRT on Windows: Optional, disabling CRT degrades performances + and reduces to upper-case conversion to characters 'a' to 'z'. + @param arr Array of string allowing abbreviations. + @param spec Special character indicating start of optional text. + @param str String to find in array. + @param cs Flag: Case-sensitive search (0=no, other=yes). + @return Non-negative index value on success, -1 on error. +*/ +int +dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs); + +/** Check whether a text matches a pattern, the text may be abbreviated. + + CRT on Windows: Optional, disabling CRT degrades performances + and reduces to upper-case conversion to characters 'a' to 'z' + in case-insensitive comparisons. + @param str Text to check. + @param pattern Pattern for comparison. + @param spec Special character marking the abbreviation in the + pattern. + @param cs Flag: Case sensitive (1) or not (0). + @return 1 for a match, 0 otherwise. +*/ +int +dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs); + +/** Check whether a string represents a boolean value. + + CRT on Windows: Optional, disabling CRT degrades performances. + @param str String to check. + @return 1 if str represents a boolean value, 0 otherwise. +*/ +int +dk4str8_is_bool(const char *str); + +/** Check whether a string represents the boolean value TRUE. + + CRT on Windows: Optional, disabling CRT degrades performances. + @param str String to check. + @return 1 if str represents the boolean value TRUE, 0 otherwise. +*/ +int +dk4str8_is_on(const char *str); + +#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \ + || (DK4_HAVE_MALLOC && DK4_HAVE_FREE) + +/** Duplicate string in dynamically allocated memory. + + CRT on Windows: Optional, disabling CRT reduces functionality + to strings with length fitting to int and overall size in + bytes - including finalizer - fitting into a DWORD. + @param src String to duplicate. + @param erp Error report, may be NULL. + @return Pointer to string in new memory on succes, NULL on error. + Use dk4mem_free() to release the memory after usage. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if src is a NULL pointer, + - DK4_E_MATH_OVERFLOW<br> + on mathematical overflow in size calculation, + - DK4_E_MEMORY<br> + if no memory is available. +*/ +char * +dk4str8_dup(const char *src, dk4_er_t *erp); + +#endif +/* if (defined(_WIN32) ... */ + +/** Remove trailing white spaces. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param str String to remove white spaces from. + @param whsp White spaces set. +*/ +void +dk4str8_rtwh(char *str, const char *whsp); + +/** Convert character to uppercase. + + CRT on Windows: Optional, disabling CRT degrades performances + and reduces functionality to characters 'a' to 'z'. + @param c Character to convert. + @return Conversion result. +*/ +char +dk4str8_toupper(char c); + +/** Convert character to lowercase. + + CRT on Windows: Optional, disabling CRT degrades performances + and reduces functionality to characters 'A' to 'Z'. + @param c Character to convert. + @return Conversion result. +*/ +char +dk4str8_tolower(char c); + +/** Remove trailing newline from line. + @param lptr Line pointer. +*/ +void +dk4str8_delnl(char *lptr); + +/** Skip the first text words in a line, return pointer to start + of next word. + @param line Line to process. + @param skip Number of words to skip. + @return Pointer to next word on success, NULL on error. +*/ +const char * +dk4str8_skip(const char *line, size_t skip); + +/** Sanitize string (overwrite using 0 bytes). + @param str Address of string to sanitize. + @return 1 on success, 0 on error. +*/ +int +dk4str8_sanitize(char *str); + +/** Sanitize string buffer (overwrite using 0 bytes). + @param str Address of string buffer. + @param sz Size of string buffer (number of elements). + @return 1 on success, 0 on error. +*/ +int +dk4str8_buffer_sanitize(char *str, size_t sz); + +/** Sanitize dynamically allocated memory and release it. + @param str Address of string to sanitize and release. + @return 1 on success, 0 on error. +*/ +int +dk4str8_free_sanitized(char *str); + +#ifdef __cplusplus +} +#endif + + +/** Sanitize string and release it, set pointer to NULL. + @param p Pointer to string to release. +*/ +#define dk4str8_release_sanitized(p) \ +do { if (NULL != p) { (void)dk4str8_free_sanitized(p); } p = NULL; } while (0) + + +%% module + +#include "dk4conf.h" + +#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) +#ifndef WINDOWS_H_INCLUDED +#include <windows.h> +#define WINDOWS_H_INCLUDED 1 +#endif +#endif + +#include "dk4str8.h" + +#if DK4_HAVE_STRING_H +#ifndef STRING_H_INCLUDED +#include <string.h> +#define STRING_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_CTYPE_H +#ifndef CTYPE_H_INCLUDED +#include <ctype.h> +#define CTYPE_H_INCLUDED 1 +#endif +#endif + +#ifndef DK4NUMCO_H_INCLUDED +#include "dk4numco.h" +#endif + +#ifndef DK4MEM_H_INCLUDED +#include "dk4mem.h" +#endif + +#ifndef DK4MEMRS_H_INCLUDED +#include "dk4memrs.h" +#endif + + +$!trace-include + + + +/** Constant strings used in the module. +*/ +static const char * const dk4str8_modkw[] = { +$!string-table +# +# 0 Default delimiters. +# + \t\r\n +$!end +}; + + + +/** First index of a keyword indicating true in the + dk4str8_boolkw array below. +*/ +#define DK4STR8_FIRST_TRUE 5 + +/** Keywords for boolean values. +*/ +static const char * const dk4str8_boolkw[] = { +$!string-table +# +# 0...4 false +# +- +0 +n$o +of$f +f$alse +# +# 5... true +# ++ +1 +y$es +on +t$rue +ok +$!end +}; + + + +/** Number of significant digits. +*/ +static const int dk4str8_dbl_digits = DK4_DBL_DIGITS; + + +void +dk4str8_cpy_to_left(char *dst, const char *src) +{ + register char *dptr; + register const char *sptr; + if (NULL != dst) { + *dst = '\0'; + if (NULL != src) { + dptr = dst; sptr = src; + while('\0' != *sptr) { *(dptr++) = *(sptr++); } + *dptr = '\0'; + } + } +} + + + +size_t +dk4str8_len(const char *src) +{ + if (NULL == src) { + return 0; + } +#if DK4_ON_WINDOWS + /* +++ Windows */ +#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT + return ((size_t)lstrlenA(src)); +#else + return (strlen(src)); +#endif + /* --- Windows */ +#else + /* +++ non-Windows */ + return (strlen(src)); + /* --- non-Windows */ +#endif +} + + + +char +dk4str8_toupper(char c) +{ +#if DK4_ON_WINDOWS +#if DK4_WIN_DENY_CRT + char back; + back = c; + if (('a' <= c) && ('z' >= c)) { + back = 'A' + (c - 'a'); + } + return back; +#else + return (char)toupper((unsigned char)c); +#endif +#else + return (char)toupper((unsigned char)c); +#endif +} + + + +char +dk4str8_tolower(char c) +{ +#if DK4_ON_WINDOWS +#if DK4_WIN_DENY_CRT + char back; + back = c; + if (('A' <= c) && ('Z' >= c)) { + back = 'a' + (c - 'A'); + } + return back; +#else + return (char)tolower((unsigned char)c); +#endif +#else + return (char)tolower((unsigned char)c); +#endif +} + + + +char * +dk4str8_chr(const char *s, char c) +{ + if (NULL == s) { return NULL; } +#if DK4_ON_WINDOWS + /* +++ Windows */ +#if DK4_WIN_DENY_CRT + { + char *back = NULL; + while (('\0' != *s) && (NULL == back)) { + if (c == *s) { + back = (char *)s; + } else { + s++; + } + } + return back; + } +#else + return (strchr(s, (int)((unsigned char)c))); +#endif + /* --- Windows */ +#else + /* +++ non-Windows */ + return (strchr(s, (int)((unsigned char)c))); + /* --- non-Windows */ +#endif +} + + + +char * +dk4str8_rchr(const char *s, char c) +{ + if (NULL == s) { return NULL; } +#if DK4_ON_WINDOWS +#if DK4_WIN_DENY_CRT + { + char *back = NULL; + while ('\0' != *s) { + if (c == *s) { + back = (char *)s; + } + s++; + } + return back; + } +#else + return (strrchr(s, (int)((unsigned char)c))); +#endif +#else + return (strrchr(s, (int)((unsigned char)c))); +#endif +} + + + +int +dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp) +{ + int back = 0; + if ((NULL != dst) && (0 < sz)) { + *dst = '\0'; + if (NULL != src) { + if (dk4str8_len(src) < sz) { +#if DK4_ON_WINDOWS + /* +++ Windows */ +#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT + (void)lstrcpyA(dst, (char *)src); +#else +#pragma warning (disable:4996) + (void)strcpy(dst, src); +#pragma warning (default:4996) +#endif + /* --- Windows */ +#else + /* +++ non-Windows */ + (void)strcpy(dst, src); + /* --- non-Windows */ +#endif + back = 1; + } else { + *dst = '\0'; + dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp) +{ + size_t la; + size_t lb; + int back = 0; + if ((NULL != dst) && (0 < sz) && (NULL != src)) { + la = dk4str8_len(dst); + lb = dk4str8_len(src); + if ((SIZE_MAX - la) >= lb) { + if ((la + lb) < sz) { +#if DK4_ON_WINDOWS + /* +++ Windows */ +#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT + (void)lstrcatA(dst, (char *)src); +#else +#pragma warning (disable:4996) + (void)strcat(dst, src); +#pragma warning (default:4996) +#endif + /* --- Windows */ +#else + /* +++ non-Windows */ + (void)strcat(dst, src); + /* --- non-Windows */ +#endif + back = 1; + } else { + dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +int +dk4str8_cmp(const char *s1, const char *s2) +{ + int back = 0; + if (NULL != s1) { + if (NULL != s2) { +#if DK4_ON_WINDOWS + /* +++ Windows */ +#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT + back = lstrcmpA(s1, s2); +#else + back = strcmp(s1, s2); +#endif + /* --- Windows */ +#else + /* +++ non-Windows */ + back = strcmp(s1, s2); + /* --- non-Windows */ +#endif + if (0 > back) back = -1; + if (0 < back) back = 1; + } else { + back = 1; + } + } else { + if (NULL != s2) { + back = -1; + } + } + return back; +} + + + +int +dk4str8_ncmp(const char *s1, const char *s2, size_t n) +{ + int back = 0; + if (NULL != s1) { + if (NULL != s2) { +#if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \ +|| (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP)) + while((0 < n--) && (0 == back)) { + if ('\0' == *s1) { + if ('\0' == *s2) { + n = 0; + } else { + back = -1; + } + } else { + if ('\0' == *s2) { + back = 1; + } else { + if (*s1 > *s2) { + back = 1; + } else { + if (*s1 < *s2) { + back = -1; + } else { + s1++; s2++; + } + } + } + } + } +#else + back = strncmp(s1, s2, n); + if (-1 > back) back = -1; + if ( 1 < back) back = 1; +#endif + } else { + back = 1; + } + } else { + if (NULL != s2) { + back = -1; + } + } + return back; +} + + + +int +dk4str8_casecmp(const char *s1, const char *s2) +{ + int back = 0; + if (NULL != s1) { + if (NULL != s2) { +#if DK4_ON_WINDOWS + /* +++ Windows */ +#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT + back = lstrcmpiA(s1, s2); +#else + back = _stricmp(s1, s2); +#endif + /* --- non-Windows */ +#else + /* +++ non-Windows */ +#if DK4_HAVE_STRCASECMP + back = strcasecmp(s1, s2); +#else +#if DK4_HAVE__STRICMP + back = _stricmp(s1, s2); +#else +#if DK4_HAVE_STRICMP + back = stricmp(s1, s2); +#else +#error No function for case-insensitive comparison available! +#endif +#endif +#endif + /* --- non-Windows */ +#endif + if (0 > back) back = -1; + if (0 < back) back = 1; + } else { + back = 1; + } + } else { + if (NULL != s2) { + back = -1; + } + } + return back; +} + + + +#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \ + || (DK4_HAVE_MALLOC && DK4_HAVE_FREE) + +char * +dk4str8_dup(const char *src, dk4_er_t *erp) +{ + char *back = NULL; + size_t lgt; + if (NULL != src) { + lgt = dk4str8_len(src); + if (SIZE_MAX > lgt) { + back = dk4mem_malloc_bytes((1+lgt), erp); + if (NULL != back) { + (void)dk4str8_cpy_s(back, (1+lgt), src, erp); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + +#endif +/* if (defined(_WIN32) ... */ + + + +char * +dk4str8_start(const char *src, const char *delim) +{ + char *back = NULL; + if (NULL != src) { + if (NULL == delim) { delim = dk4str8_modkw[0]; } + while (('\0' != *src) && (NULL == back)) { + if (NULL != dk4str8_chr(delim, (unsigned char)(*src))) { + src++; + } else { + back = (char *)src; + } + } + } + return back; +} + + + +/** Internal function for next token search. + + CRT on Windows: Optional, disabling CRT degrades performance. + @param src String containing tokens, must be set to + the start of a token. + @param delim Delimiter set. + @return Pointer to next token on success, NULL on error. +*/ +static +char * +dk4str8_i_next(char *src, const char *delim) +{ + char *back = NULL; + if (NULL != src) { + if (NULL == delim) { delim = dk4str8_modkw[0]; } + while (('\0' != *src) && (NULL == back)) { + if (NULL != dk4str8_chr(delim, (unsigned char)(*src))) { + back = src; + } else { + src++; + } + } + if (NULL != back) { + *(back++) = '\0'; + back = dk4str8_start(back, delim); + } + } + return back; +} + + + +char * +dk4str8_next(char *src, const char *delim) +{ + char *back = NULL; + if (NULL != src) { + back = dk4str8_start(src, delim); + if (NULL != back) { + back = dk4str8_i_next(back, delim); + } + } + return back; +} + + + +char * +dk4str8_sep(char **stringp, const char *delim) +{ + char *back = NULL; + $? "+ dk4str8_sep \"%!8s\" \"%!8s\"", TR_8STR(*stringp), TR_8STR(delim) + if (NULL != stringp) { + if (NULL != *stringp) { + if (NULL == delim) { delim = dk4str8_modkw[0]; } + back = dk4str8_start(*stringp, delim); + if (NULL != back) { + *stringp = dk4str8_next(back, delim); + } else { + *stringp = NULL; + } + } + } $? "- dk4str8_sep \"%!8s\"", TR_8STR(back) + return back; +} + + + +size_t +dk4str8_tokenize( + char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp +) +{ + char *context; + char *token; + size_t back = 0; + if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) { + if (NULL == delim) { delim = dk4str8_modkw[0]; } + context = src; + while (NULL != (token = dk4str8_sep(&context, delim))) { + if (back < szdpp) { + dpp[back] = token; + } + back++; + } + if (back >= szdpp) { + dk4error_set_elsize_nelem( + erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back + ); + back = 0; + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; +} + + + +void +dk4str8_normalize(char *src, const char *delim) +{ + char *p1; /* Pointer to traverse text. */ + char *p2; /* Start of next token. */ + int cc; /* Flag: Can continue. */ + + if (NULL != src) { + /* + Set up delimiter set, correct if necessary. + */ + if (NULL == delim) { delim = dk4str8_modkw[0]; } + /* + Remove leading delimiters. + */ + p1 = src; + cc = 0; + if ('\0' != *p1) { + if (NULL != dk4str8_chr(delim, (unsigned char)(*p1))) { + p2 = dk4str8_start(p1, delim); + if (NULL != p2) { + dk4str8_cpy_to_left(p1, p2); + cc = 1; + } else { + *p1 = '\0'; + } + } else { + cc = 1; + } + } + /* + Now traverse the string. + */ + while (0 != cc) { + if ('\0' == *p1) { + cc = 0; + } else { + if (NULL != dk4str8_chr(delim, (unsigned char)(*p1))) { + *p1 = *delim; + if ('\0' == p1[1]) { + *p1 = '\0'; + cc = 0; + } else { + if (NULL != dk4str8_chr(delim, (unsigned char)(p1[1]))) { + p2 = dk4str8_start(p1, delim); + if (NULL != p2) { + dk4str8_cpy_to_left(++p1, p2); + } else { + *p1 = '\0'; + cc = 0; + } + } else { + p1++; + } + } + } else { + p1++; + } + } + } + } +} + + + +int +dk4str8_array_index(const char * const *arr, const char *str, int cs) +{ + int back = -1; + int cand = 0; + if ((NULL != arr) && (NULL != str)) { + while((NULL != *arr) && (-1 == back)) { + if (0 != cs) { + if (0 == dk4str8_cmp(*arr, str)) { back = cand; } + } else { + if (0 == dk4str8_casecmp(*arr, str)) { back = cand; } + } + arr++; cand++; + } + } + return back; +} + + + +int +dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs) +{ + const char *lptr = NULL; /* Pointer to traverse string */ + const char *pptr = NULL; /* Pointer to traverse pattern */ + int back = 0; /* Function result */ + int fspec = 0; /* Flag: spec was found */ + int cc = 1; /* Flag: Can continue */ + char cl; + char cp; + $? "+ dk4str8_is_abbr \"%!8s\" \"%!8s\" \"%!8c\"", pattern, str, spec + if ((NULL != str) && (NULL != pattern)) { + lptr = str; pptr = pattern; + while (0 != cc) { + if ((0 == fspec) && (*pptr == spec)) { + fspec = 1; + pptr++; + } else { + if ('\0' != *lptr) { + cl = *lptr; cp = *pptr; + if (0 == cs) { + cl = dk4str8_toupper(cl); + cp = dk4str8_toupper(cp); + } + if (cl == cp) { + lptr++; + pptr++; + } else { + cc = 0; + } + } else { + cc = 0; + if (('\0' == *pptr) || (0 != fspec)) { back = 1; } + } + } + } + } $? "- dk4str8_is_abbr %d", back + return back; +} + + + +int +dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs) +{ + int back = -1; + int cand = 0; + $? "+ dk4str8_abbr_index" + if ((NULL != arr) && (NULL != str)) { + while ((NULL != *arr) && (-1 == back)) { + if (0 != dk4str8_is_abbr(str, *arr, spec, cs)) { + back = cand; + } + arr++; cand++; + } + } + $? "- dk4str8_abbr_index %d", back + return back; +} + + + +int +dk4str8_is_bool(const char *str) +{ + int back = 0; + if (NULL != str) { + if (-1 < dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0)) { + back = 1; + } + } + return back; +} + + + +int +dk4str8_is_on(const char *str) +{ + int back = 0; + $? "+ dk4str8_is_on" + if (NULL != str) { + back = dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0); + if (-1 < back) { + if (DK4STR8_FIRST_TRUE <= back) { + back = 1; + } else { + back = 0; + } + } else { + back = 0; + } + } + $? "- dk4str8_is_on %d", back + return back; +} + + + +int +dk4str8_pathcmp(const char *s1, const char *s2) +{ +#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES + return (dk4str8_casecmp(s1, s2)); +#else + return (dk4str8_cmp(s1, s2)); +#endif +} + + + +void +dk4str8_rtwh(char *str, const char *whsp) +{ + char *ptr = NULL; + if (NULL == whsp) { whsp = dk4str8_modkw[0]; } + if (NULL != str) { + while ('\0' != *str) { + if (NULL != dk4str8_chr(whsp, *str)) { + if (NULL == ptr) { ptr = str; } + } else { + ptr = NULL; + } + str++; + } + if (NULL != ptr) { *ptr = '\0'; } + } +} + + + +void +dk4str8_delnl(char *lptr) +{ + if (NULL != lptr) { + while ('\0' != *lptr) { + if ('\n' == *lptr) { + *lptr = '\0'; + } else { + if ('\r' == *lptr) { + if ('\n' == lptr[1]) { + *lptr = '\0'; + } else { + if ('\0' == lptr[1]) { + *lptr = '\0'; + } else { + lptr++; + } + } + } else { + lptr++; + } + } + } + } +} + + + +const char * +dk4str8_skip(const char *line, size_t skip) +{ + const char *back = NULL; + size_t words = 0; /* Number of words already found */ + int lwt = 0; /* Flag: Last char was text */ + + if (NULL != line) { + if (0 < skip) { + while((NULL == back) && ('\0' != *line)) { + switch (*line) { + case ' ': case '\t': case '\n': case '\r': { + lwt = 0; + } break; + default: { + if (0 == lwt) { + if (++words > skip) { + back = line; + } + } + lwt = 1; + } break; + } + line++; + } + } else { + back = dk4str8_start(line, NULL); + } + } + return back; +} + + + +int +dk4str8_buffer_sanitize(char *str, size_t sz) +{ + int back = 0; + if (NULL != str) { + if (0 < sz) { + back = dk4mem_reset_secure(str, sz, NULL); + } else { + back = 1; + } + } + return back; +} + + + +int +dk4str8_sanitize(char *str) +{ + int back = 0; + if (NULL != str) { + back = dk4str8_buffer_sanitize(str, strlen(str)); + } + return back; +} + + + +int +dk4str8_free_sanitized(char *str) +{ + int back = 0; + if (NULL != str) { + back = dk4str8_sanitize(str); + dk4mem_free(str); + } + return back; +} + |