summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c100
1 files changed, 50 insertions, 50 deletions
diff --git a/util.c b/util.c
index 74f2d11b94..4caa324849 100644
--- a/util.c
+++ b/util.c
@@ -13,6 +13,10 @@
# define MINGW_HAS_SECURE_API 1
#endif
+#ifndef __STDC_WANT_LIB_EXT1__
+#define __STDC_WANT_LIB_EXT1__ 1 /* for qsort_s() */
+#endif
+
#include "ruby/internal/config.h"
#include <ctype.h>
@@ -27,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"
@@ -37,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[] = {
@@ -203,22 +187,15 @@ ruby_strtoul(const char *str, char **endptr, int base)
}
}
+#if !defined HAVE_GNU_QSORT_R
#include <sys/types.h>
-#include <sys/stat.h>
+#include <stdint.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#if defined(HAVE_FCNTL_H)
-#include <fcntl.h>
-#endif
-
-#ifndef S_ISDIR
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
typedef int (cmpfunc_t)(const void*, const void*, void*);
-#if !defined HAVE_GNU_QSORT_R
#if defined HAVE_QSORT_S && defined RUBY_MSVCRT_VERSION
/* In contrast to its name, Visual Studio qsort_s is incompatible with
* C11 in the order of the comparison function's arguments, and same
@@ -546,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)) {
@@ -588,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)
{