summaryrefslogtreecommitdiff
path: root/src/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scan.c')
-rw-r--r--src/scan.c120
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);
+}