Mon 16 Mar 11:09:06 CET 2026
This commit is contained in:
parent
80e8557dd9
commit
8b6cb530fe
202
src/parsef.c
Normal file
202
src/parsef.c
Normal file
|
|
@ -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; }
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user