diff options
Diffstat (limited to 'util/nvmutil/lib/string.c')
| -rw-r--r-- | util/nvmutil/lib/string.c | 109 |
1 files changed, 74 insertions, 35 deletions
diff --git a/util/nvmutil/lib/string.c b/util/nvmutil/lib/string.c index b1a5c3e2..ca58fb1c 100644 --- a/util/nvmutil/lib/string.c +++ b/util/nvmutil/lib/string.c @@ -9,67 +9,106 @@ #include <errno.h> #include <stddef.h> +#include <string.h> #include <unistd.h> #include "../include/common.h" -/* Portable strncmp() that blocks - * NULL/empty/unterminated strings +/* scmp() - strict string comparison + * + * strict string comparison + * similar to strncmp, but null and + * unterminated inputs do not produce + * a return value; on error, errno is + * set and -1 is returned. + * + * the real return value is stored in + * the 4th argument by pointer. + * + * the value at rval pointer is set, + * only upon success. callers should + * check the return value accordingly. */ int -xstrxcmp(const char *a, const char *b, unsigned long maxlen) +scmp(const char *a, + const char *b, + size_t maxlen, + int *rval) { - unsigned long i; + size_t ch; + unsigned char ac; + unsigned char bc; - if (a == NULL || b == NULL) - err(EINVAL, "NULL input to xstrxcmp"); + if (a == NULL || + b == NULL || + rval == NULL) { - if (*a == '\0' || *b == '\0') - err(EINVAL, "Empty string in xstrxcmp"); + errno = EFAULT; + return -1; + } - for (i = 0; i < maxlen; i++) { + for (ch = 0; ch < maxlen; ch++) { - unsigned char ac = (unsigned char)a[i]; - unsigned char bc = (unsigned char)b[i]; + ac = (unsigned char)a[ch]; + bc = (unsigned char)b[ch]; - if (ac == '\0' || bc == '\0') { - if (ac == bc) - return 0; - return ac - bc; + if (ac != bc) { + *rval = ac - bc; + return 0; } - if (ac != bc) - return ac - bc; + if (ac == '\0') { + *rval = 0; + return 0; + } } - err(EINVAL, "Unterminated string in xstrxcmp"); - - errno = EINVAL; + /* block unterminated strings */ + errno = EFAULT; return -1; } -/* Portable strncmp() that blocks - * NULL/empty/unterminated strings +/* slen() - strict strict length + * + * strict string length calculation + * similar to strnlen, but null and + * unterminated inputs do not produce + * a return value; on error, errno is + * set and -1 is returned. + * + * the real return value is stored in + * the 3rd argument by pointer. + * + * the value at rval pointer is set, + * only upon success. callers should + * check the return value accordingly. */ -unsigned long -xstrxlen(const char *scmp, unsigned long maxlen) +int +slen(const char *s, + size_t maxlen, + size_t *rval) { - unsigned long xstr_index; + size_t ch; - if (scmp == NULL) - err(EINVAL, "NULL input to xstrxlen"); + if (s == NULL || + rval == NULL) { - if (*scmp == '\0') - err(EINVAL, "Empty string in xstrxlen"); + errno = EFAULT; + return -1; + } - for (xstr_index = 0; - xstr_index < maxlen && scmp[xstr_index] != '\0'; - xstr_index++); + for (ch = 0; + ch < maxlen && s[ch] != '\0'; + ch++); - if (xstr_index == maxlen) - err(EINVAL, "Unterminated string in xstrxlen"); + if (ch == maxlen) { + /* unterminated */ + errno = EFAULT; + return -1; + } - return xstr_index; + *rval = ch; + return 0; } |
