summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c85
1 files changed, 44 insertions, 41 deletions
diff --git a/util.c b/util.c
index 3c08879ce5..4caa324849 100644
--- a/util.c
+++ b/util.c
@@ -31,6 +31,7 @@
#include "internal.h"
#include "internal/sanitizers.h"
+#include "internal/imemo.h"
#include "internal/util.h"
#include "ruby/util.h"
#include "ruby_atomic.h"
@@ -41,40 +42,19 @@ const char ruby_hexdigits[] = "0123456789abcdef0123456789ABCDEF";
unsigned long
ruby_scan_oct(const char *start, size_t len, size_t *retlen)
{
- register const char *s = start;
- register unsigned long retval = 0;
- size_t i;
-
- for (i = 0; i < len; i++) {
- if ((s[0] < '0') || ('7' < s[0])) {
- break;
- }
- retval <<= 3;
- retval |= *s++ - '0';
- }
- *retlen = (size_t)(s - start);
- return retval;
+ int overflow;
+ unsigned long val = ruby_scan_digits(start, (ssize_t)len, 8, retlen, &overflow);
+ (void)overflow;
+ return val;
}
unsigned long
ruby_scan_hex(const char *start, size_t len, size_t *retlen)
{
- register const char *s = start;
- register unsigned long retval = 0;
- signed char d;
- size_t i = 0;
-
- for (i = 0; i < len; i++) {
- d = ruby_digit36_to_number_table[(unsigned char)*s];
- if (d < 0 || 15 < d) {
- break;
- }
- retval <<= 4;
- retval |= d;
- s++;
- }
- *retlen = (size_t)(s - start);
- return retval;
+ int overflow;
+ unsigned long val = ruby_scan_digits(start, (ssize_t)len, 16, retlen, &overflow);
+ (void)overflow;
+ return val;
}
const signed char ruby_digit36_to_number_table[] = {
@@ -543,41 +523,63 @@ ruby_strdup(const char *str)
return tmp;
}
+#if defined HAVE_GETCWD
+# if defined NO_GETCWD_MALLOC
+
char *
ruby_getcwd(void)
{
-#if defined HAVE_GETCWD
-# undef RUBY_UNTYPED_DATA_WARNING
-# define RUBY_UNTYPED_DATA_WARNING 0
-# if defined NO_GETCWD_MALLOC
- VALUE guard = Data_Wrap_Struct((VALUE)0, NULL, RUBY_DEFAULT_FREE, NULL);
+ VALUE guard = rb_imemo_tmpbuf_new();
int size = 200;
char *buf = xmalloc(size);
while (!getcwd(buf, size)) {
int e = errno;
if (e != ERANGE) {
- xfree(buf);
- DATA_PTR(guard) = NULL;
+ rb_free_tmp_buffer(&guard);
rb_syserr_fail(e, "getcwd");
}
size *= 2;
- DATA_PTR(guard) = buf;
+ rb_imemo_tmpbuf_set_ptr(guard, buf);
buf = xrealloc(buf, size);
}
+ rb_imemo_tmpbuf_set_ptr(guard, NULL);
+ return buf;
+}
+
# else
- VALUE guard = Data_Wrap_Struct((VALUE)0, NULL, free, NULL);
+
+static const rb_data_type_t getcwd_buffer_guard_type = {
+ .wrap_struct_name = "ruby_getcwd_guard",
+ .function = {
+ .dfree = free // not xfree.
+ },
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
+};
+
+char *
+ruby_getcwd(void)
+{
+ VALUE guard = TypedData_Wrap_Struct((VALUE)0, &getcwd_buffer_guard_type, NULL);
char *buf, *cwd = getcwd(NULL, 0);
- DATA_PTR(guard) = cwd;
+ RTYPEDDATA_DATA(guard) = cwd;
if (!cwd) rb_sys_fail("getcwd");
buf = ruby_strdup(cwd); /* allocate by xmalloc */
free(cwd);
+ RTYPEDDATA_DATA(RB_GC_GUARD(guard)) = NULL;
+ return buf;
+}
+
# endif
- DATA_PTR(RB_GC_GUARD(guard)) = NULL;
#else
+
# ifndef PATH_MAX
# define PATH_MAX 8192
# endif
+
+char *
+ruby_getcwd(void)
+{
char *buf = xmalloc(PATH_MAX+1);
if (!getwd(buf)) {
@@ -585,10 +587,11 @@ ruby_getcwd(void)
xfree(buf);
rb_syserr_fail(e, "getwd");
}
-#endif
return buf;
}
+#endif
+
void
ruby_each_words(const char *str, void (*func)(const char*, int, void*), void *arg)
{