summaryrefslogtreecommitdiffhomepage
path: root/src/readint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/readint.c')
-rw-r--r--src/readint.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/readint.c b/src/readint.c
new file mode 100644
index 000000000..4478574fd
--- /dev/null
+++ b/src/readint.c
@@ -0,0 +1,30 @@
+#include <mruby.h>
+#include <mruby/numeric.h>
+#include <errno.h>
+
+/* mrb_int_read(): read mrb_int from a string (base 10 only) */
+/* const char *p - string to read */
+/* const char *e - end of string */
+/* char **endp - end of pased integer */
+
+/* if integer overflows, errno will be set to ERANGE */
+/* also endp will be set to NULL on overflow */
+MRB_API mrb_int
+mrb_int_read(const char *p, const char *e, char **endp)
+{
+ mrb_int n = 0;
+ int ch;
+
+ while ((e == NULL || p < e) && ISDIGIT(*p)) {
+ ch = *p - '0';
+ if (mrb_int_mul_overflow(n, 10, &n) ||
+ mrb_int_add_overflow(n, ch, &n)) {
+ if (endp) *endp = NULL;
+ errno = ERANGE;
+ return MRB_INT_MAX;
+ }
+ p++;
+ }
+ if (endp) *endp = (char*)p;
+ return n;
+}