3#include "internal/file.h"
4#include "internal/string.h"
5#include "internal/vm.h"
7#if defined __CYGWIN__ || defined DOSISH
9# define alt_separator 1
10# define isdirsep(x) ((x) == '/' || (x) == '\\')
12# define drive_letter 0
13# define alt_separator 0
14# define isdirsep(x) ((x) == '/')
17static VALUE rb_cPathname;
22check_strpath(
VALUE path)
25 rb_get_path_check_no_convert(path);
36 rb_get_path_check_no_convert(strpath);
76 s1 = get_strpath(self);
77 s2 = get_strpath(other);
80 e1 = p1 + RSTRING_LEN(s1);
81 e2 = p2 + RSTRING_LEN(s2);
82 while (p1 < e1 && p2 < e2) {
84 c1 = (
unsigned char)*p1++;
85 c2 = (
unsigned char)*p2++;
86 if (c1 ==
'/') c1 =
'\0';
87 if (c2 ==
'/') c2 =
'\0';
155 VALUE str = get_strpath(self);
173 return RBOOL(rb_str_casecmp(a, b) ==
INT2FIX(0));
220path_root_p(
VALUE self)
222 VALUE path = get_strpath(self);
223 if (RSTRING_LEN(path) == 0)
return Qfalse;
224 const char *ptr = RSTRING_PTR(path), *end =
RSTRING_END(path);
226 const char *base = rb_enc_path_skip_prefix_root(ptr, end, enc);
227 return RBOOL(base == end);
246path_absolute_p(
VALUE self)
248 VALUE path = get_strpath(self);
249 const char *ptr = RSTRING_PTR(path);
250 long len = RSTRING_LEN(path);
255 return RBOOL(isdirsep(ptr[0]));
262 const char *ptr = RSTRING_PTR(check_strpath(path));
266 bool mb = !rb_str_enc_fastpath(path);
268 if (isdirsep(*ptr))
return Qtrue;
269 ptr += (mb ? rb_enc_mbclen(ptr, end, enc) : 1);
274 if (memchr(ptr,
'/', end - ptr))
return Qtrue;
298 VALUE path = get_strpath(self);
299 long len = RSTRING_LEN(path);
300 const char *ptr = RSTRING_PTR(path);
301 const char *ext = ruby_enc_find_extname(ptr, &
len, rb_enc_get(path));
319 long baselen, alllen = RSTRING_LEN(check_strpath(path));
320 if (alllen <= 0)
return Qnil;
322 const char *name = RSTRING_PTR(path);
323 const char *base = ruby_enc_find_basename(name, &baselen, &alllen, enc);
324 if (baselen < 1)
return Qnil;
325 if (baselen == 1 && isdirsep(*base))
return Qnil;
329 VALUE basename = rb_enc_str_new(base, alllen, enc);
339 rb_encoding *enc = rb_enc_get(check_strpath(path));
340 const char *beg = RSTRING_PTR(path), *ptr = beg;
342 const char *root = rb_enc_path_skip_prefix_root(ptr, end, enc);
346 const char *next = rb_enc_path_next(ptr, end, enc);
349 while (ptr < end && isdirsep(*ptr)) ++ptr;
359 long baselen, alllen = RSTRING_LEN(check_strpath(path));
360 if (alllen <= 0)
return Qfalse;
362 const char *name = RSTRING_PTR(path);
363 const char *base = ruby_enc_find_basename(name, &baselen, &alllen, enc);
364 if (baselen < 1)
return Qfalse;
365 if (baselen == 1 && isdirsep(*base))
return Qfalse;
374 if (RSTRING_LEN(check_strpath(path)) <= 0)
return path;
376 const char *name = RSTRING_PTR(path);
378 const char *top = rb_enc_path_skip_prefix(name, end, enc);
379 if (top < end && isdirsep(end[-1])) {
380 if (end[-1] ==
'/' || rb_enc_prev_char(top, end, end, enc) == end - 1)
390 long len = RSTRING_LEN(check_strpath(path));
391 if (
len <= 0)
return path;
393 const char *name = RSTRING_PTR(path);
394 const char *end = name +
len, *tail = end;
395 const char *top = rb_enc_path_skip_prefix(name, end, enc);
396 if (tail > top && isdirsep(tail[-1])) {
397 while (--tail > top && isdirsep(tail[-1]));
400 !rb_str_enc_fastpath(path) &&
406 if (tail == name || (drive_letter && tail == top && top[-1] ==
':')) {
411 if (tail == end)
return path;
415#include "pathname_builtin.rbinc"
417static void init_ids(
void);
422#ifdef HAVE_RB_EXT_RACTOR_SAFE
433 rb_cPathname = rb_define_class(
"Pathname",
rb_cObject);
455 id_at_path = rb_intern(
"@path");
456 id_sub = rb_intern(
"sub");
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
#define CASEFOLD_FILESYSTEM
Stone age assumption was that an operating system supports only one file system at a moment.
int rb_block_given_p(void)
Determines if the current method is given a block.
#define T_STRING
Old name of RUBY_T_STRING.
#define INT2FIX
Old name of RB_INT2FIX.
#define ISALPHA
Old name of rb_isalpha.
#define Qtrue
Old name of RUBY_Qtrue.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_cObject
Object class.
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
Allocates, then initialises an instance of the given class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
static char * rb_enc_left_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
Queries the left boundary of a character.
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
void rb_provide(const char *feature)
Declares that the given feature is already provided by someone else.
void rb_ext_ractor_safe(bool flag)
Asserts that the extension library that calls this function is aware of Ractor.
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
VALUE rb_str_subseq(VALUE str, long beg, long len)
Identical to rb_str_substr(), except the numbers are interpreted as byte offsets instead of character...
VALUE rb_str_dup(VALUE str)
Duplicates a string.
VALUE rb_str_equal(VALUE str1, VALUE str2)
Equality of two strings.
#define rb_str_cat_cstr(buf, str)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
int len
Length of the buffer.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
static char * RSTRING_END(VALUE str)
Queries the end of the contents pointer of the string.
#define InitVM(ext)
This macro is for internal use.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.