#include "scan.h" /** @file scan.c @author djb @ref qmail, ucspi-tcp @brief scanning/conversion of strings to different variable types */ static long int fromhex(unsigned char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; return -1; } unsigned int scan_0x(const char *s, unsigned int *u) { unsigned int pos = 0; unsigned long result = 0; long int c; while ((c = fromhex((unsigned char)(s[pos]))) >= 0) { result = (result << 4) + c; ++pos; } *u = result; return pos; } unsigned int scan_8long(const char *s, unsigned long *u) { unsigned int pos = 0; unsigned long result = 0; unsigned long c; while ((c = (unsigned long)(unsigned char)(s[pos] - '0')) < 8) { result = result * 8 + c; ++pos; } *u = result; return pos; } unsigned int scan_uint(const char *s, unsigned int *u) { unsigned int pos; unsigned long result; pos = scan_ulong(s, &result); *u = result; return pos; } static unsigned int scan_plusminus(const char *s, int *sign) { if (*s == '+') { *sign = 1; return 1; } if (*s == '-') { *sign = -1; return 1; } *sign = 1; return 0; } unsigned int scan_long(const char *s, long *i) { int sign; unsigned long u; unsigned int len; len = scan_plusminus(s, &sign); s += len; len += scan_ulong(s, &u); if (sign < 0) *i = -u; else *i = u; return len; } unsigned int scan_ulong(const char *s, unsigned long *u) { unsigned int pos = 0; unsigned long result = 0; unsigned long c; while ((c = (unsigned long)(unsigned char)(s[pos] - '0')) < 10) { result = result * 10 + c; ++pos; } *u = result; return pos; } unsigned int scan_xlong(const char *s, unsigned long *u) { const char *t = s; int l = 0; unsigned char c; while ((c = fromhex(*t)) < 16) { l = (l << 4) + c; ++t; } *u = l; return t - s; } unsigned int scan_xint(const char *s, unsigned int *i) { const char *t = s; unsigned int l = 0; unsigned char c; while ((l >> (sizeof(l) * 8 - 4)) == 0 && (c = (unsigned char)fromhex((unsigned char)*t)) < 16) { l = (l << 4) + c; ++t; } *i = l; return (unsigned int)(t - s); }