diff options
Diffstat (limited to 'win/tclWinInit.c')
| -rw-r--r-- | win/tclWinInit.c | 217 | 
1 files changed, 132 insertions, 85 deletions
| diff --git a/win/tclWinInit.c b/win/tclWinInit.c index f85448c..d2ee7e1 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -9,8 +9,6 @@   *   * See the file "license.terms" for information on usage and redistribution of   * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclWinInit.c,v 1.69 2006/02/08 21:41:28 dgp Exp $   */  #include "tclWinInt.h" @@ -85,12 +83,12 @@ typedef struct {  #define NUMPLATFORMS 4 -static char* platforms[NUMPLATFORMS] = { +static const char *const platforms[NUMPLATFORMS] = {      "Win32s", "Windows 95", "Windows NT", "Windows CE"  };  #define NUMPROCESSORS 11 -static char* processors[NUMPROCESSORS] = { +static const char *const processors[NUMPROCESSORS] = {      "intel", "mips", "alpha", "ppc", "shx", "arm", "ia64", "alpha64", "msil",      "amd64", "ia32_on_win64"  }; @@ -103,16 +101,20 @@ static TclInitProcessGlobalValueProc	InitializeDefaultLibraryDir;  static ProcessGlobalValue defaultLibraryDir =  	{0, 0, NULL, NULL, InitializeDefaultLibraryDir, NULL, NULL}; -static void		AppendEnvironment(Tcl_Obj *listPtr, CONST char *lib); -static int		ToUtf(CONST WCHAR *wSrc, char *dst); +static TclInitProcessGlobalValueProc	InitializeSourceLibraryDir; +static ProcessGlobalValue sourceLibraryDir = +	{0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL}; + +static void		AppendEnvironment(Tcl_Obj *listPtr, const char *lib); +static int		ToUtf(const WCHAR *wSrc, char *dst);  /*   *---------------------------------------------------------------------------   *   * TclpInitPlatform --   * - *	Initialize all the platform-dependant things like signals and - *	floating-point error handling. + *	Initialize all the platform-dependant things like signals, + *	floating-point error handling and sockets.   *   *	Called at process initialization time.   * @@ -128,20 +130,16 @@ static int		ToUtf(CONST WCHAR *wSrc, char *dst);  void  TclpInitPlatform(void)  { +    WSADATA wsaData; +    WORD wVersionRequested = MAKEWORD(2, 2); +      tclPlatform = TCL_PLATFORM_WINDOWS;      /* -     * The following code stops Windows 3.X and Windows NT 3.51 from -     * automatically putting up Sharing Violation dialogs, e.g, when someone -     * tries to access a file that is locked or a drive with no disk in it. -     * Tcl already returns the appropriate error to the caller, and they can -     * decide to put up their own dialog in response to that failure. -     * -     * Under 95 and NT 4.0, this is a NOOP because the system doesn't -     * automatically put up dialogs when the above operations fail. +     * Initialize the winsock library. On Windows XP and higher this +     * can never fail.       */ - -    SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS); +    WSAStartup(wVersionRequested, &wsaData);  #ifdef STATIC_BUILD      /* @@ -174,13 +172,13 @@ TclpInitPlatform(void)  void  TclpInitLibraryPath(      char **valuePtr, -    int *lengthPtr, +    size_t *lengthPtr,      Tcl_Encoding *encodingPtr)  { -#define LIBRARY_SIZE	    32 +#define LIBRARY_SIZE	    64      Tcl_Obj *pathPtr;      char installLib[LIBRARY_SIZE]; -    char *bytes; +    const char *bytes;      pathPtr = Tcl_NewObj(); @@ -208,10 +206,18 @@ TclpInitLibraryPath(      Tcl_ListObjAppendElement(NULL, pathPtr,  	    TclGetProcessGlobalValue(&defaultLibraryDir)); +    /* +     * Look for the library in its source checkout location. +     */ + +    Tcl_ListObjAppendElement(NULL, pathPtr, +	    TclGetProcessGlobalValue(&sourceLibraryDir)); +      *encodingPtr = NULL; -    bytes = Tcl_GetStringFromObj(pathPtr, lengthPtr); -    *valuePtr = ckalloc((unsigned int)(*lengthPtr)+1); -    memcpy((VOID *) *valuePtr, (VOID *) bytes, (size_t)(*lengthPtr)+1); +    bytes = TclGetString(pathPtr); +    *lengthPtr = pathPtr->length; +    *valuePtr = ckalloc(*lengthPtr + 1); +    memcpy(*valuePtr, bytes, *lengthPtr + 1);      Tcl_DecrRefCount(pathPtr);  } @@ -237,14 +243,14 @@ TclpInitLibraryPath(  static void  AppendEnvironment(      Tcl_Obj *pathPtr, -    CONST char *lib) +    const char *lib)  {      int pathc;      WCHAR wBuf[MAX_PATH];      char buf[MAX_PATH * TCL_UTF_MAX];      Tcl_Obj *objPtr;      Tcl_DString ds; -    CONST char **pathv; +    const char **pathv;      char *shortlib;      /* @@ -290,8 +296,6 @@ AppendEnvironment(  	 */  	if ((pathc > 0) && (lstrcmpiA(shortlib, pathv[pathc - 1]) != 0)) { -	    CONST char *str; -  	    /*  	     * TCL_LIBRARY is set but refers to a different tcl installation  	     * than the current version. Try fiddling with the specified @@ -301,14 +305,13 @@ AppendEnvironment(  	    pathv[pathc - 1] = shortlib;  	    Tcl_DStringInit(&ds); -	    str = Tcl_JoinPath(pathc, pathv, &ds); -	    objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&ds)); -	    Tcl_DStringFree(&ds); +	    (void) Tcl_JoinPath(pathc, pathv, &ds); +	    objPtr = TclDStringToObj(&ds);  	} else {  	    objPtr = Tcl_NewStringObj(buf, -1);  	}  	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	ckfree((char *) pathv); +	ckfree(pathv);      }  } @@ -332,7 +335,7 @@ AppendEnvironment(  static void  InitializeDefaultLibraryDir(      char **valuePtr, -    int *lengthPtr, +    size_t *lengthPtr,      Tcl_Encoding *encodingPtr)  {      HMODULE hModule = TclWinGetTclInstance(); @@ -357,17 +360,19 @@ InitializeDefaultLibraryDir(      TclWinNoBackslash(name);      sprintf(end + 1, "lib/tcl%s", TCL_VERSION);      *lengthPtr = strlen(name); -    *valuePtr = ckalloc((unsigned int) *lengthPtr + 1); +    *valuePtr = ckalloc(*lengthPtr + 1);      *encodingPtr = NULL; -    memcpy((VOID *) *valuePtr, (VOID *) name, (size_t) *lengthPtr + 1); +    memcpy(*valuePtr, name, *lengthPtr + 1);  }  /*   *---------------------------------------------------------------------------   * - * ToUtf -- + * InitializeSourceLibraryDir --   * - *	Convert a char string to a UTF string. + *	Locate the Tcl script library default location relative to the + *	location of the Tcl DLL as it exists in the build output directory + *	associated with the source checkout.   *   * Results:   *	None. @@ -378,45 +383,69 @@ InitializeDefaultLibraryDir(   *---------------------------------------------------------------------------   */ -static int -ToUtf( -    CONST WCHAR *wSrc, -    char *dst) +static void +InitializeSourceLibraryDir( +    char **valuePtr, +    size_t *lengthPtr, +    Tcl_Encoding *encodingPtr)  { -    char *start; +    HMODULE hModule = TclWinGetTclInstance(); +    WCHAR wName[MAX_PATH + LIBRARY_SIZE]; +    char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; +    char *end, *p; -    start = dst; -    while (*wSrc != '\0') { -	dst += Tcl_UniCharToUtf(*wSrc, dst); -	wSrc++; +    if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { +	GetModuleFileNameA(hModule, name, MAX_PATH); +    } else { +	ToUtf(wName, name);      } -    *dst = '\0'; -    return (int) (dst - start); + +    end = strrchr(name, '\\'); +    *end = '\0'; +    p = strrchr(name, '\\'); +    if (p != NULL) { +	end = p; +    } +    *end = '\\'; + +    TclWinNoBackslash(name); +    sprintf(end + 1, "../library"); +    *lengthPtr = strlen(name); +    *valuePtr = ckalloc(*lengthPtr + 1); +    *encodingPtr = NULL; +    memcpy(*valuePtr, name, *lengthPtr + 1);  }  /*   *---------------------------------------------------------------------------   * - * TclWinEncodingsCleanup -- + * ToUtf --   * - *	Reset information to its original state in finalization to allow for - *	reinitialization to be possible. This must not be called until after - *	the filesystem has been finalised, or exit crashes may occur when - *	using virtual filesystems. + *	Convert a char string to a UTF string.   *   * Results:   *	None.   *   * Side effects: - *	Static information reset to startup state. + *	None.   *   *---------------------------------------------------------------------------   */ -void -TclWinEncodingsCleanup(void) +static int +ToUtf( +    const WCHAR *wSrc, +    char *dst)  { -    TclWinResetInterfaceEncodings(); +    char *start; + +    start = dst; +    while (*wSrc != '\0') { +	dst += Tcl_UniCharToUtf(*wSrc, dst); +	wSrc++; +    } +    *dst = '\0'; +    return (int) (dst - start);  }  /* @@ -454,23 +483,20 @@ TclpSetInitialEncodings(void)      Tcl_DStringFree(&encodingName);  } -void -TclpSetInterfaces(void) +void TclWinSetInterfaces( +    int dummy)			/* Not used. */  { -    int platformId, useWide; - -    platformId = TclWinGetPlatformId(); -    useWide = ((platformId == VER_PLATFORM_WIN32_NT) -	    || (platformId == VER_PLATFORM_WIN32_CE)); -    TclWinSetInterfaces(useWide); +    TclpSetInterfaces();  } -CONST char * +const char *  Tcl_GetEncodingNameFromEnvironment(      Tcl_DString *bufPtr)  {      Tcl_DStringInit(bufPtr); +    Tcl_DStringSetLength(bufPtr, 2+TCL_INTEGER_SPACE);      wsprintfA(Tcl_DStringValue(bufPtr), "cp%d", GetACP()); +    Tcl_DStringSetLength(bufPtr, strlen(Tcl_DStringValue(bufPtr)));      return Tcl_DStringValue(bufPtr);  } @@ -495,23 +521,35 @@ void  TclpSetVariables(      Tcl_Interp *interp)		/* Interp to initialize. */  { -    CONST char *ptr; +    const char *ptr;      char buffer[TCL_INTEGER_SPACE * 2]; -    SYSTEM_INFO sysInfo; -    OemId *oemId; -    OSVERSIONINFOA osInfo; +    union { +	SYSTEM_INFO info; +	OemId oemId; +    } sys; +    static OSVERSIONINFOW osInfo; +    static int osInfoInitialized = 0;      Tcl_DString ds;      TCHAR szUserName[UNLEN+1]; -    DWORD dwUserNameLen = sizeof(szUserName); +    DWORD cchUserNameLen = UNLEN;      Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,  	    TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY); -    osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); -    GetVersionExA(&osInfo); - -    oemId = (OemId *) &sysInfo; -    GetSystemInfo(&sysInfo); +    if (!osInfoInitialized) { +	HANDLE handle = LoadLibraryW(L"NTDLL"); +	int(__stdcall *getversion)(void *) = +		(int(__stdcall *)(void *)) GetProcAddress(handle, "RtlGetVersion"); +	osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); +	if (!getversion || getversion(&osInfo)) { +	    GetVersionExW(&osInfo); +	} +	if (handle) { +		FreeLibrary(handle); +	} +	osInfoInitialized = 1; +    } +    GetSystemInfo(&sys.info);      /*       * Define the tcl_platform array. @@ -525,9 +563,9 @@ TclpSetVariables(      }      wsprintfA(buffer, "%d.%d", osInfo.dwMajorVersion, osInfo.dwMinorVersion);      Tcl_SetVar2(interp, "tcl_platform", "osVersion", buffer, TCL_GLOBAL_ONLY); -    if (oemId->wProcessorArchitecture < NUMPROCESSORS) { +    if (sys.oemId.wProcessorArchitecture < NUMPROCESSORS) {  	Tcl_SetVar2(interp, "tcl_platform", "machine", -		processors[oemId->wProcessorArchitecture], +		processors[sys.oemId.wProcessorArchitecture],  		TCL_GLOBAL_ONLY);      } @@ -571,17 +609,26 @@ TclpSetVariables(      /*       * Initialize the user name from the environment first, since this is much       * faster than asking the system. +     * Note: cchUserNameLen is number of characters including nul terminator.       */      Tcl_DStringInit(&ds);      if (TclGetEnv("USERNAME", &ds) == NULL) { -	if (GetUserName(szUserName, &dwUserNameLen) != 0) { -	    Tcl_WinTCharToUtf(szUserName, (int) dwUserNameLen, &ds); +	if (GetUserName(szUserName, &cchUserNameLen) != 0) { +	    int cbUserNameLen = cchUserNameLen - 1; +	    cbUserNameLen *= sizeof(TCHAR); +	    Tcl_WinTCharToUtf(szUserName, cbUserNameLen, &ds);  	}      }      Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds),  	    TCL_GLOBAL_ONLY);      Tcl_DStringFree(&ds); + +    /* +     * Define what the platform PATH separator is. [TIP #315] +     */ + +    Tcl_SetVar2(interp, "tcl_platform","pathSeparator", ";", TCL_GLOBAL_ONLY);  }  /* @@ -590,7 +637,7 @@ TclpSetVariables(   * TclpFindVariable --   *   *	Locate the entry in environ for a given name. On Unix this routine is - *	case sensetive, on Windows this matches mioxed case. + *	case sensitive, on Windows this matches mioxed case.   *   * Results:   *	The return value is the index in environ of an entry with the name @@ -606,7 +653,7 @@ TclpSetVariables(  int  TclpFindVariable( -    CONST char *name,		/* Name of desired environment variable +    const char *name,		/* Name of desired environment variable  				 * (UTF-8). */      int *lengthPtr)		/* Used to return length of name (for  				 * successful searches) or number of non-NULL @@ -614,7 +661,7 @@ TclpFindVariable(  				 * searches). */  {      int i, length, result = -1; -    register CONST char *env, *p1, *p2; +    register const char *env, *p1, *p2;      char *envUpper, *nameUpper;      Tcl_DString envString; @@ -623,8 +670,8 @@ TclpFindVariable(       */      length = strlen(name); -    nameUpper = (char *) ckalloc((unsigned) length+1); -    memcpy((VOID *) nameUpper, (VOID *) name, (size_t) length+1); +    nameUpper = ckalloc(length + 1); +    memcpy(nameUpper, name, (size_t) length+1);      Tcl_UtfToUpper(nameUpper);      Tcl_DStringInit(&envString); | 
