%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% header /** @file Retrieve dk4_um_t value from wchar_t string in hexadecimal notation. CRT on Windows: Optional, disabling CRT degrades performance. */ #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4TYPES_H_INCLUDED #include "dk4types.h" #endif #ifndef DK4ERROR_H_INCLUDED #include "dk4error.h" #endif #ifdef __cplusplus extern "C" { #endif /** Retrieve numeric value from string, hexadecimal notation. @param rp Pointer to result variable for the found value. @param src String to check for numeric value. @param endptr Address of pointer variable. A pointer to the first character not processed is stored here. The function may also store a NULL pointer in this variable. @param atg Allow trailing garbage: 0=no unprocessable trailing bytes allowed, 1=trailing whitespaces allowed, 2=any trailing characters allowed. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: DK4_E_INVALID_ARGUMENTS if rp or src is NULL, DK4_E_MATH_OVERFLOW if the number is out of range, or DK4_E_SYNTAX if src contains illegal characters. */ int dk4ma_input_wc_hex_dk4_um_t( dk4_um_t *rp, const wchar_t *src, const wchar_t **endptr, int atg, dk4_er_t *erp ); #ifdef __cplusplus } #endif %% module #include "dk4maiwhdu.h" #include "dk4numco.h" #include "dk4strw.h" $!trace-include /* UNTESTED */ int dk4ma_input_wc_hex_dk4_um_t( dk4_um_t *rp, const wchar_t *src, const wchar_t **endptr, int atg, dk4_er_t *erp ) { dk4_um_t result = (dk4_um_t)0UL; dk4_um_t op; const wchar_t *ep = NULL; int found = 0; int back = 0; int cc = 1; $? "+ dk4ma_input_wc_hex_dk4_um_t" if ((NULL != rp) && (NULL != src)) { if (L'0' == src[0]) { if ((L'x' == src[1]) || (L'X' == src[1])) { src++; src++; } } do { op = (dk4_um_t)0UL; #if DK4_SIZEOF_WCHAR_T <= DK4_SIZEOF_INT switch (*src) { case L'0': { op = (dk4_um_t)0UL; } break; case L'1': { op = (dk4_um_t)1UL; } break; case L'2': { op = (dk4_um_t)2UL; } break; case L'3': { op = (dk4_um_t)3UL; } break; case L'4': { op = (dk4_um_t)4UL; } break; case L'5': { op = (dk4_um_t)5UL; } break; case L'6': { op = (dk4_um_t)6UL; } break; case L'7': { op = (dk4_um_t)7UL; } break; case L'8': { op = (dk4_um_t)8UL; } break; case L'9': { op = (dk4_um_t)9UL; } break; case L'a': case L'A': { op = (dk4_um_t)10UL; } break; case L'b': case L'B': { op = (dk4_um_t)11UL; } break; case L'c': case L'C': { op = (dk4_um_t)12UL; } break; case L'd': case L'D': { op = (dk4_um_t)13UL; } break; case L'e': case L'E': { op = (dk4_um_t)14UL; } break; case L'f': case L'F': { op = (dk4_um_t)15UL; } break; case L'\0': { $? ". string finished" cc = 0; if (0 != found) { $? ". digits found" back = 1; *rp = result; } else { $? ". no digits found" ep = src; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } break; default: { cc = 0; ep = src; if (0 != found) { switch (atg) { case 2: { back = 1; *rp = result; } break; case 1: { if (NULL == dk4strw_start(src, NULL)) { back = 1; *rp = result; } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } break; default: { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } break; } #else if (L'0' == *src) { op = (dk4_um_t)0UL; } else { if (L'1' == *src) { op = (dk4_um_t)1UL; } else { if (L'2' == *src) { op = (dk4_um_t)2UL; } else { if (L'3' == *src) { op = (dk4_um_t)3UL; } else { if (L'4' == *src) { op = (dk4_um_t)4UL; } else { if (L'5' == *src) { op = (dk4_um_t)5UL; } else { if (L'6' == *src) { op = (dk4_um_t)6UL; } else { if (L'7' == *src) { op = (dk4_um_t)7UL; } else { if (L'8' == *src) { op = (dk4_um_t)8UL; } else { if (L'9' == *src) { op = (dk4_um_t)9UL; } else { if ((L'A' == *src) || (L'a' == *src)) { op = (dk4_um_t)10UL; } else { if ((L'B' == *src) || (L'b' == *src)) { op = (dk4_um_t)11UL; } else { if ((L'C' == *src) || (L'c' == *src)) { op = (dk4_um_t)12UL; } else { if ((L'D' == *src) || (L'd' == *src)) { op = (dk4_um_t)13UL; } else { if ((L'E' == *src) || (L'e' == *src)) { op = (dk4_um_t)14UL; } else { if ((L'F' == *src) || (L'f' == *src)) { op = (dk4_um_t)15UL; } else { if (L'\0' == *src) { /* finalizer */ cc = 0; if (0 != found) { back = 1; *rp = result; } else { ep = src; dk4error_set_simple_error_code( erp, DK4_E_SYNTAX ); } } else { /* any other */ cc = 0; ep = src; if (0 != found) { switch (atg) { case 2: { back = 1; *rp = result; } break; case 1: { if (dk4strw_start(src, NULL)) { dk4error_set_simple_error_code( erp, DK4_E_SYNTAX ); } else { back = 1; *rp = result; } } break; default: { dk4error_set_simple_error_code( erp, DK4_E_SYNTAX ); } break; } } else { dk4error_set_simple_error_code( erp, DK4_E_SYNTAX ); } } } } } } } } } } } } } } } } } } #endif /* after switch */ if (0 != cc) { found = 1; if ((DK4_UM_MAX / (dk4_um_t)16UL) >= result) { result *= (dk4_um_t)16UL; if ((DK4_UM_MAX - op) >= result) { result += op; } else { cc = 0; ep = src; dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } else { cc = 0; ep = src; dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } if (0 != cc) { src++; } } while (0 != cc); } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); if (NULL != src) { ep = src; } } if (NULL != endptr) { *endptr = ep; } $? "- dk4ma_input_wc_hex_dk4_um_t %d", back return back; }