ruby-changes:13587
From: usa <ko1@a...>
Date: Fri, 16 Oct 2009 16:42:50 +0900 (JST)
Subject: [ruby-changes:13587] Ruby:r25368 (ruby_1_8): * dln.c (dln_find_1): backport from trunkn.
usa 2009-10-16 16:42:38 +0900 (Fri, 16 Oct 2009) New Revision: 25368 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25368 Log: * dln.c (dln_find_1): backport from trunkn. [ruby-core:25802] Modified files: branches/ruby_1_8/ChangeLog branches/ruby_1_8/dln.c Index: ruby_1_8/dln.c =================================================================== --- ruby_1_8/dln.c (revision 25367) +++ ruby_1_8/dln.c (revision 25368) @@ -1653,6 +1653,8 @@ static char *dln_find_1(); +static char fbuf[MAXPATHLEN]; + char * dln_find_exe(fname, path) const char *fname; @@ -1669,7 +1671,7 @@ 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 @@ 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 @@ /* 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 @@ if (*dp == '~' && (l == 1 || #if defined(DOSISH) - dp[1] == '\\' || + dp[1] == '\\' || #endif dp[1] == '/')) { char *home; @@ -1750,8 +1802,9 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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') { Index: ruby_1_8/ChangeLog =================================================================== --- ruby_1_8/ChangeLog (revision 25367) +++ ruby_1_8/ChangeLog (revision 25368) @@ -1,3 +1,7 @@ +Fri Oct 16 16:41:56 2009 NAKAMURA Usaku <usa@r...> + + * dln.c (dln_find_1): backport from trunkn. [ruby-core:25802] + Fri Oct 16 09:52:00 2009 Nobuyoshi Nakada <nobu@r...> * eval.c (rb_clear_cache_for_undef): clear entries for inherited -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/