From 8b6cb530fe468f18c64be495d7f3bca0fad106f1 Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 16 Mar 2026 11:12:13 +0100 Subject: [PATCH] Mon 16 Mar 11:09:06 CET 2026 --- src/parsef.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 src/parsef.c diff --git a/src/parsef.c b/src/parsef.c new file mode 100644 index 0000000..cfdae08 --- /dev/null +++ b/src/parsef.c @@ -0,0 +1,202 @@ +#include "config.h" +#include "parsef.h" + +// input stream +// Not thread safe TODO +static index_t _stdin=0; + +/* + 1. String Operations +*/ +/* + * reading a positive number from a char buffer + * maximum number of digits is adjusted to 16 + * ugly here, testcode when introducting + * number_t was only 16 bit before + */ +address_t ParseNumber(char *c, number_t *r) { + address_t nd = 0; + *r = 0; + while (*c >= '0' && *c <= '9' && *c != 0) { + *r = *r * 10 + *c++ - '0'; + nd++; + } + return nd; +} + +#if HAS_FLOAT>0 +/* a poor man's atof implementation with character count */ +address_t ParseNumber2(char *c, number_t *r) { + address_t nd = 0; + index_t i; + number_t fraction = 0; + number_t exponent = 0; + mem_t nexp = 0; + + *r = 0; + + /* integer part */ + i = parsenumber(c, r); + c += i; + nd += i; + + /* the fractional part */ + if (*c == '.') { + c++; + nd++; + + i = ParseNumber(c, &fraction); + c += i; + nd += i; + + if (i > 0) { + while ((--i) >= 0) + fraction = fraction / 10; + *r += fraction; + } + } + + /* the exponent */ + if (*c == 'E' || *c == 'e') { + c++; + nd++; + if (*c == '-') { + c++; + nd++; + nexp = 1; + }; + i = ParseNumber(c, &exponent); + nd += i; + while ((--exponent) >= 0) + if (nexp) + *r = *r / 10; + else + *r = *r * 10; + } + + return nd; +} +#endif + +address_t ParseString(char *c, char *r) { + address_t nd = 0; + if (*c=='"') c++; + while (*c != '"') { + *r = *c; + r++; c++; + nd++; + } + *r = 0; + return nd; +} + +/* + 2. Byte Stream Versions, can block (returning 0)! +*/ + +index_t ReadNumber(number_t *r) { + if (!AVAILBYTE(_stdin)) return 0; + char c=INBYTE(_stdin); + address_t nd = 1; + number_t s=1; + *r = 0; + if (c=='-') { + s=-1; + if (!AVAILBYTE(_stdin)) return 0; + c=INBYTE(_stdin); + } + + while (c >= '0' && c <= '9' && c != 0) { + *r = *r * 10 + c - '0'; + nd++; + if (!AVAILBYTE(_stdin)) break; + c=INBYTE(_stdin); + } + if (nd) *r*=s; + return nd; +} + +#if HAS_FLOAT>0 +/* a poor man's atof implementation with character count */ +index_t ReadNumber2(number_t *r) { + if (!AVAILBYTE(_stdin)) return 0; + char c=INBYTE(_stdin); + address_t nd = 1; + index_t i; + number_t fraction = 0; + number_t exponent = 0; + mem_t nexp = 0; + + *r = 0; + + /* integer part */ + i = ReadNumber(r); + if (i<=0) return -1; // error + nd += i; + if (!AVAILBYTE(_stdin)) return 0; + c=INBYTE(_stdin); + /* the fractional part */ + if (c == '.') { + c++; + nd++; + + i = ReadNumber(&fraction); + if (i<=0) return -1; // error + nd += i; + + if (i > 0) { + while ((--i) >= 0) + fraction = fraction / 10; + *r += fraction; + } + } + + /* the exponent */ + if (!AVAILBYTE(_stdin)) return 0; + c=INBYTE(_stdin) + if (c == 'E' || c == 'e') { + if (!AVAILBYTE(_stdin)) return 0; + c=INBYTE(_stdin); + nd++; + if (c == '-') { + c=INBYTE(_stdin); + nd++; + nexp = 1; + }; + i = ReadNumber(&exponent); + if (i<=0) return -1; // error + nd += i; + while ((--exponent) >= 0) + if (nexp) + *r = *r / 10; + else + *r = *r * 10; + } + return nd; +} +#endif +// read string "xxx", returns # of parsed chars, 0 if blocked, or -1 on error +index_t ReadString(char *r) { + if (!AVAILBYTE(_stdin)) return 0; + char c=INBYTE(_stdin); + address_t nd = 0; + if (c=='"') c=INBYTE(_stdin); else return -1; // error + while (c != '"') { + *r = c; + r++; + if (!AVAILBYTE(_stdin)) break; + c=INBYTE(_stdin); + nd++; + } + if (c!='"') return -1; // error + *r = 0; + return nd; +} + + +/* + Set standard input channel (default 1) +*/ +index_t parse_stdin(index_t handle) { index_t old=_stdin; _stdin=handle; return old; } + +