diff options
Diffstat (limited to 'src/scan.c')
-rw-r--r-- | src/scan.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/scan.c b/src/scan.c new file mode 100644 index 0000000..597e76c --- /dev/null +++ b/src/scan.c @@ -0,0 +1,120 @@ +#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; +} + +unsigned int scan_plusminus(const char *s,register 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,register 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); +} |