diff options
Diffstat (limited to 'unix/tclUnixInit.c')
| -rw-r--r-- | unix/tclUnixInit.c | 1276 | 
1 files changed, 770 insertions, 506 deletions
| diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index b75acd7..1617cba 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -1,4 +1,4 @@ -/*  +/*   * tclUnixInit.c --   *   *	Contains the Unix-specific interpreter initialization functions. @@ -6,14 +6,23 @@   * Copyright (c) 1995-1997 Sun Microsystems, Inc.   * Copyright (c) 1999 by Scriptics Corporation.   * All rights reserved. - * - * RCS: @(#) $Id: tclUnixInit.c,v 1.23 2001/07/31 19:12:08 vincentdarley Exp $   */  #include "tclInt.h" -#include "tclPort.h" +#include <stddef.h>  #include <locale.h> -#if defined(__FreeBSD__) +#ifdef HAVE_LANGINFO +#   include <langinfo.h> +#   ifdef __APPLE__ +#       if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1030 +	    /* Support for weakly importing nl_langinfo on Darwin. */ +#	    define WEAK_IMPORT_NL_LANGINFO +	    extern char *nl_langinfo(nl_item) WEAK_IMPORT_ATTRIBUTE; +#       endif +#    endif +#endif +#include <sys/resource.h> +#if defined(__FreeBSD__) && defined(__GNUC__)  #   include <floatingpoint.h>  #endif  #if defined(__bsdi__) @@ -23,80 +32,308 @@  #   endif  #endif +#ifdef __CYGWIN__ +DLLIMPORT extern __stdcall unsigned char GetVersionExW(void *); +DLLIMPORT extern __stdcall void *LoadLibraryW(const void *); +DLLIMPORT extern __stdcall void FreeLibrary(void *); +DLLIMPORT extern __stdcall void *GetProcAddress(void *, const char *); +DLLIMPORT extern __stdcall void GetSystemInfo(void *); + +#define NUMPLATFORMS 4 +static const char *const platforms[NUMPLATFORMS] = { +    "Win32s", "Windows 95", "Windows NT", "Windows CE" +}; + +#define NUMPROCESSORS 11 +static const char *const  processors[NUMPROCESSORS] = { +    "intel", "mips", "alpha", "ppc", "shx", "arm", "ia64", "alpha64", "msil", +    "amd64", "ia32_on_win64" +}; + +typedef struct _SYSTEM_INFO { +  union { +    DWORD  dwOemId; +    struct { +      int wProcessorArchitecture; +      int wReserved; +    }; +  }; +  DWORD     dwPageSize; +  void *lpMinimumApplicationAddress; +  void *lpMaximumApplicationAddress; +  void *dwActiveProcessorMask; +  DWORD     dwNumberOfProcessors; +  DWORD     dwProcessorType; +  DWORD     dwAllocationGranularity; +  int      wProcessorLevel; +  int      wProcessorRevision; +} SYSTEM_INFO; + +typedef struct _OSVERSIONINFOW { +  DWORD dwOSVersionInfoSize; +  DWORD dwMajorVersion; +  DWORD dwMinorVersion; +  DWORD dwBuildNumber; +  DWORD dwPlatformId; +  wchar_t szCSDVersion[128]; +} OSVERSIONINFOW; +#endif + +#ifdef HAVE_COREFOUNDATION +#include <CoreFoundation/CoreFoundation.h> +#endif +  /* - * The Init script (common to Windows and Unix platforms) is - * defined in tkInitScript.h + * Tcl tries to use standard and homebrew methods to guess the right encoding + * on the platform. However, there is always a final fallback, and this value + * is it. Make sure it is a real Tcl encoding.   */ -#include "tclInitScript.h" -/* Used to store the encoding used for binary files */ -static Tcl_Encoding binaryEncoding = NULL; -/* Has the basic library path encoding issue been fixed */ -static int libraryPathEncodingFixed = 0; +#ifndef TCL_DEFAULT_ENCODING +#define TCL_DEFAULT_ENCODING "iso8859-1" +#endif  /* - * Default directory in which to look for Tcl library scripts.  The - * symbol is defined by Makefile. + * Default directory in which to look for Tcl library scripts. The symbol is + * defined by Makefile.   */  static char defaultLibraryDir[sizeof(TCL_LIBRARY)+200] = TCL_LIBRARY;  /*   * Directory in which to look for packages (each package is typically - * installed as a subdirectory of this directory).  The symbol is - * defined by Makefile. + * installed as a subdirectory of this directory). The symbol is defined by + * Makefile.   */  static char pkgPath[sizeof(TCL_PACKAGE_PATH)+200] = TCL_PACKAGE_PATH;  /* - * The following table is used to map from Unix locale strings to - * encoding files. + * The following table is used to map from Unix locale strings to encoding + * files. If HAVE_LANGINFO is defined, then this is a fallback table when the + * result from nl_langinfo isn't a recognized encoding. Otherwise this is the + * first list checked for a mapping from env encoding to Tcl encoding name.   */  typedef struct LocaleTable { -    CONST char *lang; -    CONST char *encoding; +    const char *lang; +    const char *encoding;  } LocaleTable; -static CONST LocaleTable localeTable[] = { -    {"ja_JP.SJIS",	"shiftjis"}, -    {"ja_JP.EUC",	"euc-jp"}, -    {"ja_JP.eucJP",     "euc-jp"}, -    {"ja_JP.JIS",	"iso2022-jp"}, -    {"ja_JP.mscode",	"shiftjis"}, -    {"ja_JP.ujis",	"euc-jp"}, -    {"ja_JP",		"euc-jp"}, -    {"Ja_JP",		"shiftjis"}, -    {"Jp_JP",		"shiftjis"}, -    {"japan",		"euc-jp"}, +/* + * The table below is sorted for the sake of doing binary searches on it. The + * indenting reflects different categories of data. The leftmost data + * represent the encoding names directly implemented by data files in Tcl's + * default encoding directory. Indented by one TAB are the encoding names that + * are common alternative spellings. Indented by two TABs are the accumulated + * "bug fixes" that have been added to deal with the wide variability seen + * among existing platforms. + */ + +static const LocaleTable localeTable[] = { +	    {"",		"iso8859-1"}, +		    {"ansi-1251",	"cp1251"}, +	    {"ansi_x3.4-1968",	"iso8859-1"}, +    {"ascii",		"ascii"}, +    {"big5",		"big5"}, +    {"cp1250",		"cp1250"}, +    {"cp1251",		"cp1251"}, +    {"cp1252",		"cp1252"}, +    {"cp1253",		"cp1253"}, +    {"cp1254",		"cp1254"}, +    {"cp1255",		"cp1255"}, +    {"cp1256",		"cp1256"}, +    {"cp1257",		"cp1257"}, +    {"cp1258",		"cp1258"}, +    {"cp437",		"cp437"}, +    {"cp737",		"cp737"}, +    {"cp775",		"cp775"}, +    {"cp850",		"cp850"}, +    {"cp852",		"cp852"}, +    {"cp855",		"cp855"}, +    {"cp857",		"cp857"}, +    {"cp860",		"cp860"}, +    {"cp861",		"cp861"}, +    {"cp862",		"cp862"}, +    {"cp863",		"cp863"}, +    {"cp864",		"cp864"}, +    {"cp865",		"cp865"}, +    {"cp866",		"cp866"}, +    {"cp869",		"cp869"}, +    {"cp874",		"cp874"}, +    {"cp932",		"cp932"}, +    {"cp936",		"cp936"}, +    {"cp949",		"cp949"}, +    {"cp950",		"cp950"}, +    {"dingbats",	"dingbats"}, +    {"ebcdic",		"ebcdic"}, +    {"euc-cn",		"euc-cn"}, +    {"euc-jp",		"euc-jp"}, +    {"euc-kr",		"euc-kr"}, +		    {"eucjp",		"euc-jp"}, +		    {"euckr",		"euc-kr"}, +		    {"euctw",		"euc-cn"}, +    {"gb12345",		"gb12345"}, +    {"gb1988",		"gb1988"}, +    {"gb2312",		"gb2312"}, +		    {"gb2312-1980",	"gb2312"}, +    {"gb2312-raw",	"gb2312-raw"}, +		    {"greek8",		"cp869"}, +	    {"ibm1250",		"cp1250"}, +	    {"ibm1251",		"cp1251"}, +	    {"ibm1252",		"cp1252"}, +	    {"ibm1253",		"cp1253"}, +	    {"ibm1254",		"cp1254"}, +	    {"ibm1255",		"cp1255"}, +	    {"ibm1256",		"cp1256"}, +	    {"ibm1257",		"cp1257"}, +	    {"ibm1258",		"cp1258"}, +	    {"ibm437",		"cp437"}, +	    {"ibm737",		"cp737"}, +	    {"ibm775",		"cp775"}, +	    {"ibm850",		"cp850"}, +	    {"ibm852",		"cp852"}, +	    {"ibm855",		"cp855"}, +	    {"ibm857",		"cp857"}, +	    {"ibm860",		"cp860"}, +	    {"ibm861",		"cp861"}, +	    {"ibm862",		"cp862"}, +	    {"ibm863",		"cp863"}, +	    {"ibm864",		"cp864"}, +	    {"ibm865",		"cp865"}, +	    {"ibm866",		"cp866"}, +	    {"ibm869",		"cp869"}, +	    {"ibm874",		"cp874"}, +	    {"ibm932",		"cp932"}, +	    {"ibm936",		"cp936"}, +	    {"ibm949",		"cp949"}, +	    {"ibm950",		"cp950"}, +	    {"iso-2022",	"iso2022"}, +	    {"iso-2022-jp",	"iso2022-jp"}, +	    {"iso-2022-kr",	"iso2022-kr"}, +	    {"iso-8859-1",	"iso8859-1"}, +	    {"iso-8859-10",	"iso8859-10"}, +	    {"iso-8859-13",	"iso8859-13"}, +	    {"iso-8859-14",	"iso8859-14"}, +	    {"iso-8859-15",	"iso8859-15"}, +	    {"iso-8859-16",	"iso8859-16"}, +	    {"iso-8859-2",	"iso8859-2"}, +	    {"iso-8859-3",	"iso8859-3"}, +	    {"iso-8859-4",	"iso8859-4"}, +	    {"iso-8859-5",	"iso8859-5"}, +	    {"iso-8859-6",	"iso8859-6"}, +	    {"iso-8859-7",	"iso8859-7"}, +	    {"iso-8859-8",	"iso8859-8"}, +	    {"iso-8859-9",	"iso8859-9"}, +    {"iso2022",		"iso2022"}, +    {"iso2022-jp",	"iso2022-jp"}, +    {"iso2022-kr",	"iso2022-kr"}, +    {"iso8859-1",	"iso8859-1"}, +    {"iso8859-10",	"iso8859-10"}, +    {"iso8859-13",	"iso8859-13"}, +    {"iso8859-14",	"iso8859-14"}, +    {"iso8859-15",	"iso8859-15"}, +    {"iso8859-16",	"iso8859-16"}, +    {"iso8859-2",	"iso8859-2"}, +    {"iso8859-3",	"iso8859-3"}, +    {"iso8859-4",	"iso8859-4"}, +    {"iso8859-5",	"iso8859-5"}, +    {"iso8859-6",	"iso8859-6"}, +    {"iso8859-7",	"iso8859-7"}, +    {"iso8859-8",	"iso8859-8"}, +    {"iso8859-9",	"iso8859-9"}, +		    {"iso88591",	"iso8859-1"}, +		    {"iso885915",	"iso8859-15"}, +		    {"iso88592",	"iso8859-2"}, +		    {"iso88595",	"iso8859-5"}, +		    {"iso88596",	"iso8859-6"}, +		    {"iso88597",	"iso8859-7"}, +		    {"iso88598",	"iso8859-8"}, +		    {"iso88599",	"iso8859-9"},  #ifdef hpux -    {"japanese",	"shiftjis"},	 -    {"ja",		"shiftjis"},	 +		    {"ja",		"shiftjis"},  #else -    {"japanese",	"euc-jp"}, -    {"ja",		"euc-jp"}, +		    {"ja",		"euc-jp"},  #endif -    {"japanese.sjis",	"shiftjis"}, -    {"japanese.euc",	"euc-jp"}, -    {"japanese-sjis",	"shiftjis"}, -    {"japanese-ujis",	"euc-jp"}, - -    {"ko",              "euc-kr"}, -    {"ko_KR",           "euc-kr"}, -    {"ko_KR.EUC",       "euc-kr"}, -    {"ko_KR.euc",       "euc-kr"}, -    {"ko_KR.eucKR",     "euc-kr"}, -    {"korean",          "euc-kr"}, - -    {"ru",		"iso8859-5"},		 -    {"ru_RU",		"iso8859-5"},		 -    {"ru_SU",		"iso8859-5"},		 +		    {"ja_jp",		"euc-jp"}, +		    {"ja_jp.euc",	"euc-jp"}, +		    {"ja_jp.eucjp",	"euc-jp"}, +		    {"ja_jp.jis",	"iso2022-jp"}, +		    {"ja_jp.mscode",	"shiftjis"}, +		    {"ja_jp.sjis",	"shiftjis"}, +		    {"ja_jp.ujis",	"euc-jp"}, +		    {"japan",		"euc-jp"}, +#ifdef hpux +		    {"japanese",	"shiftjis"}, +#else +		    {"japanese",	"euc-jp"}, +#endif +		    {"japanese-sjis",	"shiftjis"}, +		    {"japanese-ujis",	"euc-jp"}, +		    {"japanese.euc",	"euc-jp"}, +		    {"japanese.sjis",	"shiftjis"}, +    {"jis0201",		"jis0201"}, +    {"jis0208",		"jis0208"}, +    {"jis0212",		"jis0212"}, +		    {"jp_jp",		"shiftjis"}, +		    {"ko",		"euc-kr"}, +		    {"ko_kr",		"euc-kr"}, +		    {"ko_kr.euc",	"euc-kr"}, +		    {"ko_kw.euckw",	"euc-kr"}, +    {"koi8-r",		"koi8-r"}, +    {"koi8-u",		"koi8-u"}, +		    {"korean",		"euc-kr"}, +    {"ksc5601",		"ksc5601"}, +    {"maccenteuro",	"macCentEuro"}, +    {"maccroatian",	"macCroatian"}, +    {"maccyrillic",	"macCyrillic"}, +    {"macdingbats",	"macDingbats"}, +    {"macgreek",	"macGreek"}, +    {"maciceland",	"macIceland"}, +    {"macjapan",	"macJapan"}, +    {"macroman",	"macRoman"}, +    {"macromania",	"macRomania"}, +    {"macthai",		"macThai"}, +    {"macturkish",	"macTurkish"}, +    {"macukraine",	"macUkraine"}, +		    {"roman8",		"iso8859-1"}, +		    {"ru",		"iso8859-5"}, +		    {"ru_ru",		"iso8859-5"}, +		    {"ru_su",		"iso8859-5"}, +    {"shiftjis",	"shiftjis"}, +		    {"sjis",		"shiftjis"}, +    {"symbol",		"symbol"}, +    {"tis-620",		"tis-620"}, +		    {"tis620",		"tis-620"}, +		    {"turkish8",	"cp857"}, +		    {"utf8",		"utf-8"}, +		    {"zh",		"cp936"}, +		    {"zh_cn.gb2312",	"euc-cn"}, +		    {"zh_cn.gbk",	"euc-cn"}, +		    {"zh_cz.gb2312",	"euc-cn"}, +		    {"zh_tw",		"euc-tw"}, +		    {"zh_tw.big5",	"big5"}, +}; -    {"zh",		"cp936"}, +#ifdef HAVE_COREFOUNDATION +static int		MacOSXGetLibraryPath(Tcl_Interp *interp, +			    int maxPathLen, char *tclLibPath); +#endif /* HAVE_COREFOUNDATION */ +#if defined(__APPLE__) && (defined(TCL_LOAD_FROM_MEMORY) || ( \ +	defined(MAC_OS_X_VERSION_MIN_REQUIRED) && ( \ +	(defined(TCL_THREADS) && MAC_OS_X_VERSION_MIN_REQUIRED < 1030) || \ +	(defined(__LP64__) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050) || \ +	(defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050)\ +	))) +/* + * Need to check Darwin release at runtime in tclUnixFCmd.c and tclLoadDyld.c: + * initialize release global at startup from uname(). + */ +#define GET_DARWIN_RELEASE 1 +MODULE_SCOPE long tclMacOSXDarwinRelease; +long tclMacOSXDarwinRelease = 0; +#endif -    {NULL, NULL} -};  /*   *--------------------------------------------------------------------------- @@ -118,34 +355,89 @@ static CONST LocaleTable localeTable[] = {   */  void -TclpInitPlatform() +TclpInitPlatform(void)  { +#ifdef DJGPP +    tclPlatform = TCL_PLATFORM_WINDOWS; +#else      tclPlatform = TCL_PLATFORM_UNIX; +#endif + +    /* +     * Make sure, that the standard FDs exist. [Bug 772288] +     */ + +    if (TclOSseek(0, (Tcl_SeekOffset) 0, SEEK_CUR) == -1 && errno == EBADF) { +	open("/dev/null", O_RDONLY); +    } +    if (TclOSseek(1, (Tcl_SeekOffset) 0, SEEK_CUR) == -1 && errno == EBADF) { +	open("/dev/null", O_WRONLY); +    } +    if (TclOSseek(2, (Tcl_SeekOffset) 0, SEEK_CUR) == -1 && errno == EBADF) { +	open("/dev/null", O_WRONLY); +    }      /* -     * The code below causes SIGPIPE (broken pipe) errors to -     * be ignored.  This is needed so that Tcl processes don't -     * die if they create child processes (e.g. using "exec" or -     * "open") that terminate prematurely.  The signal handler -     * is only set up when the first interpreter is created; -     * after this the application can override the handler with -     * a different one of its own, if it wants. +     * The code below causes SIGPIPE (broken pipe) errors to be ignored. This +     * is needed so that Tcl processes don't die if they create child +     * processes (e.g. using "exec" or "open") that terminate prematurely. +     * The signal handler is only set up when the first interpreter is +     * created; after this the application can override the handler with a +     * different one of its own, if it wants.       */  #ifdef SIGPIPE      (void) signal(SIGPIPE, SIG_IGN);  #endif /* SIGPIPE */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && defined(__GNUC__) +    /* +     * Adjust the rounding mode to be more conventional. Note that FreeBSD +     * only provides the __fpsetreg() used by the following two for the GNU +     * Compiler. When using, say, Intel's icc they break. (Partially based on +     * patch in BSD ports system from root@celsius.bychok.com) +     */ +      fpsetround(FP_RN); -    fpsetmask(0L); +    (void) fpsetmask(0L);  #endif  #if defined(__bsdi__) && (_BSDI_VERSION > 199501)      /*       * Find local symbols. Don't report an error if we fail.       */ -    (void) dlopen (NULL, RTLD_NOW);			/* INTL: Native. */ + +    (void) dlopen(NULL, RTLD_NOW);			/* INTL: Native. */ +#endif + +    /* +     * Initialize the C library's locale subsystem. This is required for input +     * methods to work properly on X11. We only do this for LC_CTYPE because +     * that's the necessary one, and we don't want to affect LC_TIME here. +     * The side effect of setting the default locale should be to load any +     * locale specific modules that are needed by X. [BUG: 5422 3345 4236 2522 +     * 2521]. +     */ + +    setlocale(LC_CTYPE, ""); + +    /* +     * In case the initial locale is not "C", ensure that the numeric +     * processing is done in "C" locale regardless. This is needed because Tcl +     * relies on routines like strtod, but should not have locale dependent +     * behavior. +     */ + +    setlocale(LC_NUMERIC, "C"); + +#ifdef GET_DARWIN_RELEASE +    { +	struct utsname name; + +	if (!uname(&name)) { +	    tclMacOSXDarwinRelease = strtol(name.release, NULL, 10); +	} +    }  #endif  } @@ -154,84 +446,36 @@ TclpInitPlatform()   *   * TclpInitLibraryPath --   * - *	Initialize the library path at startup.  We have a minor - *	metacircular problem that we don't know the encoding of the - *	operating system but we may need to talk to operating system - *	to find the library directories so that we know how to talk to - *	the operating system. - * - *	We do not know the encoding of the operating system. - *	We do know that the encoding is some multibyte encoding. - *	In that multibyte encoding, the characters 0..127 are equivalent - *	    to ascii. - * - *	So although we don't know the encoding, it's safe: - *	    to look for the last slash character in a path in the encoding. - *	    to append an ascii string to a path. - *	    to pass those strings back to the operating system. - * - *	But any strings that we remembered before we knew the encoding of - *	the operating system must be translated to UTF-8 once we know the - *	encoding so that the rest of Tcl can use those strings. - * - *	This call sets the library path to strings in the unknown native - *	encoding.  TclpSetInitialEncodings() will translate the library - *	path from the native encoding to UTF-8 as soon as it determines - *	what the native encoding actually is. - * - *	Called at process initialization time. + *	This is the fallback routine that sets the library path if the + *	application has not set one by the first time it is needed.   *   * Results:   *	None.   *   * Side effects: - *	None. + *	Sets the library path to an initial value.   * - *--------------------------------------------------------------------------- + *-------------------------------------------------------------------------   */  void -TclpInitLibraryPath(path) -CONST char *path;		/* Path to the executable in native  -				 * multi-byte encoding. */ +TclpInitLibraryPath( +    char **valuePtr, +    int *lengthPtr, +    Tcl_Encoding *encodingPtr)  {  #define LIBRARY_SIZE	    32      Tcl_Obj *pathPtr, *objPtr; -    char *str; -    Tcl_DString buffer, ds; -    int pathc; -    char **pathv; -    char installLib[LIBRARY_SIZE], developLib[LIBRARY_SIZE]; +    const char *str; +    Tcl_DString buffer; -    Tcl_DStringInit(&ds);      pathPtr = Tcl_NewObj();      /* -     * Initialize the substrings used when locating an executable.  The -     * installLib variable computes the path as though the executable -     * is installed.  The developLib computes the path as though the -     * executable is run from a develpment directory. -     */ -      -    sprintf(installLib, "lib/tcl%s", TCL_VERSION); -    sprintf(developLib, "tcl%s/library", -	    ((TCL_RELEASE_LEVEL < 2) ? TCL_PATCH_LEVEL : TCL_VERSION)); - -    /* -     * Look for the library relative to default encoding dir. -     */ - -    str = Tcl_GetDefaultEncodingDir(); -    if ((str != NULL) && (str[0] != '\0')) { -	objPtr = Tcl_NewStringObj(str, -1); -	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -    } - -    /* -     * Look for the library relative to the TCL_LIBRARY env variable. -     * If the last dirname in the TCL_LIBRARY path does not match the -     * last dirname in the installLib variable, use the last dir name -     * of installLib in addition to the orginal TCL_LIBRARY path. +     * Look for the library relative to the TCL_LIBRARY env variable. If the +     * last dirname in the TCL_LIBRARY path does not match the last dirname in +     * the installLib variable, use the last dir name of installLib in +     * addition to the orginal TCL_LIBRARY path.       */      str = getenv("TCL_LIBRARY");			/* INTL: Native. */ @@ -239,12 +483,26 @@ CONST char *path;		/* Path to the executable in native      str = Tcl_DStringValue(&buffer);      if ((str != NULL) && (str[0] != '\0')) { +	Tcl_DString ds; +	int pathc; +	const char **pathv; +	char installLib[LIBRARY_SIZE]; + +	Tcl_DStringInit(&ds); + +	/* +	 * Initialize the substrings used when locating an executable. The +	 * installLib variable computes the path as though the executable is +	 * installed. +	 */ + +	sprintf(installLib, "lib/tcl%s", TCL_VERSION); +  	/*  	 * If TCL_LIBRARY is set, search there.  	 */ -	  -	objPtr = Tcl_NewStringObj(str, -1); -	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); + +	Tcl_ListObjAppendElement(NULL, pathPtr, Tcl_NewStringObj(str, -1));  	Tcl_SplitPath(str, &pathc, &pathv);  	if ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc-1]) != 0)) { @@ -252,118 +510,50 @@ CONST char *path;		/* Path to the executable in native  	     * If TCL_LIBRARY is set but refers to a different tcl  	     * installation than the current version, try fiddling with the  	     * specified directory to make it refer to this installation by -	     * removing the old "tclX.Y" and substituting the current -	     * version string. +	     * removing the old "tclX.Y" and substituting the current version +	     * string.  	     */ -	     +  	    pathv[pathc - 1] = installLib + 4;  	    str = Tcl_JoinPath(pathc, pathv, &ds); -	    objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&ds)); -	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds); +	    Tcl_ListObjAppendElement(NULL, pathPtr, TclDStringToObj(&ds));  	} -	ckfree((char *) pathv); +	ckfree(pathv);      }      /* -     * Look for the library relative to the executable.  This algorithm -     * should be the same as the one in the tcl_findLibrary procedure. -     * -     * This code looks in the following directories: -     * -     *	<bindir>/../<installLib> -     *		(e.g. /usr/local/bin/../lib/tcl8.2) -     *	<bindir>/../../<installLib> -     *		(e.g. /usr/local/TclPro/solaris-sparc/bin/../../lib/tcl8.2) -     *	<bindir>/../library -     *		(e.g. /usr/src/tcl8.2/unix/../library) -     *	<bindir>/../../library -     *		(e.g. /usr/src/tcl8.2/unix/solaris-sparc/../../library) -     *	<bindir>/../../<developLib> -     *		(e.g. /usr/src/tcl8.2/unix/../../tcl8.2/library) -     *	<bindir>/../../../<devlopLib> -     *		(e.g. /usr/src/tcl8.2/unix/solaris-sparc/../../../tcl8.2/library) +     * Finally, look for the library relative to the compiled-in path. This is +     * needed when users install Tcl with an exec-prefix that is different +     * from the prefix.       */ -      - -     /* -      * The variable path holds an absolute path.  Take care not to -      * overwrite pathv[0] since that might produce a relative path. -      */ - -    if (path != NULL) { -	Tcl_SplitPath(path, &pathc, &pathv); -	if (pathc > 2) { -	    str = pathv[pathc - 2]; -	    pathv[pathc - 2] = installLib; -	    path = Tcl_JoinPath(pathc - 1, pathv, &ds); -	    pathv[pathc - 2] = str; -	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds)); -	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds); -	} -	if (pathc > 3) { -	    str = pathv[pathc - 3]; -	    pathv[pathc - 3] = installLib; -	    path = Tcl_JoinPath(pathc - 2, pathv, &ds); -	    pathv[pathc - 3] = str; -	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds)); -	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds); -	} -	if (pathc > 2) { -	    str = pathv[pathc - 2]; -	    pathv[pathc - 2] = "library"; -	    path = Tcl_JoinPath(pathc - 1, pathv, &ds); -	    pathv[pathc - 2] = str; -	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds)); -	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds); -	} -	if (pathc > 3) { -	    str = pathv[pathc - 3]; -	    pathv[pathc - 3] = "library"; -	    path = Tcl_JoinPath(pathc - 2, pathv, &ds); -	    pathv[pathc - 3] = str; -	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds)); -	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds); -	} -	if (pathc > 3) { -	    str = pathv[pathc - 3]; -	    pathv[pathc - 3] = developLib; -	    path = Tcl_JoinPath(pathc - 2, pathv, &ds); -	    pathv[pathc - 3] = str; -	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds)); -	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds); + +    { +#ifdef HAVE_COREFOUNDATION +	char tclLibPath[MAXPATHLEN + 1]; + +	if (MacOSXGetLibraryPath(NULL, MAXPATHLEN, tclLibPath) == TCL_OK) { +	    str = tclLibPath; +	} else +#endif /* HAVE_COREFOUNDATION */ +	{ +	    /* +	     * TODO: Pull this value from the TIP 59 table. +	     */ + +	    str = defaultLibraryDir;  	} -	if (pathc > 4) { -	    str = pathv[pathc - 4]; -	    pathv[pathc - 4] = developLib; -	    path = Tcl_JoinPath(pathc - 3, pathv, &ds); -	    pathv[pathc - 4] = str; -	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds)); +	if (str[0] != '\0') { +	    objPtr = Tcl_NewStringObj(str, -1);  	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); -	    Tcl_DStringFree(&ds);  	} -	ckfree((char *) pathv); -    } - -    /* -     * Finally, look for the library relative to the compiled-in path. -     * This is needed when users install Tcl with an exec-prefix that -     * is different from the prtefix. -     */ -			       -    str = defaultLibraryDir; -    if (str[0] != '\0') { -        objPtr = Tcl_NewStringObj(str, -1); -        Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);      } - -    TclSetLibraryPath(pathPtr);          Tcl_DStringFree(&buffer); + +    *encodingPtr = Tcl_GetEncoding(NULL, NULL); +    str = Tcl_GetStringFromObj(pathPtr, lengthPtr); +    *valuePtr = ckalloc((*lengthPtr) + 1); +    memcpy(*valuePtr, str, (size_t)(*lengthPtr)+1); +    Tcl_DecrRefCount(pathPtr);  }  /* @@ -371,169 +561,168 @@ CONST char *path;		/* Path to the executable in native   *   * TclpSetInitialEncodings --   * - *	Based on the locale, determine the encoding of the operating - *	system and the default encoding for newly opened files. + *	Based on the locale, determine the encoding of the operating system + *	and the default encoding for newly opened files.   * - *	Called at process initialization time, and part way through - *	startup, we verify that the initial encodings were correctly - *	setup.  Depending on Tcl's environment, there may not have been - *	enough information first time through (above). + *	Called at process initialization time, and part way through startup, + *	we verify that the initial encodings were correctly setup. Depending + *	on Tcl's environment, there may not have been enough information first + *	time through (above).   *   * Results:   *	None.   *   * Side effects: - *	The Tcl library path is converted from native encoding to UTF-8, - *	on the first call, and the encodings may be changed on first or - *	second call. + *	The Tcl library path is converted from native encoding to UTF-8, on + *	the first call, and the encodings may be changed on first or second + *	call.   *   *---------------------------------------------------------------------------   */  void -TclpSetInitialEncodings() +TclpSetInitialEncodings(void)  { -    if (libraryPathEncodingFixed == 0) { -	CONST char *encoding; -	int i; -	Tcl_Obj *pathPtr; -	char *langEnv; +    Tcl_DString encodingName; +    Tcl_SetSystemEncoding(NULL, +	    Tcl_GetEncodingNameFromEnvironment(&encodingName)); +    Tcl_DStringFree(&encodingName); +} -	/* -	 * Determine the current encoding from the LC_* or LANG environment -	 * variables.  We previously used setlocale() to determine the locale, -	 * but this does not work on some systems (e.g. Linux/i386 RH 5.0). -	 */ +void +TclpSetInterfaces(void) +{ +    /* do nothing */ +} -	langEnv = getenv("LC_ALL"); +static const char * +SearchKnownEncodings( +    const char *encoding) +{ +    int left = 0; +    int right = sizeof(localeTable)/sizeof(LocaleTable); -	if (langEnv == NULL || langEnv[0] == '\0') { -	    langEnv = getenv("LC_CTYPE"); -	} -	if (langEnv == NULL || langEnv[0] == '\0') { -	    langEnv = getenv("LANG"); +    while (left <= right) { +	int test = (left + right)/2; +	int code = strcmp(localeTable[test].lang, encoding); + +	if (code == 0) { +	    return localeTable[test].encoding;  	} -	if (langEnv == NULL || langEnv[0] == '\0') { -	    langEnv = NULL; +	if (code < 0) { +	    left = test+1; +	} else { +	    right = test-1;  	} +    } +    return NULL; +} -	encoding = NULL; -	if (langEnv != NULL) { -	    for (i = 0; localeTable[i].lang != NULL; i++) { -		if (strcmp(localeTable[i].lang, langEnv) == 0) { -		    encoding = localeTable[i].encoding; -		    break; -		} -	    } -	    /* -	     * There was no mapping in the locale table.  If there is an -	     * encoding subfield, we can try to guess from that. -	     */ +const char * +Tcl_GetEncodingNameFromEnvironment( +    Tcl_DString *bufPtr) +{ +    const char *encoding; +    const char *knownEncoding; -	    if (encoding == NULL) { -		char *p; -		for (p = langEnv; *p != '\0'; p++) { -		    if (*p == '.') { -			p++; -			break; -		    } -		} -		if (*p != '\0') { -		    Tcl_DString ds; -		    Tcl_DStringInit(&ds); -		    Tcl_DStringAppend(&ds, p, -1); - -		    encoding = Tcl_DStringValue(&ds); -		    Tcl_UtfToLower(Tcl_DStringValue(&ds)); -		    if (Tcl_SetSystemEncoding(NULL, encoding) == TCL_OK) { -			Tcl_DStringFree(&ds); -			goto resetPath; -		    } -		    Tcl_DStringFree(&ds); -		    encoding = NULL; -		} -	    } -	} -	if (encoding == NULL) { -	    encoding = "iso8859-1"; -	} +    Tcl_DStringInit(bufPtr); -	Tcl_SetSystemEncoding(NULL, encoding); +    /* +     * Determine the current encoding from the LC_* or LANG environment +     * variables. We previously used setlocale() to determine the locale, but +     * this does not work on some systems (e.g. Linux/i386 RH 5.0). +     */ + +#ifdef HAVE_LANGINFO +    if ( +#ifdef WEAK_IMPORT_NL_LANGINFO +	    nl_langinfo != NULL && +#endif +	    setlocale(LC_CTYPE, "") != NULL) { +	Tcl_DString ds; -	resetPath:  	/* -	 * Initialize the C library's locale subsystem.  This is required -	 * for input methods to work properly on X11.  We only do this for -	 * LC_CTYPE because that's the necessary one, and we don't want to -	 * affect LC_TIME here.  The side effect of setting the default locale -	 * should be to load any locale specific modules that are needed by X. -	 * [BUG: 5422 3345 4236 2522 2521]. +	 * Use a DString so we can modify case.  	 */ -	setlocale(LC_CTYPE, ""); +	Tcl_DStringInit(&ds); +	encoding = Tcl_DStringAppend(&ds, nl_langinfo(CODESET), -1); +	Tcl_UtfToLower(Tcl_DStringValue(&ds)); +	knownEncoding = SearchKnownEncodings(encoding); +	if (knownEncoding != NULL) { +	    Tcl_DStringAppend(bufPtr, knownEncoding, -1); +	} else if (NULL != Tcl_GetEncoding(NULL, encoding)) { +	    Tcl_DStringAppend(bufPtr, encoding, -1); +	} +	Tcl_DStringFree(&ds); +	if (Tcl_DStringLength(bufPtr)) { +	    return Tcl_DStringValue(bufPtr); +	} +    } +#endif /* HAVE_LANGINFO */ -	/* -	 * In case the initial locale is not "C", ensure that the numeric -	 * processing is done in "C" locale regardless.  This is needed because -	 * Tcl relies on routines like strtod, but should not have locale -	 * dependent behavior. -	 */ +    /* +     * Classic fallback check. This tries a homebrew algorithm to determine +     * what encoding should be used based on env vars. +     */ -	setlocale(LC_NUMERIC, "C"); +    encoding = getenv("LC_ALL"); -	/* -	 * Until the system encoding was actually set, the library path was -	 * actually in the native multi-byte encoding, and not really UTF-8 -	 * as advertised.  We cheated as follows: -	 * -	 * 1. It was safe to allow the Tcl_SetSystemEncoding() call to  -	 * append the ASCII chars that make up the encoding's filename to  -	 * the names (in the native encoding) of directories in the library  -	 * path, since all Unix multi-byte encodings have ASCII in the -	 * beginning. -	 * -	 * 2. To open the encoding file, the native bytes in the file name -	 * were passed to the OS, without translating from UTF-8 to native, -	 * because the name was already in the native encoding. -	 * -	 * Now that the system encoding was actually successfully set, -	 * translate all the names in the library path to UTF-8.  That way, -	 * next time we search the library path, we'll translate the names  -	 * from UTF-8 to the system encoding which will be the native  -	 * encoding. -	 */ +    if (encoding == NULL || encoding[0] == '\0') { +	encoding = getenv("LC_CTYPE"); +    } +    if (encoding == NULL || encoding[0] == '\0') { +	encoding = getenv("LANG"); +    } +    if (encoding == NULL || encoding[0] == '\0') { +	encoding = NULL; +    } -	pathPtr = TclGetLibraryPath(); -	if (pathPtr != NULL) { -	    int objc; -	    Tcl_Obj **objv; -	     -	    objc = 0; -	    Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv); -	    for (i = 0; i < objc; i++) { -		int length; -		char *string; -		Tcl_DString ds; - -		string = Tcl_GetStringFromObj(objv[i], &length); -		Tcl_ExternalToUtfDString(NULL, string, length, &ds); -		Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds),  -			Tcl_DStringLength(&ds)); -		Tcl_DStringFree(&ds); -	    } +    if (encoding != NULL) { +	const char *p; +	Tcl_DString ds; + +	Tcl_DStringInit(&ds); +	p = encoding; +	encoding = Tcl_DStringAppend(&ds, p, -1); +	Tcl_UtfToLower(Tcl_DStringValue(&ds)); + +	knownEncoding = SearchKnownEncodings(encoding); +	if (knownEncoding != NULL) { +	    Tcl_DStringAppend(bufPtr, knownEncoding, -1); +	} else if (NULL != Tcl_GetEncoding(NULL, encoding)) { +	    Tcl_DStringAppend(bufPtr, encoding, -1); +	} +	if (Tcl_DStringLength(bufPtr)) { +	    Tcl_DStringFree(&ds); +	    return Tcl_DStringValue(bufPtr);  	} -	libraryPathEncodingFixed = 1; -    } -     -    /* This is only ever called from the startup thread */ -    if (binaryEncoding == NULL) {  	/* -	 * Keep the iso8859-1 encoding preloaded.  The IO package uses -	 * it for gets on a binary channel. +	 * We didn't recognize the full value as an encoding name. If there is +	 * an encoding subfield, we can try to guess from that.  	 */ -	binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1"); + +	for (p = encoding; *p != '\0'; p++) { +	    if (*p == '.') { +		p++; +		break; +	    } +	} +	if (*p != '\0') { +	    knownEncoding = SearchKnownEncodings(p); +	    if (knownEncoding != NULL) { +		Tcl_DStringAppend(bufPtr, knownEncoding, -1); +	    } else if (NULL != Tcl_GetEncoding(NULL, p)) { +		Tcl_DStringAppend(bufPtr, p, -1); +	    } +	} +	Tcl_DStringFree(&ds); +	if (Tcl_DStringLength(bufPtr)) { +	    return Tcl_DStringValue(bufPtr); +	}      } +    return Tcl_DStringAppend(bufPtr, TCL_DEFAULT_ENCODING, -1);  }  /* @@ -541,9 +730,9 @@ TclpSetInitialEncodings()   *   * TclpSetVariables --   * - *	Performs platform-specific interpreter initialization related to - *	the tcl_library and tcl_platform variables, and other platform- - *	specific things. + *	Performs platform-specific interpreter initialization related to the + *	tcl_library and tcl_platform variables, and other platform-specific + *	things.   *   * Results:   *	None. @@ -556,36 +745,169 @@ TclpSetInitialEncodings()   */  void -TclpSetVariables(interp) -    Tcl_Interp *interp; +TclpSetVariables( +    Tcl_Interp *interp)  { -#ifndef NO_UNAME +#ifdef __CYGWIN__ +    SYSTEM_INFO sysInfo; +    static OSVERSIONINFOW osInfo; +    static int osInfoInitialized = 0; +    char buffer[TCL_INTEGER_SPACE * 2]; +#elif !defined(NO_UNAME)      struct utsname name;  #endif      int unameOK; -    char *user;      Tcl_DString ds; -    Tcl_SetVar(interp, "tclDefaultLibrary", defaultLibraryDir, TCL_GLOBAL_ONLY); -    Tcl_SetVar(interp, "tcl_pkgPath", pkgPath, TCL_GLOBAL_ONLY); +#ifdef HAVE_COREFOUNDATION +    char tclLibPath[MAXPATHLEN + 1]; + +#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 +    /* +     * Set msgcat fallback locale to current CFLocale identifier. +     */ + +    CFLocaleRef localeRef; +     +    if (CFLocaleCopyCurrent != NULL && CFLocaleGetIdentifier != NULL && +	    (localeRef = CFLocaleCopyCurrent())) { +	CFStringRef locale = CFLocaleGetIdentifier(localeRef); + +	if (locale) { +	    char loc[256]; + +	    if (CFStringGetCString(locale, loc, 256, kCFStringEncodingUTF8)) { +		if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { +		    Tcl_ResetResult(interp); +		} +		Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); +	    } +	} +	CFRelease(localeRef); +    } +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED > 1020 */ + +    if (MacOSXGetLibraryPath(interp, MAXPATHLEN, tclLibPath) == TCL_OK) { +	const char *str; +	CFBundleRef bundleRef; + +	Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); +	Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); +	Tcl_SetVar(interp, "tcl_pkgPath", " ", +		TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); + +	str = TclGetEnv("DYLD_FRAMEWORK_PATH", &ds); +	if ((str != NULL) && (str[0] != '\0')) { +	    char *p = Tcl_DStringValue(&ds); + +	    /* +	     * Convert DYLD_FRAMEWORK_PATH from colon to space separated. +	     */ + +	    do { +		if (*p == ':') { +		    *p = ' '; +		} +	    } while (*p++); +	    Tcl_SetVar(interp, "tcl_pkgPath", Tcl_DStringValue(&ds), +		    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +	    Tcl_SetVar(interp, "tcl_pkgPath", " ", +		    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +	    Tcl_DStringFree(&ds); +	} +	bundleRef = CFBundleGetMainBundle(); +	if (bundleRef) { +	    CFURLRef frameworksURL; +	    Tcl_StatBuf statBuf; + +	    frameworksURL = CFBundleCopyPrivateFrameworksURL(bundleRef); +	    if (frameworksURL) { +		if (CFURLGetFileSystemRepresentation(frameworksURL, TRUE, +			(unsigned char*) tclLibPath, MAXPATHLEN) && +			! TclOSstat(tclLibPath, &statBuf) && +			S_ISDIR(statBuf.st_mode)) { +		    Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, +			    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +		    Tcl_SetVar(interp, "tcl_pkgPath", " ", +			    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +		} +		CFRelease(frameworksURL); +	    } +	    frameworksURL = CFBundleCopySharedFrameworksURL(bundleRef); +	    if (frameworksURL) { +		if (CFURLGetFileSystemRepresentation(frameworksURL, TRUE, +			(unsigned char*) tclLibPath, MAXPATHLEN) && +			! TclOSstat(tclLibPath, &statBuf) && +			S_ISDIR(statBuf.st_mode)) { +		    Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, +			    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +		    Tcl_SetVar(interp, "tcl_pkgPath", " ", +			    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +		} +		CFRelease(frameworksURL); +	    } +	} +	Tcl_SetVar(interp, "tcl_pkgPath", pkgPath, +		TCL_GLOBAL_ONLY | TCL_APPEND_VALUE); +    } else +#endif /* HAVE_COREFOUNDATION */ +    { +	Tcl_SetVar(interp, "tcl_pkgPath", pkgPath, TCL_GLOBAL_ONLY); +    } + +#ifdef DJGPP +    Tcl_SetVar2(interp, "tcl_platform", "platform", "dos", TCL_GLOBAL_ONLY); +#else      Tcl_SetVar2(interp, "tcl_platform", "platform", "unix", TCL_GLOBAL_ONLY); +#endif +      unameOK = 0; -#ifndef NO_UNAME +#ifdef __CYGWIN__ +	unameOK = 1; +    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(&sysInfo); + +    if (osInfo.dwPlatformId < NUMPLATFORMS) { +	Tcl_SetVar2(interp, "tcl_platform", "os", +		platforms[osInfo.dwPlatformId], TCL_GLOBAL_ONLY); +    } +    sprintf(buffer, "%d.%d", osInfo.dwMajorVersion, osInfo.dwMinorVersion); +    Tcl_SetVar2(interp, "tcl_platform", "osVersion", buffer, TCL_GLOBAL_ONLY); +    if (sysInfo.wProcessorArchitecture < NUMPROCESSORS) { +	Tcl_SetVar2(interp, "tcl_platform", "machine", +		processors[sysInfo.wProcessorArchitecture], +		TCL_GLOBAL_ONLY); +    } + +#elif !defined NO_UNAME      if (uname(&name) >= 0) { -	char *native; -	 +	const char *native; +  	unameOK = 1;  	native = Tcl_ExternalToUtfDString(NULL, name.sysname, -1, &ds);  	Tcl_SetVar2(interp, "tcl_platform", "os", native, TCL_GLOBAL_ONLY);  	Tcl_DStringFree(&ds); -	 +  	/* -	 * The following code is a special hack to handle differences in -	 * the way version information is returned by uname.  On most -	 * systems the full version number is available in name.release. -	 * However, under AIX the major version number is in -	 * name.version and the minor version number is in name.release. +	 * The following code is a special hack to handle differences in the +	 * way version information is returned by uname. On most systems the +	 * full version number is available in name.release. However, under +	 * AIX the major version number is in name.version and the minor +	 * version number is in name.release.  	 */  	if ((strchr(name.release, '.') != NULL) @@ -593,17 +915,33 @@ TclpSetVariables(interp)  	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,  		    TCL_GLOBAL_ONLY);  	} else { +#ifdef DJGPP +	    /* +	     * For some obscure reason DJGPP puts major version into +	     * name.release and minor into name.version. As of DJGPP 2.04 this +	     * is documented in djgpp libc.info file. +	     */ + +	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release, +		    TCL_GLOBAL_ONLY); +	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", ".", +		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE); +	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.version, +		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE); +#else  	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.version,  		    TCL_GLOBAL_ONLY);  	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", ".",  		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);  	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,  		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE); + +#endif /* DJGPP */  	}  	Tcl_SetVar2(interp, "tcl_platform", "machine", name.machine,  		TCL_GLOBAL_ONLY);      } -#endif +#endif /* !NO_UNAME */      if (!unameOK) {  	Tcl_SetVar2(interp, "tcl_platform", "os", "", TCL_GLOBAL_ONLY);  	Tcl_SetVar2(interp, "tcl_platform", "osVersion", "", TCL_GLOBAL_ONLY); @@ -611,20 +949,30 @@ TclpSetVariables(interp)      }      /* -     * Copy USER or LOGNAME environment variable into tcl_platform(user) +     * Copy the username of the real user (according to getuid()) into +     * tcl_platform(user).       */ -    Tcl_DStringInit(&ds); -    user = TclGetEnv("USER", &ds); -    if (user == NULL) { -	user = TclGetEnv("LOGNAME", &ds); -	if (user == NULL) { +    { +	struct passwd *pwEnt = TclpGetPwUid(getuid()); +	const char *user; + +	if (pwEnt == NULL) {  	    user = ""; +	    Tcl_DStringInit(&ds);	/* ensure cleanliness */ +	} else { +	    user = Tcl_ExternalToUtfDString(NULL, pwEnt->pw_name, -1, &ds);  	} + +	Tcl_SetVar2(interp, "tcl_platform", "user", user, TCL_GLOBAL_ONLY); +	Tcl_DStringFree(&ds);      } -    Tcl_SetVar2(interp, "tcl_platform", "user", user, TCL_GLOBAL_ONLY); -    Tcl_DStringFree(&ds); +    /* +     * Define what the platform PATH separator is. [TIP #315] +     */ + +    Tcl_SetVar2(interp, "tcl_platform","pathSeparator", ":", TCL_GLOBAL_ONLY);  }  /* @@ -632,15 +980,14 @@ TclpSetVariables(interp)   *   * TclpFindVariable --   * - *	Locate the entry in environ for a given name.  On Unix this  - *	routine is case sensetive, on Windows this matches mixed case. + *	Locate the entry in environ for a given name. On Unix this routine is + *	case sensetive, on Windows this matches mixed case.   *   * Results: - *	The return value is the index in environ of an entry with the - *	name "name", or -1 if there is no such entry.   The integer at - *	*lengthPtr is filled in with the length of name (if a matching - *	entry is found) or the length of the environ array (if no matching - *	entry is found). + *	The return value is the index in environ of an entry with the name + *	"name", or -1 if there is no such entry. The integer at *lengthPtr is + *	filled in with the length of name (if a matching entry is found) or + *	the length of the environ array (if no matching entry is found).   *   * Side effects:   *	None. @@ -649,16 +996,16 @@ TclpSetVariables(interp)   */  int -TclpFindVariable(name, lengthPtr) -    CONST char *name;		/* Name of desired environment variable +TclpFindVariable( +    const char *name,		/* Name of desired environment variable  				 * (native). */ -    int *lengthPtr;		/* Used to return length of name (for +    int *lengthPtr)		/* Used to return length of name (for  				 * successful searches) or number of non-NULL  				 * entries in environ (for unsuccessful  				 * searches). */  {      int i, result = -1; -    register CONST char *env, *p1, *p2; +    register const char *env, *p1, *p2;      Tcl_DString envString;      Tcl_DStringInit(&envString); @@ -674,141 +1021,58 @@ TclpFindVariable(name, lengthPtr)  	    result = i;  	    goto done;  	} -	 +  	Tcl_DStringFree(&envString);      } -     +      *lengthPtr = i; -    done: +  done:      Tcl_DStringFree(&envString);      return result;  } -/* - *---------------------------------------------------------------------- - * - * Tcl_Init -- - * - *	This procedure is typically invoked by Tcl_AppInit procedures - *	to find and source the "init.tcl" script, which should exist - *	somewhere on the Tcl library path. - * - * Results: - *	Returns a standard Tcl completion code and sets the interp's - *	result if there is an error. - * - * Side effects: - *	Depends on what's in the init.tcl script. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_Init(interp) -    Tcl_Interp *interp;		/* Interpreter to initialize. */ -{ -    Tcl_Obj *pathPtr; - -    if (tclPreInitScript != NULL) { -	if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) { -	    return (TCL_ERROR); -	}; -    } -     -    pathPtr = TclGetLibraryPath(); -    if (pathPtr == NULL) { -	pathPtr = Tcl_NewObj(); -    } -    Tcl_SetVar2Ex(interp, "tcl_libPath", NULL, pathPtr, TCL_GLOBAL_ONLY); -    return Tcl_Eval(interp, initScript); -}  /*   *----------------------------------------------------------------------   * - * Tcl_SourceRCFile -- + * MacOSXGetLibraryPath --   * - *	This procedure is typically invoked by Tcl_Main of Tk_Main - *	procedure to source an application specific rc file into the - *	interpreter at startup time. + *	If we have a bundle structure for the Tcl installation, then check + *	there first to see if we can find the libraries there.   *   * Results: - *	None. + *	TCL_OK if we have found the tcl library; TCL_ERROR otherwise.   *   * Side effects: - *	Depends on what's in the rc script. + *	Same as for Tcl_MacOSXOpenVersionedBundleResources.   *   *----------------------------------------------------------------------   */ -void -Tcl_SourceRCFile(interp) -    Tcl_Interp *interp;		/* Interpreter to source rc file into. */ +#ifdef HAVE_COREFOUNDATION +static int +MacOSXGetLibraryPath( +    Tcl_Interp *interp, +    int maxPathLen, +    char *tclLibPath)  { -    Tcl_DString temp; -    char *fileName; -    Tcl_Channel errChannel; - -    fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY); +    int foundInFramework = TCL_ERROR; -    if (fileName != NULL) { -        Tcl_Channel c; -	char *fullName; - -        Tcl_DStringInit(&temp); -	fullName = Tcl_TranslateFileName(interp, fileName, &temp); -	if (fullName == NULL) { -	    /* -	     * Couldn't translate the file name (e.g. it referred to a -	     * bogus user or there was no HOME environment variable). -	     * Just do nothing. -	     */ -	} else { - -	    /* -	     * Test for the existence of the rc file before trying to read it. -	     */ +#ifdef TCL_FRAMEWORK +    foundInFramework = Tcl_MacOSXOpenVersionedBundleResources(interp, +	    "com.tcltk.tcllibrary", TCL_FRAMEWORK_VERSION, 0, maxPathLen, +	    tclLibPath); +#endif -            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0); -            if (c != (Tcl_Channel) NULL) { -                Tcl_Close(NULL, c); -		if (Tcl_EvalFile(interp, fullName) != TCL_OK) { -		    errChannel = Tcl_GetStdChannel(TCL_STDERR); -		    if (errChannel) { -			Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); -			Tcl_WriteChars(errChannel, "\n", 1); -		    } -		} -	    } -	} -        Tcl_DStringFree(&temp); -    } +    return foundInFramework;  } +#endif /* HAVE_COREFOUNDATION */  /* - *---------------------------------------------------------------------- - * - * TclpCheckStackSpace -- - * - *	Detect if we are about to blow the stack.  Called before an  - *	evaluation can happen when nesting depth is checked. - * - * Results: - *	1 if there is enough stack space to continue; 0 if not. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End:   */ - -int -TclpCheckStackSpace() -{ -    /* -     * This function is unimplemented on Unix platforms. -     */ - -    return 1; -} | 
