14#define dln_warning(...) rb_warning(__VA_ARGS__)
16#define dln_warning(...) fprintf(stderr, __VA_ARGS__)
24#if defined(HAVE_ALLOCA_H)
36#include "missing/file.h"
42# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
49#if !defined(_WIN32) && !HAVE_DECL_GETENV
53static char *dln_find_1(
const char *fname,
const char *path,
char *buf,
size_t size,
int exe_flag
54 DLN_FIND_EXTRA_ARG_DECL);
57dln_find_exe_r(
const char *fname,
const char *path,
char *buf,
size_t size
58 DLN_FIND_EXTRA_ARG_DECL)
64 if (path) path = envpath =
strdup(path);
75 buf = dln_find_1(fname, path, buf, size, 1 DLN_FIND_EXTRA_ARG);
81dln_find_file_r(
const char *fname,
const char *path,
char *buf,
size_t size
82 DLN_FIND_EXTRA_ARG_DECL)
84 if (!path) path =
".";
85 return dln_find_1(fname, path, buf, size, 0 DLN_FIND_EXTRA_ARG);
89dln_find_1(
const char *fname,
const char *path,
char *fbuf,
size_t size,
91 DLN_FIND_EXTRA_ARG_DECL)
93 register const char *dp;
94 register const char *ep;
97 size_t i, fnlen, fspace;
99 static const char extension[][5] = {
103 int is_abs = 0, has_path = 0;
106 const char *p = fname;
108 static const char pathname_too_long[] =
"openpath: pathname too long (ignored)\n\
109\tDirectory \"%.*s\"%s\n\tFile \"%.*s\"%s\n";
110#define PATHNAME_TOO_LONG() dln_warning(pathname_too_long, \
111 ((bp - fbuf) > 100 ? 100 : (int)(bp - fbuf)), fbuf, \
112 ((bp - fbuf) > 100 ? "..." : ""), \
113 (fnlen > 100 ? 100 : (int)fnlen), fname, \
114 (fnlen > 100 ? "..." : ""))
116#define RETURN_IF(expr) if (expr) return (char *)fname;
119 fnlen = strlen(fname);
121 dln_warning(
"openpath: pathname too long (ignored)\n\tFile \"%.*s\"%s\n",
122 (fnlen > 100 ? 100 : (int)fnlen), fname,
123 (fnlen > 100 ?
"..." :
""));
127# ifndef DLN_CHAR_NEXT
129# define DLN_CHAR_NEXT(p) ((p)+1)
131# ifdef DOSISH_DRIVE_LETTER
132 if ((
unsigned char)((p[0] | 0x20) -
'a') < 26u && p[1] ==
':') {
155 p = DLN_CHAR_NEXT(p);
159 for (j = 0;
STRCASECMP(ext, extension[j]); ) {
160 if (++j ==
sizeof(extension) /
sizeof(extension[0])) {
173 if (i + 1 > size)
goto toolong;
174 fspace = size - i - 1;
177 memcpy(fbuf, fname, i + 1);
178 goto needs_extension;
183 if (*p ==
'.' && *++p ==
'.') ++p;
184 RETURN_IF(*p ==
'/');
185 RETURN_IF(exe_flag && strchr(fname,
'/'));
189 for (dp = path;; dp = ++ep) {
210 if (*dp ==
'~' && (l == 1 ||
217 home = getenv(
"HOME");
239 if (ep[-1] !=
'/' && ep[-1] !=
'\\')
252 memcpy(bp, fname, i + 1);
255 if (exe_flag && !ext) {
256 goto needs_extension;
261# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
263 if (stat(fbuf, &st) == 0 && S_ISREG(st.st_mode)) {
264 if (exe_flag == 0)
return fbuf;
266 if (eaccess(fbuf, X_OK) == 0)
return fbuf;
281 for (j = 0; j <
sizeof(extension) /
sizeof(extension[0]); j++) {
282 if (fspace < strlen(extension[j])) {
286 strlcpy(bp + i, extension[j], fspace);
287 if (stat(fbuf, &st) == 0)
#define PATH_SEP
The delimiter of PATH environment variable.
#define STRCASECMP
Old name of st_locale_insensitive_strcasecmp.
#define strdup(s)
Just another name of ruby_strdup.