summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2012-03-07 16:39:29 +0000
committerkr.angelov <kr.angelov@gmail.com>2012-03-07 16:39:29 +0000
commited5de8335bb1d984918702abff70aadc4d554539 (patch)
tree7e61957d0b103da4409bf39ba55bbe42efc772d2 /src/runtime/c/gu
parent96493c274ba1a02d52f4739f4c222f2b2cbdee54 (diff)
libpgf: implementation for built in literal categories
Diffstat (limited to 'src/runtime/c/gu')
-rw-r--r--src/runtime/c/gu/string.c103
-rw-r--r--src/runtime/c/gu/string.h6
2 files changed, 109 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)
{
diff --git a/src/runtime/c/gu/string.h b/src/runtime/c/gu/string.h
index d6bb11b58..b041518b3 100644
--- a/src/runtime/c/gu/string.h
+++ b/src/runtime/c/gu/string.h
@@ -63,6 +63,12 @@ gu_format_string(GuPool* pool, const char* fmt, ...);
GuString
gu_str_string(const char* str, GuPool* pool);
+bool
+gu_string_to_int(GuString s, int *res);
+
+bool
+gu_string_to_double(GuString s, double *res);
+
#endif // GU_STRING_H_
#if defined(GU_HASH_H_) && !defined(GU_STRING_H_HASH_)