aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-12-05 16:53:55 -0800
committerNicholas Noll <nbnoll@eml.cc>2021-12-05 17:04:55 -0800
commitf4aef385bdd41b02ef58b5366fa9318ecdc6e37e (patch)
tree72642760a08f8c4d81dc8e13b57c0b6081e48c76
parentb4cb7c06f94e2e91b22b7d82efd7943a82331d86 (diff)
Chore: updated fs·walk to use new data structures
Completes the port to our standard library (up to malloc).
-rw-r--r--include/base/string.h2
-rw-r--r--src/base/string/raw/asint.c86
2 files changed, 87 insertions, 1 deletions
diff --git a/include/base/string.h b/include/base/string.h
index a59c553..20bf21b 100644
--- a/include/base/string.h
+++ b/include/base/string.h
@@ -35,7 +35,7 @@ double str·atof(char *s);
char *str·itoa(char *s, int x);
/* nicer */
-vlong str·asint(char *s, char **end);
+long str·asint(char *s, char **end, int base);
double str·asfloat(char *s, char **end);
/* augmented string functions */
diff --git a/src/base/string/raw/asint.c b/src/base/string/raw/asint.c
new file mode 100644
index 0000000..6751146
--- /dev/null
+++ b/src/base/string/raw/asint.c
@@ -0,0 +1,86 @@
+#include <u.h>
+#include <base.h>
+
+long
+str·asint(char *s, char **end, int base)
+{
+ char *p;
+ vlong n, nn, m;
+ int c, ovfl, v, neg, ndig;
+
+ p = s;
+ neg = 0;
+ n = 0;
+ ndig = 0;
+ ovfl = 0;
+
+ /* White space */
+ for(;; p++){
+ switch(*p){
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f':
+ case '\r':
+ case '\v':
+ continue;
+ }
+ break;
+ }
+
+ /* Sign */
+ if(*p=='-' || *p=='+')
+ if(*p++ == '-')
+ neg = 1;
+
+ /* Base */
+ if(base==0){
+ base=10;
+ if(*p == '0'){
+ base = 8;
+ if(p[1]=='x'||p[1]=='X'){
+ p += 2;
+ base = 16;
+ }
+ }
+ }else if(base==16 && *p=='0'){
+ if(p[1]=='x' || p[1]=='X')
+ p += 2;
+ }else if(base<0 || 36<base)
+ goto Return;
+
+ /* Non-empty sequence of digits */
+ m = LONG_MAX/base;
+ for(;; p++,ndig++){
+ c = *p;
+ v = base;
+ if('0'<=c && c<='9')
+ v = c - '0';
+ else if('a'<=c && c<='z')
+ v = c - 'a' + 10;
+ else if('A'<=c && c<='Z')
+ v = c - 'A' + 10;
+ if(v >= base)
+ break;
+ if(n > m)
+ ovfl = 1;
+ nn = n*base + v;
+ if(nn < n)
+ ovfl = 1;
+ n = nn;
+ }
+
+Return:
+ if(ndig == 0)
+ p = s;
+ if(end)
+ *end = p;
+ if(ovfl){
+ if(neg)
+ return LONG_MIN;
+ return LONG_MAX;
+ }
+ if(neg)
+ return -n;
+ return n;
+}