diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-16 07:42:38 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-16 07:42:38 +0000 |
commit | 369218ed2105c24bd4c4e24a85012eafd10800a7 (patch) | |
tree | b1bdbb2592dabf117dde05ad4eab1ea2bd4aaec1 /dln.c | |
parent | ac0b7f38fe41d9e90faa8651dcee32d2c9fe1690 (diff) |
* dln.c (dln_find_1): backport from trunkn. [ruby-core:25802]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@25368 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'dln.c')
-rw-r--r-- | dln.c | 150 |
1 files changed, 86 insertions, 64 deletions
@@ -1653,6 +1653,8 @@ dln_load(file) static char *dln_find_1(); +static char fbuf[MAXPATHLEN]; + char * dln_find_exe(fname, path) const char *fname; @@ -1669,7 +1671,7 @@ dln_find_exe(fname, path) path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:."; #endif } - return dln_find_1(fname, path, 1); + return dln_find_1(fname, path, fbuf, sizeof(fbuf), 1); } char * @@ -1682,45 +1684,95 @@ dln_find_file(fname, path) return dln_find_1(fname, path, 0); #else if (!path) path = "."; - return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, 0)); + return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, fbuf, sizeof(fbuf), 0)); #endif } -static char fbuf[MAXPATHLEN]; - static char * -dln_find_1(fname, path, exe_flag) - const char *fname; - const char *path; - int exe_flag; /* non 0 if looking for executable. */ +dln_find_1(const char *fname, const char *path, char *fbuf, size_t size, + int exe_flag /* non 0 if looking for executable. */) { register const char *dp; register const char *ep; register char *bp; struct stat st; -#ifdef __MACOS__ - const char* mac_fullpath; + size_t i, fspace; +#ifdef DOSISH + static const char extension[][5] = { + ".exe", ".com", ".cmd", ".bat", + }; + size_t j; + int is_abs = 0, has_path = 0; + const char *ext = 0; + const char *p = fname; #endif - if (!fname) return (char *)fname; - if (fname[0] == '/') return (char *)fname; - if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0) - return (char *)fname; - if (exe_flag && strchr(fname, '/')) return (char *)fname; +#define RETURN_IF(expr) if (expr) return (char *)fname; + + RETURN_IF(!fname); #ifdef DOSISH - if (fname[0] == '\\') return (char *)fname; +# ifndef CharNext +# define CharNext(p) ((p)+1) +# endif # ifdef DOSISH_DRIVE_LETTER - if (strlen(fname) > 2 && fname[1] == ':') return (char *)fname; + if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') { + p += 2; + is_abs = 1; + } # endif - if (strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0) - return (char *)fname; - if (exe_flag && strchr(fname, '\\')) return (char *)fname; + switch (*p) { + case '/': case '\\': + is_abs = 1; + p++; + } + has_path = is_abs; + while (*p) { + switch (*p) { + case '/': case '\\': + has_path = 1; + ext = 0; + p++; + break; + case '.': + ext = p; + p++; + break; + default: + p = CharNext(p); + } + } + if (ext) { + for (j = 0; strcasecmp(ext, extension[j]); ) { + if (++j == sizeof(extension) / sizeof(extension[0])) { + ext = 0; + break; + } + } + } + ep = bp = 0; + if (!exe_flag) { + RETURN_IF(is_abs); + } + else if (has_path) { + RETURN_IF(ext); + i = p - fname; + if (i + 1 > size) goto toolong; + fspace = size - i - 1; + bp = fbuf; + ep = p; + memcpy(fbuf, fname, i + 1); + goto needs_extension; + } #endif + RETURN_IF(fname[0] == '/'); + RETURN_IF(strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0); + RETURN_IF(exe_flag && strchr(fname, '/')); + +#undef RETURN_IF + for (dp = path;; dp = ++ep) { - register int l; - int i; - int fspace; + register size_t l; /* extract a component */ ep = strchr(dp, PATH_SEP[0]); @@ -1730,7 +1782,7 @@ dln_find_1(fname, path, exe_flag) /* find the length of that component */ l = ep - dp; bp = fbuf; - fspace = sizeof fbuf - 2; + fspace = size - 2; if (l > 0) { /* ** If the length of the component is zero length, @@ -1742,7 +1794,7 @@ dln_find_1(fname, path, exe_flag) if (*dp == '~' && (l == 1 || #if defined(DOSISH) - dp[1] == '\\' || + dp[1] == '\\' || #endif dp[1] == '/')) { char *home; @@ -1750,8 +1802,9 @@ dln_find_1(fname, path, exe_flag) home = getenv("HOME"); if (home != NULL) { i = strlen(home); - if ((fspace -= i) < 0) + if (fspace < i) goto toolong; + fspace -= i; memcpy(bp, home, i); bp += i; } @@ -1759,8 +1812,9 @@ dln_find_1(fname, path, exe_flag) l--; } if (l > 0) { - if ((fspace -= l) < 0) + if (fspace < l) goto toolong; + fspace -= l; memcpy(bp, dp, l); bp += l; } @@ -1772,7 +1826,7 @@ dln_find_1(fname, path, exe_flag) /* now append the file name */ i = strlen(fname); - if ((fspace -= i) < 0) { + if (fspace < i) { toolong: fprintf(stderr, "openpath: pathname too long (ignored)\n"); *bp = '\0'; @@ -1780,26 +1834,12 @@ dln_find_1(fname, path, exe_flag) fprintf(stderr, "\tFile \"%s\"\n", fname); goto next; } + fspace -= i; memcpy(bp, fname, i + 1); #if defined(DOSISH) - if (exe_flag) { - static const char extension[][5] = { -#if defined(MSDOS) - ".com", ".exe", ".bat", -#if defined(DJGPP) - ".btm", ".sh", ".ksh", ".pl", ".sed", -#endif -#elif defined(__EMX__) || defined(_WIN32) - ".exe", ".com", ".cmd", ".bat", -/* end of __EMX__ or _WIN32 */ -#else - ".r", ".R", ".x", ".X", ".bat", ".BAT", -/* __human68k__ */ -#endif - }; - int j; - + if (exe_flag && !ext) { + needs_extension: for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) { if (fspace < strlen(extension[j])) { fprintf(stderr, "openpath: pathname too long (ignored)\n"); @@ -1808,37 +1848,19 @@ dln_find_1(fname, path, exe_flag) continue; } strcpy(bp + i, extension[j]); -#ifndef __MACOS__ if (stat(fbuf, &st) == 0) return fbuf; -#else - if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) - return mac_fullpath; - -#endif } goto next; } -#endif /* MSDOS or _WIN32 or __human68k__ or __EMX__ */ +#endif /* _WIN32 or __EMX__ */ -#ifndef __MACOS__ if (stat(fbuf, &st) == 0) { if (exe_flag == 0) return fbuf; /* looking for executable */ if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0) return fbuf; } -#else - if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) { - if (exe_flag == 0) return mac_fullpath; - /* looking for executable */ - if (stat(mac_fullpath, &st) == 0) { - if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0) - return mac_fullpath; - } - } -#endif - next: /* if not, and no other alternatives, life is bleak */ if (*ep == '\0') { |