%% options copyright owner = Dirk Krause copyright year = 2014-xxxx license = bsd %% header /** @file dk3masts.h Retrieve size_t from dkChar text. */ #ifdef __cplusplus extern "C" { #endif /** Convert string to size_t. The string can optionally contain an ``k'', ``K'', ``m'', ``M'', ``g'', or ``G'' suffix. @param rp Pointer to result variable. @param src Source text to convert. @param ec Pointer to error code variable, may be NULL. Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL or the string is too long for the internal buffer, DK3_ERROR_SYNTAX if unacceptable characters found, DK3_ERROR_MATH_OVERFLOW on numeric overflow. @return 1 on success, 0 on error (see ec). */ int dk3ma_sz_from_string(size_t *rp, dkChar const *src, int *ec); #ifdef __cplusplus } #endif %% module #include "dk3ma.h" #include #include "dk3mem.h" #include "dk3str.h" $!trace-include int dk3ma_sz_from_string(size_t *rp, dkChar const *src, int *ec) { /* Private copy of string, can be modified. */ dkChar buffer[DK3_MEM_ALIGN((8*sizeof(dk3_um_t)+1),16)]; dkChar const *ptr; /* Start of original text */ size_t lgt; /* Length of text in buffer */ dk3_um_t convres = (dk3_um_t)1; /* Conversion result */ dk3_um_t factor = (dk3_um_t)1; /* Constant factor */ int myec = 0; /* Private error code */ int back = 0; /* Function result */ int done = 0; /* Flag: No conversion necessary */ $? "+ dk3ma_sz_from_string %!ds", TR_STR(src) if ((NULL != rp) && (NULL != src)) { ptr = dk3str_start(src, NULL); if (NULL != ptr) { if (dk3str_len(ptr) < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy(buffer, ptr); dk3str_chomp(buffer, NULL); lgt = dk3str_len(buffer); if (0 < lgt) { switch(buffer[lgt-1]) { case dkT('k'): case dkT('K'): { factor = (dk3_um_t)1024; buffer[lgt-1] = dkT('\0'); if (1 == lgt) { done = 1; } } break; case dkT('m'): case dkT('M'): { factor = dk3ma_um_mul_ok((dk3_um_t)1024, (dk3_um_t)1024, &myec); buffer[lgt-1] = dkT('\0'); if (1 == lgt) { done = 1; } } break; case dkT('g'): case dkT('G'): { factor = dk3ma_um_mul_ok( dk3ma_um_mul_ok((dk3_um_t)1024, (dk3_um_t)1024, &myec), (dk3_um_t)1024, &myec ); buffer[lgt-1] = dkT('\0'); if (1 == lgt) { done = 1; } } break; } if (0 == myec) { if (0 == done) { $? ". must scan" if (0 != dk3ma_um_from_string(&convres, buffer, ec)) { $? ". scan ok" convres = dk3ma_um_mul_ok(convres, factor, &myec); if ((dk3_um_t)DK3_SIZE_T_MAX >= convres) { *rp = (size_t)convres; back = 1; #if DK3_ON_WINDOWS $? ". size = %I64u", convres #else $? ". size = %ju", (uintmax_t)convres #endif } else { $? "! overflow" if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } else { $? "! failed to scan" } } else { $? ". simply unit, no number" convres = dk3ma_um_mul_ok(convres, factor, &myec); if ((dk3_um_t)DK3_SIZE_T_MAX >= convres) { *rp = (size_t)convres; back = 1; $? ". success" #if DK3_ON_WINDOWS $? ". size = %I64u", convres #else $? ". size = %ju", (uintmax_t)convres #endif } else { $? "! overflow" if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } } } if (1 == back) { if (0 != myec) { $? "! internal error" back = 0; if (NULL != ec) { *ec = myec; } } } } else { $? "! myec set" if (NULL != ec) { *ec = myec; } } } else { $? "! empty string" if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; } } } else { $? "! string too long" if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; } } } else { $? "! empty string" if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; } } } else { $? "! invalid arguments" if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; } } $? "- dk3ma_sz_from_string %d", back return back; }