#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); }