summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/c/gu/string.c')
-rw-r--r--src/runtime/c/gu/string.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/runtime/c/gu/string.c b/src/runtime/c/gu/string.c
index b24eeeb06..0af0ce7be 100644
--- a/src/runtime/c/gu/string.c
+++ b/src/runtime/c/gu/string.c
@@ -209,6 +209,109 @@ gu_str_string(const char* str, GuPool* pool)
#endif
}
+bool
+gu_string_to_int(GuString s, int *res)
+{
+ GuWord w = s.w_;
+ uint8_t buf[sizeof(GuWord)];
+ char* src;
+ size_t sz;
+ if (w & 1) {
+ sz = (w & 0xff) >> 1;
+ gu_assert(sz <= sizeof(GuWord));
+ size_t i = sz;
+ while (i > 0) {
+ w >>= 8;
+ buf[--i] = w & 0xff;
+ }
+ src = (char*) buf;
+ } else {
+ uint8_t* p = (void*) w;
+ sz = (p[0] == 0) ? ((size_t*) p)[-1] : p[0];
+ src = (char*) &p[1];
+ }
+
+ size_t i = 0;
+
+ bool neg = false;
+
+ if (src[i] == '-') {
+ neg = true;
+ i++;
+ }
+
+ if (i >= sz)
+ return false;
+
+ int n = 0;
+ for (; i < sz; i++) {
+ if (src[i] < '0' || src[i] > '9')
+ return false;
+
+ n = n * 10 + (src[i] - '0');
+ }
+
+ *res = neg ? -n : n;
+ return true;
+}
+
+bool
+gu_string_to_double(GuString s, double *res)
+{
+ GuWord w = s.w_;
+ uint8_t buf[sizeof(GuWord)];
+ char* src;
+ size_t sz;
+ if (w & 1) {
+ sz = (w & 0xff) >> 1;
+ gu_assert(sz <= sizeof(GuWord));
+ size_t i = sz;
+ while (i > 0) {
+ w >>= 8;
+ buf[--i] = w & 0xff;
+ }
+ src = (char*) buf;
+ } else {
+ uint8_t* p = (void*) w;
+ sz = (p[0] == 0) ? ((size_t*) p)[-1] : p[0];
+ src = (char*) &p[1];
+ }
+
+ size_t i = 0;
+
+ bool neg = false;
+ bool dec = false;
+ int exp = 1;
+
+ if (src[i] == '-') {
+ neg = true;
+ i++;
+ }
+
+ if (i >= sz)
+ return false;
+
+ double d = 0;
+ for (; i < sz; i++) {
+ if (src[i] == '.') {
+ if (dec) return false;
+
+ dec = true;
+ continue;
+ }
+
+ if (src[i] < '0' || src[i] > '9')
+ return false;
+
+ if (dec) exp = exp * 10;
+
+ d = d * 10 + (src[i] - '0');
+ }
+
+ *res = (neg ? -d : d) / exp;
+ return true;
+}
+
GuWord
gu_string_hash(GuString s)
{