@@ -633,7 +633,7 @@ open_exclusive(char *filename)
633633#ifdef O_BINARY
634634 |O_BINARY /* necessary for Windows */
635635#endif
636-
636+
637637 , 0666 );
638638 if (fd < 0 )
639639 return NULL ;
@@ -830,13 +830,10 @@ extern FILE *PyWin_FindRegisteredModule(const char *, struct filedescr **,
830830 char * , int );
831831#endif
832832
833- #ifdef CHECK_IMPORT_CASE
834- static int check_case (char * , int , int , char * );
835- #endif
836-
833+ static int case_ok (char * , int , int , char * );
837834static int find_init_module (char * ); /* Forward */
838835
839- #ifdef HAVE_DIRENT_H
836+ #if 0 /* XXX was # ifdef HAVE_DIRENT_H; resolve whether we really need this */
840837
841838static int MatchFilename (char * pathname , char * filename );
842839
@@ -944,25 +941,25 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
944941 continue ; /* v contains '\0' */
945942#ifdef macintosh
946943#ifdef INTERN_STRINGS
947- /*
944+ /*
948945 ** Speedup: each sys.path item is interned, and
949946 ** FindResourceModule remembers which items refer to
950947 ** folders (so we don't have to bother trying to look
951- ** into them for resources).
948+ ** into them for resources).
952949 */
953950 PyString_InternInPlace (& PyList_GET_ITEM (path , i ));
954951 v = PyList_GET_ITEM (path , i );
955952#endif
956953 if (PyMac_FindResourceModule ((PyStringObject * )v , name , buf )) {
957954 static struct filedescr resfiledescr =
958955 {"" , "" , PY_RESOURCE };
959-
956+
960957 return & resfiledescr ;
961958 }
962959 if (PyMac_FindCodeResourceModule ((PyStringObject * )v , name , buf )) {
963960 static struct filedescr resfiledescr =
964961 {"" , "" , PY_CODERESOURCE };
965-
962+
966963 return & resfiledescr ;
967964 }
968965#endif
@@ -974,18 +971,17 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
974971 buf [len ++ ] = SEP ;
975972 strcpy (buf + len , name );
976973 len += namelen ;
974+
975+ /* Check for package import (buf holds a directory name,
976+ and there's an __init__ module in that directory */
977977#ifdef HAVE_STAT
978- if (stat (buf , & statbuf ) == 0 ) {
979- if (S_ISDIR (statbuf .st_mode )) {
980- if (find_init_module (buf )) {
981- #ifdef CHECK_IMPORT_CASE
982- if (!check_case (buf , len , namelen ,
983- name ))
984- return NULL ;
985- #endif
986- return & fd_package ;
987- }
988- }
978+ if (stat (buf , & statbuf ) == 0 &&
979+ S_ISDIR (statbuf .st_mode ) &&
980+ find_init_module (buf )) {
981+ if (case_ok (buf , len , namelen , name ))
982+ return & fd_package ;
983+ else
984+ return NULL ;
989985 }
990986#else
991987 /* XXX How are you going to test for directories? */
@@ -1000,27 +996,14 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
1000996 if (Py_VerboseFlag > 1 )
1001997 PySys_WriteStderr ("# trying %s\n" , buf );
1002998 fp = fopen (buf , fdp -> mode );
1003- #ifdef HAVE_DIRENT_H
1004-
1005- if (fp != NULL ) { /* check case */
1006- char * curpath = PyString_AsString (v );
1007- char * nstart = buf + strlen (curpath );
1008- if (* nstart == SEP )
1009- nstart ++ ;
1010- if (MatchFilename (curpath , nstart )) {
1011- break ; /* Found */
999+ if (fp != NULL ) {
1000+ if (case_ok (buf , len , namelen , name ))
1001+ break ;
1002+ else { /* continue search */
1003+ fclose (fp );
1004+ fp = NULL ;
10121005 }
1013- fclose (fp ); /* No. Close & continue search */
1014- fp = NULL ;
1015- if (Py_VerboseFlag > 1 )
1016- PySys_WriteStderr (
1017- "# case mismatch for %s: %s\n" ,
1018- name , buf );
10191006 }
1020- #else /* !HAVE_DIRENT_H */
1021- if (fp != NULL )
1022- break ;
1023- #endif /* HAVE_DIRENT_H */
10241007 }
10251008#endif /* !macintosh */
10261009 if (fp != NULL )
@@ -1031,62 +1014,62 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
10311014 "No module named %.200s" , name );
10321015 return NULL ;
10331016 }
1034- #ifdef CHECK_IMPORT_CASE
1035- if (!check_case (buf , len , namelen , name )) {
1036- fclose (fp );
1037- return NULL ;
1038- }
1039- #endif
1040-
10411017 * p_fp = fp ;
10421018 return fdp ;
10431019}
10441020
1045- #ifdef CHECK_IMPORT_CASE
1046-
1021+ /* case_ok(buf, len, namelen, name)
1022+ * We've already done a successful stat() or fopen() on buf (a path of length
1023+ * len; can not assume there's a trailing null). name is the last component
1024+ * of then path (a string of length namelen, exclusive of trailing null).
1025+ * case_ok() is to return 1 if there's a case-sensitive match for
1026+ * name, else 0. case_ok() is also to return 1 if envar PYTHONCASEOK
1027+ * exists.
1028+ * case_ok() is used to implement case-sensitive import semantics even
1029+ * on platforms with case-insensitive filesystems. It's trivial to implement
1030+ * for case-sensitive filesystems. It's pretty much a cross-platform
1031+ * nightmare for systems with case-insensitive filesystems.
1032+ */
1033+
1034+ /* First we may need a pile of platform-specific header files; the sequence
1035+ * of #if's here should match the sequence in the body of case_ok().
1036+ */
10471037#if defined(MS_WIN32 ) || defined(__CYGWIN__ )
10481038#include <windows.h>
10491039#include <ctype.h>
1050-
1051- static int
1052- allcaps8x3 (char * s )
1053- {
1054- /* Return 1 if s is an 8.3 filename in ALLCAPS */
1055- char c ;
1056- char * dot = strchr (s , '.' );
1057- char * end = strchr (s , '\0' );
1058- if (dot != NULL ) {
1059- if (dot - s > 8 )
1060- return 0 ; /* More than 8 before '.' */
1061- if (end - dot > 4 )
1062- return 0 ; /* More than 3 after '.' */
1063- end = strchr (dot + 1 , '.' );
1064- if (end != NULL )
1065- return 0 ; /* More than one dot */
1066- }
1067- else if (end - s > 8 )
1068- return 0 ; /* More than 8 and no dot */
1069- while ((c = * s ++ )) {
1070- if (islower (c ))
1071- return 0 ;
1072- }
1073- return 1 ;
1074- }
1075-
10761040#ifdef __CYGWIN__
10771041#include <sys/cygwin.h>
10781042#endif
10791043
1044+ #elif defined(DJGPP )
1045+ #include <dir.h>
1046+
1047+ #elif defined(macintosh )
1048+ #include <TextUtils.h>
1049+ #ifdef USE_GUSI1
1050+ #include "TFileSpec.h" /* for Path2FSSpec() */
1051+ #endif
1052+
1053+ #endif
1054+
10801055static int
1081- check_case (char * buf , int len , int namelen , char * name )
1056+ case_ok (char * buf , int len , int namelen , char * name )
10821057{
1058+ /* Pick a platform-specific implementation; the sequence of #if's here should
1059+ * match the sequence just above.
1060+ */
1061+
1062+ /* MS_WIN32 || __CYGWIN__ */
1063+ #if defined(MS_WIN32 ) || defined(__CYGWIN__ )
10831064 WIN32_FIND_DATA data ;
10841065 HANDLE h ;
10851066#ifdef __CYGWIN__
10861067 char tempbuf [MAX_PATH ];
10871068#endif
1069+
10881070 if (getenv ("PYTHONCASEOK" ) != NULL )
10891071 return 1 ;
1072+
10901073#ifdef __CYGWIN__
10911074 cygwin32_conv_to_win32_path (buf , tempbuf );
10921075 h = FindFirstFile (tempbuf , & data );
@@ -1100,35 +1083,33 @@ check_case(char *buf, int len, int namelen, char *name)
11001083 return 0 ;
11011084 }
11021085 FindClose (h );
1103- if (allcaps8x3 (data .cFileName )) {
1104- /* Skip the test if the filename is ALL.CAPS. This can
1105- happen in certain circumstances beyond our control,
1106- e.g. when software is installed under NT on a FAT
1107- filesystem and then the same FAT filesystem is used
1108- under Windows 95. */
1086+ return strncmp (data .cFileName , name , namelen ) == 0 ;
1087+
1088+ /* DJGPP */
1089+ #elif defined(DJGPP )
1090+ struct ffblk ffblk ;
1091+ int done ;
1092+
1093+ if (getenv ("PYTHONCASEOK" ) != NULL )
11091094 return 1 ;
1110- }
1111- if ( strncmp ( data . cFileName , name , namelen ) != 0 ) {
1112- strcpy ( buf + len - namelen , data . cFileName );
1095+
1096+ done = findfirst ( buf , & ffblk , FA_ARCH | FA_RDONLY | FA_HIDDEN | FA_DIREC );
1097+ if ( done ) {
11131098 PyErr_Format (PyExc_NameError ,
1114- "Case mismatch for module name %.100s\n(filename %.300s)" ,
1099+ "Can't find file for module %.100s\n(filename %.300s)" ,
11151100 name , buf );
11161101 return 0 ;
11171102 }
1118- return 1 ;
1119- }
1120- #endif /* MS_WIN32 */
1103+ return strncmp (ffblk .ff_name , name , namelen ) == 0 ;
11211104
1122- #ifdef macintosh
1123- #include <TextUtils.h>
1124- #ifdef USE_GUSI1
1125- #include "TFileSpec.h" /* for Path2FSSpec() */
1126- #endif
1127- static int
1128- check_case (char * buf , int len , int namelen , char * name )
1129- {
1105+ /* macintosh */
1106+ #elif defined(macintosh )
11301107 FSSpec fss ;
11311108 OSErr err ;
1109+
1110+ if (getenv ("PYTHONCASEOK" ) != NULL )
1111+ return 1 ;
1112+
11321113#ifndef USE_GUSI1
11331114 err = FSMakeFSSpec (0 , 0 , Pstring (buf ), & fss );
11341115#else
@@ -1154,48 +1135,16 @@ check_case(char *buf, int len, int namelen, char *name)
11541135 name , buf );
11551136 return 0 ;
11561137 }
1157- if (namelen > fss .name [0 ] ||
1158- strncmp (name , (char * )fss .name + 1 , namelen ) != 0 ) {
1159- PyErr_Format (PyExc_NameError ,
1160- "Case mismatch for module name %.100s\n(filename %.300s)" ,
1161- name , fss .name );
1162- return 0 ;
1163- }
1164- return 1 ;
1165- }
1166- #endif /* macintosh */
1167-
1168- #ifdef DJGPP
1169- #include <dir.h>
1170-
1171- static int
1172- check_case (char * buf , int len , int namelen , char * name )
1173- {
1174- struct ffblk ffblk ;
1175- int done ;
1176-
1177- if (getenv ("PYTHONCASEOK" ) != NULL )
1178- return 1 ;
1179- done = findfirst (buf , & ffblk , FA_ARCH |FA_RDONLY |FA_HIDDEN |FA_DIREC );
1180- if (done ) {
1181- PyErr_Format (PyExc_NameError ,
1182- "Can't find file for module %.100s\n(filename %.300s)" ,
1183- name , buf );
1184- return 0 ;
1185- }
1138+ return fss .name [0 ] >= namelen &&
1139+ strncmp (name , (char * )fss .name + 1 , namelen ) == 0 ;
11861140
1187- if (strncmp (ffblk .ff_name , name , namelen ) != 0 ) {
1188- strcpy (buf + len - namelen , ffblk .ff_name );
1189- PyErr_Format (PyExc_NameError ,
1190- "Case mismatch for module name %.100s\n(filename %.300s)" ,
1191- name , buf );
1192- return 0 ;
1193- }
1141+ /* assuming it's a case-sensitive filesystem, so there's nothing to do! */
1142+ #else
11941143 return 1 ;
1195- }
1144+
11961145#endif
1146+ }
11971147
1198- #endif /* CHECK_IMPORT_CASE */
11991148
12001149#ifdef HAVE_STAT
12011150/* Helper to look for __init__.py or __init__.py[co] in potential package */
@@ -1754,7 +1703,7 @@ import_submodule(PyObject *mod, char *subname, char *fullname)
17541703 else: mod.__name__ + "." + subname == fullname
17551704 */
17561705
1757- if ((m = PyDict_GetItemString (modules , fullname )) != NULL ) {
1706+ if ((m = PyDict_GetItemString (modules , fullname )) != NULL ) {
17581707 Py_INCREF (m );
17591708 }
17601709 else {
@@ -1929,7 +1878,7 @@ PyImport_Import(PyObject *module_name)
19291878 Py_XDECREF (globals );
19301879 Py_XDECREF (builtins );
19311880 Py_XDECREF (import );
1932-
1881+
19331882 return r ;
19341883}
19351884
@@ -2006,7 +1955,7 @@ call_find_module(char *name, PyObject *path)
20061955 else {
20071956 fob = Py_None ;
20081957 Py_INCREF (fob );
2009- }
1958+ }
20101959 ret = Py_BuildValue ("Os(ssi)" ,
20111960 fob , pathname , fdp -> suffix , fdp -> mode , fdp -> type );
20121961 Py_DECREF (fob );
0 commit comments