os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/unix/tclUnixInit.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* 
sl@0
     2
 * tclUnixInit.c --
sl@0
     3
 *
sl@0
     4
 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
sl@0
     5
 *
sl@0
     6
 *	Contains the Unix-specific interpreter initialization functions.
sl@0
     7
 *
sl@0
     8
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
sl@0
     9
 * Copyright (c) 1999 by Scriptics Corporation.
sl@0
    10
 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.  
sl@0
    11
 * All rights reserved.
sl@0
    12
 *
sl@0
    13
 * RCS: @(#) $Id: tclUnixInit.c,v 1.34.2.15 2007/04/29 02:19:51 das Exp $
sl@0
    14
 */
sl@0
    15
sl@0
    16
#if defined(HAVE_COREFOUNDATION)
sl@0
    17
#include <CoreFoundation/CoreFoundation.h>
sl@0
    18
#endif
sl@0
    19
#include "tclInt.h"
sl@0
    20
#include "tclPort.h"
sl@0
    21
#include <locale.h>
sl@0
    22
#ifdef HAVE_LANGINFO
sl@0
    23
#   include <langinfo.h>
sl@0
    24
#   ifdef __APPLE__
sl@0
    25
#       if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1030
sl@0
    26
	    /* Support for weakly importing nl_langinfo on Darwin. */
sl@0
    27
#           define WEAK_IMPORT_NL_LANGINFO
sl@0
    28
	    extern char *nl_langinfo(nl_item) WEAK_IMPORT_ATTRIBUTE;
sl@0
    29
#       endif
sl@0
    30
#    endif
sl@0
    31
#endif
sl@0
    32
#if defined(__FreeBSD__) && defined(__GNUC__)
sl@0
    33
#   include <floatingpoint.h>
sl@0
    34
#endif
sl@0
    35
#if defined(__bsdi__)
sl@0
    36
#   include <sys/param.h>
sl@0
    37
#   if _BSDI_VERSION > 199501
sl@0
    38
#	include <dlfcn.h>
sl@0
    39
#   endif
sl@0
    40
#endif
sl@0
    41
sl@0
    42
#if defined(__SYMBIAN32__) 
sl@0
    43
#include "tclSymbianGlobals.h"
sl@0
    44
#include "convertPathSlashes.h"
sl@0
    45
#endif 
sl@0
    46
sl@0
    47
/*
sl@0
    48
 * The Init script (common to Windows and Unix platforms) is
sl@0
    49
 * defined in tkInitScript.h
sl@0
    50
 */
sl@0
    51
#include "tclInitScript.h"
sl@0
    52
sl@0
    53
/* Used to store the encoding used for binary files */
sl@0
    54
static Tcl_Encoding binaryEncoding = NULL;
sl@0
    55
/* Has the basic library path encoding issue been fixed */
sl@0
    56
static int libraryPathEncodingFixed = 0;
sl@0
    57
sl@0
    58
/*
sl@0
    59
 * Tcl tries to use standard and homebrew methods to guess the right
sl@0
    60
 * encoding on the platform.  However, there is always a final fallback,
sl@0
    61
 * and this value is it.  Make sure it is a real Tcl encoding.
sl@0
    62
 */
sl@0
    63
sl@0
    64
#ifndef TCL_DEFAULT_ENCODING
sl@0
    65
#define TCL_DEFAULT_ENCODING "iso8859-1"
sl@0
    66
#endif
sl@0
    67
sl@0
    68
/*
sl@0
    69
 * Default directory in which to look for Tcl library scripts.  The
sl@0
    70
 * symbol is defined by Makefile.
sl@0
    71
 */
sl@0
    72
#ifdef __SYMBIAN32__  
sl@0
    73
// building one *.exe, giving substitute values to tclUnixInt.c (l#65) to bypass compiler errors for 'normal' install. 
sl@0
    74
//  IMPORTANT NOTE: tcl uses unix-style slashes _inside_ tcl.
sl@0
    75
#ifndef TCL_LIBRARY
sl@0
    76
#define TCL_LIBRARY "C:/private/00000000/library/" 
sl@0
    77
#endif
sl@0
    78
#endif
sl@0
    79
sl@0
    80
static char defaultLibraryDir[sizeof(TCL_LIBRARY)+200] = TCL_LIBRARY;
sl@0
    81
sl@0
    82
/*
sl@0
    83
 * Directory in which to look for packages (each package is typically
sl@0
    84
 * installed as a subdirectory of this directory).  The symbol is
sl@0
    85
 * defined by Makefile.
sl@0
    86
 */
sl@0
    87
#ifdef __SYMBIAN32__   
sl@0
    88
// building one *.exe, giving substitute values to tclUnixInt.c (l#65) to bypass compiler errors for 'normal' install. 
sl@0
    89
//  IMPORTANT NOTE: tcl uses unix-style slashes _insode_ tcl.
sl@0
    90
#ifndef TCL_PACKAGE_PATH
sl@0
    91
#define TCL_PACKAGE_PATH "C:/private/00000000/" 
sl@0
    92
#endif
sl@0
    93
#endif
sl@0
    94
sl@0
    95
static char pkgPath[sizeof(TCL_PACKAGE_PATH)+200] = TCL_PACKAGE_PATH;
sl@0
    96
sl@0
    97
/*
sl@0
    98
 * The following table is used to map from Unix locale strings to
sl@0
    99
 * encoding files.  If HAVE_LANGINFO is defined, then this is a fallback
sl@0
   100
 * table when the result from nl_langinfo isn't a recognized encoding.
sl@0
   101
 * Otherwise this is the first list checked for a mapping from env
sl@0
   102
 * encoding to Tcl encoding name.
sl@0
   103
 */
sl@0
   104
sl@0
   105
typedef struct LocaleTable {
sl@0
   106
    CONST char *lang;
sl@0
   107
    CONST char *encoding;
sl@0
   108
} LocaleTable;
sl@0
   109
sl@0
   110
static CONST LocaleTable localeTable[] = {
sl@0
   111
#ifdef HAVE_LANGINFO
sl@0
   112
    {"gb2312-1980",	"gb2312"},
sl@0
   113
    {"ansi-1251",	"cp1251"},		/* Solaris gets this wrong. */
sl@0
   114
#ifdef __hpux
sl@0
   115
    {"SJIS",		"shiftjis"},
sl@0
   116
    {"eucjp",		"euc-jp"},
sl@0
   117
    {"euckr",		"euc-kr"},
sl@0
   118
    {"euctw",		"euc-cn"},
sl@0
   119
    {"greek8",		"cp869"},
sl@0
   120
    {"iso88591",	"iso8859-1"},
sl@0
   121
    {"iso88592",	"iso8859-2"},
sl@0
   122
    {"iso88595",	"iso8859-5"},
sl@0
   123
    {"iso88596",	"iso8859-6"},
sl@0
   124
    {"iso88597",	"iso8859-7"},
sl@0
   125
    {"iso88598",	"iso8859-8"},
sl@0
   126
    {"iso88599",	"iso8859-9"},
sl@0
   127
    {"iso885915",	"iso8859-15"},
sl@0
   128
    {"roman8",		"iso8859-1"},
sl@0
   129
    {"tis620",		"tis-620"},
sl@0
   130
    {"turkish8",	"cp857"},
sl@0
   131
    {"utf8",		"utf-8"},
sl@0
   132
#endif /* __hpux */
sl@0
   133
#endif /* HAVE_LANGINFO */
sl@0
   134
sl@0
   135
    {"ja_JP.SJIS",	"shiftjis"},
sl@0
   136
    {"ja_JP.EUC",	"euc-jp"},
sl@0
   137
    {"ja_JP.eucJP",     "euc-jp"},
sl@0
   138
    {"ja_JP.JIS",	"iso2022-jp"},
sl@0
   139
    {"ja_JP.mscode",	"shiftjis"},
sl@0
   140
    {"ja_JP.ujis",	"euc-jp"},
sl@0
   141
    {"ja_JP",		"euc-jp"},
sl@0
   142
    {"Ja_JP",		"shiftjis"},
sl@0
   143
    {"Jp_JP",		"shiftjis"},
sl@0
   144
    {"japan",		"euc-jp"},
sl@0
   145
#ifdef hpux
sl@0
   146
    {"japanese",	"shiftjis"},	
sl@0
   147
    {"ja",		"shiftjis"},	
sl@0
   148
#else
sl@0
   149
    {"japanese",	"euc-jp"},
sl@0
   150
    {"ja",		"euc-jp"},
sl@0
   151
#endif
sl@0
   152
    {"japanese.sjis",	"shiftjis"},
sl@0
   153
    {"japanese.euc",	"euc-jp"},
sl@0
   154
    {"japanese-sjis",	"shiftjis"},
sl@0
   155
    {"japanese-ujis",	"euc-jp"},
sl@0
   156
sl@0
   157
    {"ko",              "euc-kr"},
sl@0
   158
    {"ko_KR",           "euc-kr"},
sl@0
   159
    {"ko_KR.EUC",       "euc-kr"},
sl@0
   160
    {"ko_KR.euc",       "euc-kr"},
sl@0
   161
    {"ko_KR.eucKR",     "euc-kr"},
sl@0
   162
    {"korean",          "euc-kr"},
sl@0
   163
sl@0
   164
    {"ru",		"iso8859-5"},		
sl@0
   165
    {"ru_RU",		"iso8859-5"},		
sl@0
   166
    {"ru_SU",		"iso8859-5"},		
sl@0
   167
sl@0
   168
    {"zh",		"cp936"},
sl@0
   169
    {"zh_CN.gb2312",	"euc-cn"},
sl@0
   170
    {"zh_CN.GB2312",	"euc-cn"},
sl@0
   171
    {"zh_CN.GBK",	"euc-cn"},
sl@0
   172
    {"zh_TW.Big5",	"big5"},
sl@0
   173
    {"zh_TW",		"euc-tw"},
sl@0
   174
sl@0
   175
    {NULL, NULL}
sl@0
   176
};
sl@0
   177
sl@0
   178
#ifdef HAVE_COREFOUNDATION
sl@0
   179
static int		MacOSXGetLibraryPath _ANSI_ARGS_((
sl@0
   180
			    Tcl_Interp *interp, int maxPathLen,
sl@0
   181
			    char *tclLibPath));
sl@0
   182
#endif /* HAVE_COREFOUNDATION */
sl@0
   183
#if defined(__APPLE__) && (defined(TCL_LOAD_FROM_MEMORY) || ( \
sl@0
   184
	defined(TCL_THREADS) && defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
sl@0
   185
	MAC_OS_X_VERSION_MIN_REQUIRED < 1030) || ( \
sl@0
   186
	defined(__LP64__) && defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
sl@0
   187
	MAC_OS_X_VERSION_MIN_REQUIRED < 1050))
sl@0
   188
/*
sl@0
   189
 * Need to check Darwin release at runtime in tclUnixFCmd.c and tclLoadDyld.c:
sl@0
   190
 * initialize release global at startup from uname().
sl@0
   191
 */
sl@0
   192
#define GET_DARWIN_RELEASE 1
sl@0
   193
long tclMacOSXDarwinRelease = 0;
sl@0
   194
#endif
sl@0
   195
sl@0
   196

sl@0
   197
/*
sl@0
   198
 *---------------------------------------------------------------------------
sl@0
   199
 *
sl@0
   200
 * TclpInitPlatform --
sl@0
   201
 *
sl@0
   202
 *	Initialize all the platform-dependant things like signals and
sl@0
   203
 *	floating-point error handling.
sl@0
   204
 *
sl@0
   205
 *	Called at process initialization time.
sl@0
   206
 *
sl@0
   207
 * Results:
sl@0
   208
 *	None.
sl@0
   209
 *
sl@0
   210
 * Side effects:
sl@0
   211
 *	None.
sl@0
   212
 *
sl@0
   213
 *---------------------------------------------------------------------------
sl@0
   214
 */
sl@0
   215
sl@0
   216
void
sl@0
   217
TclpInitPlatform()
sl@0
   218
{
sl@0
   219
#if defined(__SYMBIAN32__) 
sl@0
   220
	// we need to use Windows file and path name convention with unix code.
sl@0
   221
	tclPlatform = TCL_PLATFORM_WINDOWS;
sl@0
   222
#else
sl@0
   223
    tclPlatform = TCL_PLATFORM_UNIX;	
sl@0
   224
#endif
sl@0
   225
sl@0
   226
    /*
sl@0
   227
     * Make sure, that the standard FDs exist. [Bug 772288]
sl@0
   228
     */
sl@0
   229
    if (TclOSseek(0, (Tcl_SeekOffset) 0, SEEK_CUR) == -1 && errno == EBADF) {
sl@0
   230
	open("/dev/null", O_RDONLY);
sl@0
   231
    }
sl@0
   232
    if (TclOSseek(1, (Tcl_SeekOffset) 0, SEEK_CUR) == -1 && errno == EBADF) {
sl@0
   233
	open("/dev/null", O_WRONLY);
sl@0
   234
    }
sl@0
   235
    if (TclOSseek(2, (Tcl_SeekOffset) 0, SEEK_CUR) == -1 && errno == EBADF) {
sl@0
   236
	open("/dev/null", O_WRONLY);
sl@0
   237
    }
sl@0
   238
sl@0
   239
    /*
sl@0
   240
     * The code below causes SIGPIPE (broken pipe) errors to
sl@0
   241
     * be ignored.  This is needed so that Tcl processes don't
sl@0
   242
     * die if they create child processes (e.g. using "exec" or
sl@0
   243
     * "open") that terminate prematurely.  The signal handler
sl@0
   244
     * is only set up when the first interpreter is created;
sl@0
   245
     * after this the application can override the handler with
sl@0
   246
     * a different one of its own, if it wants.
sl@0
   247
     */
sl@0
   248
sl@0
   249
#ifdef SIGPIPE
sl@0
   250
    (void) signal(SIGPIPE, SIG_IGN);
sl@0
   251
#endif /* SIGPIPE */
sl@0
   252
sl@0
   253
#if defined(__FreeBSD__) && defined(__GNUC__)
sl@0
   254
    /*
sl@0
   255
     * Adjust the rounding mode to be more conventional. Note that FreeBSD
sl@0
   256
     * only provides the __fpsetreg() used by the following two for the GNU
sl@0
   257
     * Compiler. When using, say, Intel's icc they break. (Partially based on
sl@0
   258
     * patch in BSD ports system from root@celsius.bychok.com)
sl@0
   259
     */
sl@0
   260
sl@0
   261
    fpsetround(FP_RN);
sl@0
   262
    fpsetmask(0L);
sl@0
   263
#endif
sl@0
   264
sl@0
   265
#if defined(__bsdi__) && (_BSDI_VERSION > 199501)
sl@0
   266
    /*
sl@0
   267
     * Find local symbols. Don't report an error if we fail.
sl@0
   268
     */
sl@0
   269
    (void) dlopen (NULL, RTLD_NOW);			/* INTL: Native. */
sl@0
   270
#endif
sl@0
   271
sl@0
   272
#ifdef GET_DARWIN_RELEASE
sl@0
   273
    {
sl@0
   274
	struct utsname name;
sl@0
   275
	if (!uname(&name)) {
sl@0
   276
	    tclMacOSXDarwinRelease = strtol(name.release, NULL, 10);
sl@0
   277
	}
sl@0
   278
    }
sl@0
   279
#endif
sl@0
   280
}
sl@0
   281

sl@0
   282
/*
sl@0
   283
 *---------------------------------------------------------------------------
sl@0
   284
 *
sl@0
   285
 * TclpInitLibraryPath --
sl@0
   286
 *
sl@0
   287
 *	Initialize the library path at startup.  We have a minor
sl@0
   288
 *	metacircular problem that we don't know the encoding of the
sl@0
   289
 *	operating system but we may need to talk to operating system
sl@0
   290
 *	to find the library directories so that we know how to talk to
sl@0
   291
 *	the operating system.
sl@0
   292
 *
sl@0
   293
 *	We do not know the encoding of the operating system.
sl@0
   294
 *	We do know that the encoding is some multibyte encoding.
sl@0
   295
 *	In that multibyte encoding, the characters 0..127 are equivalent
sl@0
   296
 *	    to ascii.
sl@0
   297
 *
sl@0
   298
 *	So although we don't know the encoding, it's safe:
sl@0
   299
 *	    to look for the last slash character in a path in the encoding.
sl@0
   300
 *	    to append an ascii string to a path.
sl@0
   301
 *	    to pass those strings back to the operating system.
sl@0
   302
 *
sl@0
   303
 *	But any strings that we remembered before we knew the encoding of
sl@0
   304
 *	the operating system must be translated to UTF-8 once we know the
sl@0
   305
 *	encoding so that the rest of Tcl can use those strings.
sl@0
   306
 *
sl@0
   307
 *	This call sets the library path to strings in the unknown native
sl@0
   308
 *	encoding.  TclpSetInitialEncodings() will translate the library
sl@0
   309
 *	path from the native encoding to UTF-8 as soon as it determines
sl@0
   310
 *	what the native encoding actually is.
sl@0
   311
 *
sl@0
   312
 *	Called at process initialization time.
sl@0
   313
 *
sl@0
   314
 * Results:
sl@0
   315
 *	Return 1, indicating that the UTF may be dirty and require "cleanup"
sl@0
   316
 *	after encodings are initialized.
sl@0
   317
 *
sl@0
   318
 * Side effects:
sl@0
   319
 *	None.
sl@0
   320
 *
sl@0
   321
 *---------------------------------------------------------------------------
sl@0
   322
 */
sl@0
   323
sl@0
   324
int
sl@0
   325
TclpInitLibraryPath(path)
sl@0
   326
CONST char *path;		/* Path to the executable in native 
sl@0
   327
				 * multi-byte encoding. */
sl@0
   328
{
sl@0
   329
#define LIBRARY_SIZE	    32
sl@0
   330
    Tcl_Obj *pathPtr, *objPtr;
sl@0
   331
    CONST char *str;
sl@0
   332
    Tcl_DString buffer, ds;
sl@0
   333
    int pathc;
sl@0
   334
    CONST char **pathv;
sl@0
   335
    char installLib[LIBRARY_SIZE], developLib[LIBRARY_SIZE];
sl@0
   336
#ifdef __SYMBIAN32__  
sl@0
   337
    int retEnv;  
sl@0
   338
    char homeEnvVariableBuf[LIBRARY_SIZE];  
sl@0
   339
    char *homeEnvVariableStr;  
sl@0
   340
#endif
sl@0
   341
sl@0
   342
    Tcl_DStringInit(&ds);
sl@0
   343
    pathPtr = Tcl_NewObj();
sl@0
   344
sl@0
   345
    /*
sl@0
   346
     * Initialize the substrings used when locating an executable.  The
sl@0
   347
     * installLib variable computes the path as though the executable
sl@0
   348
     * is installed.  The developLib computes the path as though the
sl@0
   349
     * executable is run from a develpment directory.
sl@0
   350
     */
sl@0
   351
     
sl@0
   352
    sprintf(installLib, "lib/tcl%s", TCL_VERSION);
sl@0
   353
    sprintf(developLib, "tcl%s/library", TCL_PATCH_LEVEL);
sl@0
   354
sl@0
   355
    /*
sl@0
   356
     * Look for the library relative to default encoding dir.
sl@0
   357
     */
sl@0
   358
sl@0
   359
    str = Tcl_GetDefaultEncodingDir();
sl@0
   360
    if ((str != NULL) && (str[0] != '\0')) {
sl@0
   361
	objPtr = Tcl_NewStringObj(str, -1);
sl@0
   362
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   363
    }
sl@0
   364
sl@0
   365
    /*
sl@0
   366
     * Look for the library relative to the TCL_LIBRARY env variable.
sl@0
   367
     * If the last dirname in the TCL_LIBRARY path does not match the
sl@0
   368
     * last dirname in the installLib variable, use the last dir name
sl@0
   369
     * of installLib in addition to the orginal TCL_LIBRARY path.
sl@0
   370
     */
sl@0
   371
sl@0
   372
#ifdef __SYMBIAN32__  
sl@0
   373
	// add setenv so that tcl has access to the TCL_LIBRARY "system" environment var.  (It can also be accessed from *.tcl scripts.)   	
sl@0
   374
	if (!getenv("HOME")) {		
sl@0
   375
	    homeEnvVariableStr = getcwd(homeEnvVariableBuf, LIBRARY_SIZE);
sl@0
   376
		if (!homeEnvVariableStr) {
sl@0
   377
			fprintf(stderr, "Error getting cwd, defaulting to SYMB_TCL_DEFAULT_HOME_DIR.\r\n");   				
sl@0
   378
		}
sl@0
   379
		/* TODO - the line bellow is a temporary patch. The defect number is: DEF116621. */
sl@0
   380
		homeEnvVariableBuf[0] = 'c';
sl@0
   381
	    tclCopySymbianPathSlashConversion(TO_TCL, homeEnvVariableStr, homeEnvVariableStr);  
sl@0
   382
    	retEnv = setenv("HOME", homeEnvVariableStr, 1);	
sl@0
   383
    	if (retEnv == -1)
sl@0
   384
    	{
sl@0
   385
			fprintf(stderr, "Error setting env(HOME)\r\n");   
sl@0
   386
    	}
sl@0
   387
	}
sl@0
   388
	// add setenv so that tcl has access to the TCL_LIBRARY "system" environment var.  (It can also be accessed from *.tcl scripts.)   
sl@0
   389
    retEnv = setenv("TCL_LIBRARY", TCL_LIBRARY, 1);		
sl@0
   390
    if (retEnv == -1)
sl@0
   391
    {
sl@0
   392
		fprintf(stderr, "Error setting env(TCL_LIBRARY)\r\n");   
sl@0
   393
    }
sl@0
   394
	// add setenv so that tcl has access to the TCL_LIBRARY "system" environment var 'tcllibpath' in init.tcl.  (It can also be accessed from *.tcl scripts.)   
sl@0
   395
    retEnv = setenv("TCLLIBPATH", TCL_LIBRARY, 1);		
sl@0
   396
    if (retEnv == -1)
sl@0
   397
    {
sl@0
   398
		fprintf(stderr, "Error setting env(TCLLIBPATH)\r\n");   
sl@0
   399
    }
sl@0
   400
#endif    
sl@0
   401
    str = getenv("TCL_LIBRARY");			/* INTL: Native. */
sl@0
   402
    Tcl_ExternalToUtfDString(NULL, str, -1, &buffer);
sl@0
   403
    str = Tcl_DStringValue(&buffer);
sl@0
   404
sl@0
   405
    if ((str != NULL) && (str[0] != '\0')) {
sl@0
   406
	/*
sl@0
   407
	 * If TCL_LIBRARY is set, search there.
sl@0
   408
	 */
sl@0
   409
	 
sl@0
   410
	objPtr = Tcl_NewStringObj(str, -1);
sl@0
   411
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   412
sl@0
   413
	Tcl_SplitPath(str, &pathc, &pathv);
sl@0
   414
	if ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc-1]) != 0)) {
sl@0
   415
	    /*
sl@0
   416
	     * If TCL_LIBRARY is set but refers to a different tcl
sl@0
   417
	     * installation than the current version, try fiddling with the
sl@0
   418
	     * specified directory to make it refer to this installation by
sl@0
   419
	     * removing the old "tclX.Y" and substituting the current
sl@0
   420
	     * version string.
sl@0
   421
	     */
sl@0
   422
	    
sl@0
   423
	    pathv[pathc - 1] = installLib + 4;
sl@0
   424
	    str = Tcl_JoinPath(pathc, pathv, &ds);
sl@0
   425
	    objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&ds));
sl@0
   426
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   427
	    Tcl_DStringFree(&ds);
sl@0
   428
	}
sl@0
   429
	ckfree((char *) pathv);
sl@0
   430
    }
sl@0
   431
sl@0
   432
    /*
sl@0
   433
     * Look for the library relative to the executable.  This algorithm
sl@0
   434
     * should be the same as the one in the tcl_findLibrary procedure.
sl@0
   435
     *
sl@0
   436
     * This code looks in the following directories:
sl@0
   437
     *
sl@0
   438
     *	<bindir>/../<installLib>
sl@0
   439
     *	  (e.g. /usr/local/bin/../lib/tcl8.4)
sl@0
   440
     *	<bindir>/../../<installLib>
sl@0
   441
     *	  (e.g. /usr/local/TclPro/solaris-sparc/bin/../../lib/tcl8.4)
sl@0
   442
     *	<bindir>/../library
sl@0
   443
     *	  (e.g. /usr/src/tcl8.4.0/unix/../library)
sl@0
   444
     *	<bindir>/../../library
sl@0
   445
     *	  (e.g. /usr/src/tcl8.4.0/unix/solaris-sparc/../../library)
sl@0
   446
     *	<bindir>/../../<developLib>
sl@0
   447
     *	  (e.g. /usr/src/tcl8.4.0/unix/../../tcl8.4.0/library)
sl@0
   448
     *	<bindir>/../../../<developLib>
sl@0
   449
     *	  (e.g. /usr/src/tcl8.4.0/unix/solaris-sparc/../../../tcl8.4.0/library)
sl@0
   450
     */
sl@0
   451
     
sl@0
   452
sl@0
   453
     /*
sl@0
   454
      * The variable path holds an absolute path.  Take care not to
sl@0
   455
      * overwrite pathv[0] since that might produce a relative path.
sl@0
   456
      */
sl@0
   457
#ifndef __SYMBIAN32__
sl@0
   458
    if (path != NULL) {
sl@0
   459
	int i, origc;
sl@0
   460
	CONST char **origv;
sl@0
   461
sl@0
   462
	Tcl_SplitPath(path, &origc, &origv);
sl@0
   463
	pathc = 0;
sl@0
   464
	pathv = (CONST char **) ckalloc((unsigned int)(origc * sizeof(char *)));
sl@0
   465
	for (i=0; i< origc; i++) {
sl@0
   466
	    if (origv[i][0] == '.') {
sl@0
   467
		if (strcmp(origv[i], ".") == 0) {
sl@0
   468
		    // do nothing //
sl@0
   469
		} else if (strcmp(origv[i], "..") == 0) {
sl@0
   470
		    pathc--;
sl@0
   471
		} else {
sl@0
   472
		    pathv[pathc++] = origv[i];
sl@0
   473
		}
sl@0
   474
	    } else {
sl@0
   475
		pathv[pathc++] = origv[i];
sl@0
   476
	    }
sl@0
   477
	}
sl@0
   478
	if (pathc > 2) {
sl@0
   479
	    str = pathv[pathc - 2];
sl@0
   480
	    pathv[pathc - 2] = installLib;
sl@0
   481
	    path = Tcl_JoinPath(pathc - 1, pathv, &ds);
sl@0
   482
	    pathv[pathc - 2] = str;
sl@0
   483
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
sl@0
   484
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   485
	    Tcl_DStringFree(&ds);
sl@0
   486
	}
sl@0
   487
	if (pathc > 3) {
sl@0
   488
	    str = pathv[pathc - 3];
sl@0
   489
	    pathv[pathc - 3] = installLib;
sl@0
   490
	    path = Tcl_JoinPath(pathc - 2, pathv, &ds);
sl@0
   491
	    pathv[pathc - 3] = str;
sl@0
   492
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
sl@0
   493
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   494
	    Tcl_DStringFree(&ds);
sl@0
   495
	}
sl@0
   496
	if (pathc > 2) {
sl@0
   497
	    str = pathv[pathc - 2];
sl@0
   498
	    pathv[pathc - 2] = "library";
sl@0
   499
	    path = Tcl_JoinPath(pathc - 1, pathv, &ds);
sl@0
   500
	    pathv[pathc - 2] = str;
sl@0
   501
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
sl@0
   502
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   503
	    Tcl_DStringFree(&ds);
sl@0
   504
	}
sl@0
   505
	if (pathc > 3) {
sl@0
   506
	    str = pathv[pathc - 3];
sl@0
   507
	    pathv[pathc - 3] = "library";
sl@0
   508
	    path = Tcl_JoinPath(pathc - 2, pathv, &ds);
sl@0
   509
	    pathv[pathc - 3] = str;
sl@0
   510
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
sl@0
   511
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   512
	    Tcl_DStringFree(&ds);
sl@0
   513
	}
sl@0
   514
	if (pathc > 3) {
sl@0
   515
	    str = pathv[pathc - 3];
sl@0
   516
	    pathv[pathc - 3] = developLib;
sl@0
   517
	    path = Tcl_JoinPath(pathc - 2, pathv, &ds);
sl@0
   518
	    pathv[pathc - 3] = str;
sl@0
   519
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
sl@0
   520
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   521
	    Tcl_DStringFree(&ds);
sl@0
   522
	}
sl@0
   523
	if (pathc > 4) {
sl@0
   524
	    str = pathv[pathc - 4];
sl@0
   525
	    pathv[pathc - 4] = developLib;
sl@0
   526
	    path = Tcl_JoinPath(pathc - 3, pathv, &ds);
sl@0
   527
	    pathv[pathc - 4] = str;
sl@0
   528
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
sl@0
   529
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   530
	    Tcl_DStringFree(&ds);
sl@0
   531
	}
sl@0
   532
	ckfree((char *) origv);
sl@0
   533
	ckfree((char *) pathv);
sl@0
   534
    }
sl@0
   535
#endif    
sl@0
   536
sl@0
   537
    /*
sl@0
   538
     * Finally, look for the library relative to the compiled-in path.
sl@0
   539
     * This is needed when users install Tcl with an exec-prefix that
sl@0
   540
     * is different from the prtefix.
sl@0
   541
     */
sl@0
   542
sl@0
   543
    {
sl@0
   544
#ifdef HAVE_COREFOUNDATION
sl@0
   545
    char tclLibPath[MAXPATHLEN + 1];
sl@0
   546
sl@0
   547
    if (MacOSXGetLibraryPath(NULL, MAXPATHLEN, tclLibPath) == TCL_OK) {
sl@0
   548
        str = tclLibPath;
sl@0
   549
    } else
sl@0
   550
#endif /* HAVE_COREFOUNDATION */
sl@0
   551
    {
sl@0
   552
        str = defaultLibraryDir;
sl@0
   553
    }
sl@0
   554
    if (str[0] != '\0') {
sl@0
   555
        objPtr = Tcl_NewStringObj(str, -1);
sl@0
   556
        Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
sl@0
   557
    }
sl@0
   558
    }
sl@0
   559
sl@0
   560
    TclSetLibraryPath(pathPtr);    
sl@0
   561
    Tcl_DStringFree(&buffer);
sl@0
   562
sl@0
   563
    return 1; /* 1 indicates that pathPtr may be dirty utf (needs cleaning) */
sl@0
   564
}
sl@0
   565

sl@0
   566
/*
sl@0
   567
 *---------------------------------------------------------------------------
sl@0
   568
 *
sl@0
   569
 * TclpSetInitialEncodings --
sl@0
   570
 *
sl@0
   571
 *	Based on the locale, determine the encoding of the operating
sl@0
   572
 *	system and the default encoding for newly opened files.
sl@0
   573
 *
sl@0
   574
 *	Called at process initialization time, and part way through
sl@0
   575
 *	startup, we verify that the initial encodings were correctly
sl@0
   576
 *	setup.  Depending on Tcl's environment, there may not have been
sl@0
   577
 *	enough information first time through (above).
sl@0
   578
 *
sl@0
   579
 * Results:
sl@0
   580
 *	None.
sl@0
   581
 *
sl@0
   582
 * Side effects:
sl@0
   583
 *	The Tcl library path is converted from native encoding to UTF-8,
sl@0
   584
 *	on the first call, and the encodings may be changed on first or
sl@0
   585
 *	second call.
sl@0
   586
 *
sl@0
   587
 *---------------------------------------------------------------------------
sl@0
   588
 */
sl@0
   589
sl@0
   590
void
sl@0
   591
TclpSetInitialEncodings()
sl@0
   592
{
sl@0
   593
	CONST char *encoding = NULL;
sl@0
   594
	int i, setSysEncCode = TCL_ERROR;
sl@0
   595
	Tcl_Obj *pathPtr;
sl@0
   596
sl@0
   597
	/*
sl@0
   598
	 * Determine the current encoding from the LC_* or LANG environment
sl@0
   599
	 * variables.  We previously used setlocale() to determine the locale,
sl@0
   600
	 * but this does not work on some systems (e.g. Linux/i386 RH 5.0).
sl@0
   601
	 */
sl@0
   602
#ifdef HAVE_LANGINFO
sl@0
   603
	if (
sl@0
   604
#ifdef WEAK_IMPORT_NL_LANGINFO
sl@0
   605
		nl_langinfo != NULL &&
sl@0
   606
#endif
sl@0
   607
		setlocale(LC_CTYPE, "") != NULL) {
sl@0
   608
	    Tcl_DString ds;
sl@0
   609
sl@0
   610
	    /*
sl@0
   611
	     * Use a DString so we can overwrite it in name compatability
sl@0
   612
	     * checks below.
sl@0
   613
	     */
sl@0
   614
sl@0
   615
	    Tcl_DStringInit(&ds);
sl@0
   616
	    encoding = Tcl_DStringAppend(&ds, nl_langinfo(CODESET), -1);
sl@0
   617
sl@0
   618
	    Tcl_UtfToLower(Tcl_DStringValue(&ds));
sl@0
   619
#ifdef HAVE_LANGINFO_DEBUG
sl@0
   620
	    fprintf(stderr, "encoding '%s'\r\n", encoding);
sl@0
   621
#endif
sl@0
   622
	    if (encoding[0] == 'i' && encoding[1] == 's' && encoding[2] == 'o'
sl@0
   623
		    && encoding[3] == '-') {
sl@0
   624
		char *p, *q;
sl@0
   625
		/* need to strip '-' from iso-* encoding */
sl@0
   626
		for(p = Tcl_DStringValue(&ds)+3, q = Tcl_DStringValue(&ds)+4;
sl@0
   627
		    *p; *p++ = *q++);
sl@0
   628
	    } else if (encoding[0] == 'i' && encoding[1] == 'b'
sl@0
   629
		    && encoding[2] == 'm' && encoding[3] >= '0'
sl@0
   630
		    && encoding[3] <= '9') {
sl@0
   631
		char *p, *q;
sl@0
   632
		/* if langinfo reports "ibm*" we should use "cp*" */
sl@0
   633
		p = Tcl_DStringValue(&ds);
sl@0
   634
		*p++ = 'c'; *p++ = 'p';
sl@0
   635
		for(q = p+1; *p ; *p++ = *q++);
sl@0
   636
	    } else if ((*encoding == '\0')
sl@0
   637
		    || !strcmp(encoding, "ansi_x3.4-1968")) {
sl@0
   638
		/* Use iso8859-1 for empty or 'ansi_x3.4-1968' encoding */
sl@0
   639
		encoding = "iso8859-1";
sl@0
   640
	    }
sl@0
   641
#ifdef HAVE_LANGINFO_DEBUG
sl@0
   642
	    fprintf(stderr, " ?%s?\r\n", encoding);
sl@0
   643
#endif
sl@0
   644
	    setSysEncCode = Tcl_SetSystemEncoding(NULL, encoding);
sl@0
   645
	    if (setSysEncCode != TCL_OK) {
sl@0
   646
		/*
sl@0
   647
		 * If this doesn't return TCL_OK, the encoding returned by
sl@0
   648
		 * nl_langinfo or as we translated it wasn't accepted.  Do
sl@0
   649
		 * this fallback check.  If this fails, we will enter the
sl@0
   650
		 * old fallback below.
sl@0
   651
		 */
sl@0
   652
sl@0
   653
		for (i = 0; localeTable[i].lang != NULL; i++) {
sl@0
   654
		    if (strcmp(localeTable[i].lang, encoding) == 0) {
sl@0
   655
			setSysEncCode = Tcl_SetSystemEncoding(NULL,
sl@0
   656
				localeTable[i].encoding);
sl@0
   657
			break;
sl@0
   658
		    }
sl@0
   659
		}
sl@0
   660
	    }
sl@0
   661
#ifdef HAVE_LANGINFO_DEBUG
sl@0
   662
	    fprintf(stderr, " => '%s'\n", encoding);
sl@0
   663
#endif
sl@0
   664
	    Tcl_DStringFree(&ds);
sl@0
   665
	}
sl@0
   666
#ifdef HAVE_LANGINFO_DEBUG
sl@0
   667
	else {
sl@0
   668
	    fprintf(stderr, "setlocale returned NULL\n");
sl@0
   669
	}
sl@0
   670
#endif
sl@0
   671
#endif /* HAVE_LANGINFO */
sl@0
   672
sl@0
   673
	if (setSysEncCode != TCL_OK) {
sl@0
   674
	    /*
sl@0
   675
	     * Classic fallback check.  This tries a homebrew algorithm to
sl@0
   676
	     * determine what encoding should be used based on env vars.
sl@0
   677
	     */
sl@0
   678
	    char *langEnv = getenv("LC_ALL");
sl@0
   679
	    encoding = NULL;
sl@0
   680
sl@0
   681
	    if (langEnv == NULL || langEnv[0] == '\0') {
sl@0
   682
		langEnv = getenv("LC_CTYPE");
sl@0
   683
	    }
sl@0
   684
	    if (langEnv == NULL || langEnv[0] == '\0') {
sl@0
   685
		langEnv = getenv("LANG");
sl@0
   686
	    }
sl@0
   687
	    if (langEnv == NULL || langEnv[0] == '\0') {
sl@0
   688
		langEnv = NULL;
sl@0
   689
	    }
sl@0
   690
sl@0
   691
	    if (langEnv != NULL) {
sl@0
   692
		for (i = 0; localeTable[i].lang != NULL; i++) {
sl@0
   693
		    if (strcmp(localeTable[i].lang, langEnv) == 0) {
sl@0
   694
			encoding = localeTable[i].encoding;
sl@0
   695
			break;
sl@0
   696
		    }
sl@0
   697
		}
sl@0
   698
		/*
sl@0
   699
		 * There was no mapping in the locale table.  If there is an
sl@0
   700
		 * encoding subfield, we can try to guess from that.
sl@0
   701
		 */
sl@0
   702
sl@0
   703
		if (encoding == NULL) {
sl@0
   704
		    char *p;
sl@0
   705
		    for (p = langEnv; *p != '\0'; p++) {
sl@0
   706
			if (*p == '.') {
sl@0
   707
			    p++;
sl@0
   708
			    break;
sl@0
   709
			}
sl@0
   710
		    }
sl@0
   711
		    if (*p != '\0') {
sl@0
   712
			Tcl_DString ds;
sl@0
   713
			Tcl_DStringInit(&ds);
sl@0
   714
			encoding = Tcl_DStringAppend(&ds, p, -1);
sl@0
   715
sl@0
   716
			Tcl_UtfToLower(Tcl_DStringValue(&ds));
sl@0
   717
			setSysEncCode = Tcl_SetSystemEncoding(NULL, encoding);
sl@0
   718
			if (setSysEncCode != TCL_OK) {
sl@0
   719
			    encoding = NULL;
sl@0
   720
			}
sl@0
   721
			Tcl_DStringFree(&ds);
sl@0
   722
		    }
sl@0
   723
		}
sl@0
   724
#ifdef HAVE_LANGINFO_DEBUG
sl@0
   725
		fprintf(stderr, "encoding fallback check '%s' => '%s'\n",
sl@0
   726
			langEnv, encoding);
sl@0
   727
#endif
sl@0
   728
	    }
sl@0
   729
	    if (setSysEncCode != TCL_OK) {
sl@0
   730
		if (encoding == NULL) {
sl@0
   731
		    encoding = TCL_DEFAULT_ENCODING;
sl@0
   732
		}
sl@0
   733
sl@0
   734
		Tcl_SetSystemEncoding(NULL, encoding);
sl@0
   735
	    }
sl@0
   736
sl@0
   737
	    /*
sl@0
   738
	     * Initialize the C library's locale subsystem.  This is required
sl@0
   739
	     * for input methods to work properly on X11.  We only do this for
sl@0
   740
	     * LC_CTYPE because that's the necessary one, and we don't want to
sl@0
   741
	     * affect LC_TIME here.  The side effect of setting the default
sl@0
   742
	     * locale should be to load any locale specific modules that are
sl@0
   743
	     * needed by X.  [BUG: 5422 3345 4236 2522 2521].
sl@0
   744
	     * In HAVE_LANGINFO, this call is already done above.
sl@0
   745
	     */
sl@0
   746
#ifndef HAVE_LANGINFO
sl@0
   747
	    setlocale(LC_CTYPE, "");
sl@0
   748
#endif
sl@0
   749
	}
sl@0
   750
sl@0
   751
	/*
sl@0
   752
	 * In case the initial locale is not "C", ensure that the numeric
sl@0
   753
	 * processing is done in "C" locale regardless.  This is needed because
sl@0
   754
	 * Tcl relies on routines like strtod, but should not have locale
sl@0
   755
	 * dependent behavior.
sl@0
   756
	 */
sl@0
   757
sl@0
   758
	setlocale(LC_NUMERIC, "C");
sl@0
   759
sl@0
   760
    if ((libraryPathEncodingFixed == 0) && strcmp("identity",
sl@0
   761
	    Tcl_GetEncodingName(Tcl_GetEncoding(NULL, NULL))) ) {
sl@0
   762
	/*
sl@0
   763
	 * Until the system encoding was actually set, the library path was
sl@0
   764
	 * actually in the native multi-byte encoding, and not really UTF-8
sl@0
   765
	 * as advertised.  We cheated as follows:
sl@0
   766
	 *
sl@0
   767
	 * 1. It was safe to allow the Tcl_SetSystemEncoding() call to 
sl@0
   768
	 * append the ASCII chars that make up the encoding's filename to 
sl@0
   769
	 * the names (in the native encoding) of directories in the library 
sl@0
   770
	 * path, since all Unix multi-byte encodings have ASCII in the
sl@0
   771
	 * beginning.
sl@0
   772
	 *
sl@0
   773
	 * 2. To open the encoding file, the native bytes in the file name
sl@0
   774
	 * were passed to the OS, without translating from UTF-8 to native,
sl@0
   775
	 * because the name was already in the native encoding.
sl@0
   776
	 *
sl@0
   777
	 * Now that the system encoding was actually successfully set,
sl@0
   778
	 * translate all the names in the library path to UTF-8.  That way,
sl@0
   779
	 * next time we search the library path, we'll translate the names 
sl@0
   780
	 * from UTF-8 to the system encoding which will be the native 
sl@0
   781
	 * encoding.
sl@0
   782
	 */
sl@0
   783
sl@0
   784
	pathPtr = TclGetLibraryPath();
sl@0
   785
	if (pathPtr != NULL) {
sl@0
   786
	    int objc;
sl@0
   787
	    Tcl_Obj **objv;
sl@0
   788
	    
sl@0
   789
	    objc = 0;
sl@0
   790
	    Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
sl@0
   791
	    for (i = 0; i < objc; i++) {
sl@0
   792
		int length;
sl@0
   793
		char *string;
sl@0
   794
		Tcl_DString ds;
sl@0
   795
sl@0
   796
		string = Tcl_GetStringFromObj(objv[i], &length);
sl@0
   797
		Tcl_ExternalToUtfDString(NULL, string, length, &ds);
sl@0
   798
		Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds), 
sl@0
   799
			Tcl_DStringLength(&ds));
sl@0
   800
		Tcl_DStringFree(&ds);
sl@0
   801
	    }
sl@0
   802
	}
sl@0
   803
sl@0
   804
	libraryPathEncodingFixed = 1;
sl@0
   805
    }
sl@0
   806
    
sl@0
   807
    /* This is only ever called from the startup thread */
sl@0
   808
    if (binaryEncoding == NULL) {
sl@0
   809
	/*
sl@0
   810
	 * Keep the iso8859-1 encoding preloaded.  The IO package uses
sl@0
   811
	 * it for gets on a binary channel.
sl@0
   812
	 */
sl@0
   813
	binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
sl@0
   814
    }
sl@0
   815
}
sl@0
   816

sl@0
   817
/*
sl@0
   818
 *---------------------------------------------------------------------------
sl@0
   819
 *
sl@0
   820
 * TclpSetVariables --
sl@0
   821
 *
sl@0
   822
 *	Performs platform-specific interpreter initialization related to
sl@0
   823
 *	the tcl_library and tcl_platform variables, and other platform-
sl@0
   824
 *	specific things.
sl@0
   825
 *
sl@0
   826
 * Results:
sl@0
   827
 *	None.
sl@0
   828
 *
sl@0
   829
 * Side effects:
sl@0
   830
 *	Sets "tclDefaultLibrary", "tcl_pkgPath", and "tcl_platform" Tcl
sl@0
   831
 *	variables.
sl@0
   832
 *
sl@0
   833
 *----------------------------------------------------------------------
sl@0
   834
 */
sl@0
   835
sl@0
   836
void
sl@0
   837
TclpSetVariables(interp)
sl@0
   838
    Tcl_Interp *interp;
sl@0
   839
{
sl@0
   840
#ifndef NO_UNAME
sl@0
   841
    struct utsname name;
sl@0
   842
#endif
sl@0
   843
    int unameOK;
sl@0
   844
    CONST char *user;
sl@0
   845
    Tcl_DString ds;
sl@0
   846
sl@0
   847
#ifdef HAVE_COREFOUNDATION
sl@0
   848
    char tclLibPath[MAXPATHLEN + 1];
sl@0
   849
sl@0
   850
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020
sl@0
   851
    /*
sl@0
   852
     * Set msgcat fallback locale to current CFLocale identifier.
sl@0
   853
     */
sl@0
   854
    CFLocaleRef localeRef;
sl@0
   855
    
sl@0
   856
    if (CFLocaleCopyCurrent != NULL && CFLocaleGetIdentifier != NULL &&
sl@0
   857
	    (localeRef = CFLocaleCopyCurrent())) {
sl@0
   858
	CFStringRef locale = CFLocaleGetIdentifier(localeRef);
sl@0
   859
sl@0
   860
	if (locale) {
sl@0
   861
	    char loc[256];
sl@0
   862
sl@0
   863
	    if (CFStringGetCString(locale, loc, 256, kCFStringEncodingUTF8)) {
sl@0
   864
		if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) {
sl@0
   865
		    Tcl_ResetResult(interp);
sl@0
   866
		}
sl@0
   867
		Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY);
sl@0
   868
	    }
sl@0
   869
	}
sl@0
   870
	CFRelease(localeRef);
sl@0
   871
    }
sl@0
   872
#endif
sl@0
   873
sl@0
   874
    if (MacOSXGetLibraryPath(interp, MAXPATHLEN, tclLibPath) == TCL_OK) {
sl@0
   875
        CONST char *str;
sl@0
   876
        Tcl_DString ds;
sl@0
   877
        CFBundleRef bundleRef;
sl@0
   878
sl@0
   879
        Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, 
sl@0
   880
                TCL_GLOBAL_ONLY);
sl@0
   881
        Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath,
sl@0
   882
                TCL_GLOBAL_ONLY);
sl@0
   883
        Tcl_SetVar(interp, "tcl_pkgPath", " ",
sl@0
   884
                TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   885
        str = TclGetEnv("DYLD_FRAMEWORK_PATH", &ds);
sl@0
   886
        if ((str != NULL) && (str[0] != '\0')) {
sl@0
   887
            char *p = Tcl_DStringValue(&ds);
sl@0
   888
            /* convert DYLD_FRAMEWORK_PATH from colon to space separated */
sl@0
   889
            do {
sl@0
   890
                if(*p == ':') *p = ' ';
sl@0
   891
            } while (*p++);
sl@0
   892
            Tcl_SetVar(interp, "tcl_pkgPath", Tcl_DStringValue(&ds),
sl@0
   893
                    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   894
            Tcl_SetVar(interp, "tcl_pkgPath", " ",
sl@0
   895
                    TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   896
            Tcl_DStringFree(&ds);
sl@0
   897
        }
sl@0
   898
        if ((bundleRef = CFBundleGetMainBundle())) {
sl@0
   899
            CFURLRef frameworksURL;
sl@0
   900
            Tcl_StatBuf statBuf;
sl@0
   901
            if((frameworksURL = CFBundleCopyPrivateFrameworksURL(bundleRef))) {
sl@0
   902
                if(CFURLGetFileSystemRepresentation(frameworksURL, TRUE,
sl@0
   903
                            (unsigned char*) tclLibPath, MAXPATHLEN) &&
sl@0
   904
                        ! TclOSstat(tclLibPath, &statBuf) &&
sl@0
   905
                        S_ISDIR(statBuf.st_mode)) {
sl@0
   906
                    Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath,
sl@0
   907
                            TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   908
                    Tcl_SetVar(interp, "tcl_pkgPath", " ",
sl@0
   909
                            TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   910
                }
sl@0
   911
                CFRelease(frameworksURL);
sl@0
   912
            }
sl@0
   913
            if((frameworksURL = CFBundleCopySharedFrameworksURL(bundleRef))) {
sl@0
   914
                if(CFURLGetFileSystemRepresentation(frameworksURL, TRUE,
sl@0
   915
                            (unsigned char*) tclLibPath, MAXPATHLEN) &&
sl@0
   916
                        ! TclOSstat(tclLibPath, &statBuf) &&
sl@0
   917
                        S_ISDIR(statBuf.st_mode)) {
sl@0
   918
                    Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath,
sl@0
   919
                            TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   920
                    Tcl_SetVar(interp, "tcl_pkgPath", " ",
sl@0
   921
                            TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   922
                }
sl@0
   923
                CFRelease(frameworksURL);
sl@0
   924
            }
sl@0
   925
        }
sl@0
   926
        Tcl_SetVar(interp, "tcl_pkgPath", pkgPath,
sl@0
   927
                TCL_GLOBAL_ONLY | TCL_APPEND_VALUE);
sl@0
   928
    } else
sl@0
   929
#endif /* HAVE_COREFOUNDATION */
sl@0
   930
    {
sl@0
   931
        Tcl_SetVar(interp, "tclDefaultLibrary", defaultLibraryDir, 
sl@0
   932
                TCL_GLOBAL_ONLY);
sl@0
   933
        Tcl_SetVar(interp, "tcl_pkgPath", pkgPath, TCL_GLOBAL_ONLY);
sl@0
   934
    }
sl@0
   935
sl@0
   936
#ifdef DJGPP
sl@0
   937
    Tcl_SetVar2(interp, "tcl_platform", "platform", "dos", TCL_GLOBAL_ONLY);
sl@0
   938
#else
sl@0
   939
    Tcl_SetVar2(interp, "tcl_platform", "platform", "symbian", TCL_GLOBAL_ONLY);
sl@0
   940
#endif
sl@0
   941
    unameOK = 0;
sl@0
   942
#ifndef NO_UNAME
sl@0
   943
    if (uname(&name) >= 0) {
sl@0
   944
	CONST char *native;
sl@0
   945
	
sl@0
   946
	unameOK = 1;
sl@0
   947
sl@0
   948
	native = Tcl_ExternalToUtfDString(NULL, name.sysname, -1, &ds);
sl@0
   949
	Tcl_SetVar2(interp, "tcl_platform", "os", native, TCL_GLOBAL_ONLY);
sl@0
   950
	Tcl_DStringFree(&ds);
sl@0
   951
	
sl@0
   952
	/*
sl@0
   953
	 * The following code is a special hack to handle differences in
sl@0
   954
	 * the way version information is returned by uname.  On most
sl@0
   955
	 * systems the full version number is available in name.release.
sl@0
   956
	 * However, under AIX the major version number is in
sl@0
   957
	 * name.version and the minor version number is in name.release.
sl@0
   958
	 */
sl@0
   959
sl@0
   960
	if ((strchr(name.release, '.') != NULL)
sl@0
   961
		|| !isdigit(UCHAR(name.version[0]))) {	/* INTL: digit */
sl@0
   962
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,
sl@0
   963
		    TCL_GLOBAL_ONLY);
sl@0
   964
	} else {
sl@0
   965
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.version,
sl@0
   966
		    TCL_GLOBAL_ONLY);
sl@0
   967
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", ".",
sl@0
   968
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);
sl@0
   969
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,
sl@0
   970
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);
sl@0
   971
	}
sl@0
   972
	Tcl_SetVar2(interp, "tcl_platform", "machine", name.machine,
sl@0
   973
		TCL_GLOBAL_ONLY);
sl@0
   974
    }
sl@0
   975
#ifdef __SYMBIAN32__
sl@0
   976
	// Symbian P.I.P.S. is a "flavour of" unix in that it's an emulation layer. 
sl@0
   977
    Tcl_SetVar2(interp, "tcl_platform", "osSystemName", name.sysname, TCL_GLOBAL_ONLY);
sl@0
   978
#endif    
sl@0
   979
#endif
sl@0
   980
    if (!unameOK) {
sl@0
   981
	  Tcl_SetVar2(interp, "tcl_platform", "os", "", TCL_GLOBAL_ONLY);
sl@0
   982
	  Tcl_SetVar2(interp, "tcl_platform", "osVersion", "", TCL_GLOBAL_ONLY);
sl@0
   983
	  Tcl_SetVar2(interp, "tcl_platform", "machine", "", TCL_GLOBAL_ONLY);
sl@0
   984
    }
sl@0
   985
sl@0
   986
    /*
sl@0
   987
     * Copy USER or LOGNAME environment variable into tcl_platform(user)
sl@0
   988
     */
sl@0
   989
sl@0
   990
    Tcl_DStringInit(&ds);
sl@0
   991
    user = TclGetEnv("USER", &ds);
sl@0
   992
    if (user == NULL) {
sl@0
   993
	user = TclGetEnv("LOGNAME", &ds);
sl@0
   994
	if (user == NULL) {
sl@0
   995
	    user = "";
sl@0
   996
	}
sl@0
   997
    }
sl@0
   998
    Tcl_SetVar2(interp, "tcl_platform", "user", user, TCL_GLOBAL_ONLY);
sl@0
   999
    Tcl_DStringFree(&ds);
sl@0
  1000
sl@0
  1001
}
sl@0
  1002

sl@0
  1003
/*
sl@0
  1004
 *----------------------------------------------------------------------
sl@0
  1005
 *
sl@0
  1006
 * TclpFindVariable --
sl@0
  1007
 *
sl@0
  1008
 *	Locate the entry in environ for a given name.  On Unix this 
sl@0
  1009
 *	routine is case sensetive, on Windows this matches mixed case.
sl@0
  1010
 *
sl@0
  1011
 * Results:
sl@0
  1012
 *	The return value is the index in environ of an entry with the
sl@0
  1013
 *	name "name", or -1 if there is no such entry.   The integer at
sl@0
  1014
 *	*lengthPtr is filled in with the length of name (if a matching
sl@0
  1015
 *	entry is found) or the length of the environ array (if no matching
sl@0
  1016
 *	entry is found).
sl@0
  1017
 *
sl@0
  1018
 * Side effects:
sl@0
  1019
 *	None.
sl@0
  1020
 *
sl@0
  1021
 *----------------------------------------------------------------------
sl@0
  1022
 */
sl@0
  1023
sl@0
  1024
int
sl@0
  1025
TclpFindVariable(name, lengthPtr)
sl@0
  1026
    CONST char *name;		/* Name of desired environment variable
sl@0
  1027
				 * (native). */
sl@0
  1028
    int *lengthPtr;		/* Used to return length of name (for
sl@0
  1029
				 * successful searches) or number of non-NULL
sl@0
  1030
				 * entries in environ (for unsuccessful
sl@0
  1031
				 * searches). */
sl@0
  1032
{
sl@0
  1033
    int i, result = -1;
sl@0
  1034
    register CONST char *env, *p1, *p2;
sl@0
  1035
    Tcl_DString envString;
sl@0
  1036
sl@0
  1037
    Tcl_DStringInit(&envString);
sl@0
  1038
    for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) {
sl@0
  1039
	p1 = Tcl_ExternalToUtfDString(NULL, env, -1, &envString);
sl@0
  1040
	p2 = name;
sl@0
  1041
sl@0
  1042
	for (; *p2 == *p1; p1++, p2++) {
sl@0
  1043
	    /* NULL loop body. */
sl@0
  1044
	}
sl@0
  1045
	if ((*p1 == '=') && (*p2 == '\0')) {
sl@0
  1046
	    *lengthPtr = p2 - name;
sl@0
  1047
	    result = i;
sl@0
  1048
	    goto done;
sl@0
  1049
	}
sl@0
  1050
	
sl@0
  1051
	Tcl_DStringFree(&envString);
sl@0
  1052
    }
sl@0
  1053
    
sl@0
  1054
    *lengthPtr = i;
sl@0
  1055
sl@0
  1056
    done:
sl@0
  1057
    Tcl_DStringFree(&envString);
sl@0
  1058
    return result;
sl@0
  1059
}
sl@0
  1060

sl@0
  1061
/*
sl@0
  1062
 *----------------------------------------------------------------------
sl@0
  1063
 *
sl@0
  1064
 * Tcl_Init --
sl@0
  1065
 *
sl@0
  1066
 *	This procedure is typically invoked by Tcl_AppInit procedures
sl@0
  1067
 *	to find and source the "init.tcl" script, which should exist
sl@0
  1068
 *	somewhere on the Tcl library path.
sl@0
  1069
 *
sl@0
  1070
 * Results:
sl@0
  1071
 *	Returns a standard Tcl completion code and sets the interp's
sl@0
  1072
 *	result if there is an error.
sl@0
  1073
 *
sl@0
  1074
 * Side effects:
sl@0
  1075
 *	Depends on what's in the init.tcl script.
sl@0
  1076
 *
sl@0
  1077
 *----------------------------------------------------------------------
sl@0
  1078
 */
sl@0
  1079
sl@0
  1080
EXPORT_C int
sl@0
  1081
Tcl_Init(interp)
sl@0
  1082
    Tcl_Interp *interp;		/* Interpreter to initialize. */
sl@0
  1083
{
sl@0
  1084
    Tcl_Obj *pathPtr;
sl@0
  1085
sl@0
  1086
    if (tclPreInitScript != NULL) {
sl@0
  1087
	if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) {
sl@0
  1088
	    return (TCL_ERROR);
sl@0
  1089
	};
sl@0
  1090
    }
sl@0
  1091
    
sl@0
  1092
    pathPtr = TclGetLibraryPath();
sl@0
  1093
    if (pathPtr == NULL) {
sl@0
  1094
	pathPtr = Tcl_NewObj();
sl@0
  1095
    }
sl@0
  1096
    Tcl_IncrRefCount(pathPtr);
sl@0
  1097
    Tcl_SetVar2Ex(interp, "tcl_libPath", NULL, pathPtr, TCL_GLOBAL_ONLY);
sl@0
  1098
    Tcl_DecrRefCount(pathPtr);
sl@0
  1099
    return Tcl_Eval(interp, initScript);
sl@0
  1100
}
sl@0
  1101

sl@0
  1102
/*
sl@0
  1103
 *----------------------------------------------------------------------
sl@0
  1104
 *
sl@0
  1105
 * Tcl_SourceRCFile --
sl@0
  1106
 *
sl@0
  1107
 *	This procedure is typically invoked by Tcl_Main of Tk_Main
sl@0
  1108
 *	procedure to source an application specific rc file into the
sl@0
  1109
 *	interpreter at startup time.
sl@0
  1110
 *
sl@0
  1111
 * Results:
sl@0
  1112
 *	None.
sl@0
  1113
 *
sl@0
  1114
 * Side effects:
sl@0
  1115
 *	Depends on what's in the rc script.
sl@0
  1116
 *
sl@0
  1117
 *----------------------------------------------------------------------
sl@0
  1118
 */
sl@0
  1119
sl@0
  1120
EXPORT_C void
sl@0
  1121
Tcl_SourceRCFile(interp)
sl@0
  1122
    Tcl_Interp *interp;		/* Interpreter to source rc file into. */
sl@0
  1123
{
sl@0
  1124
    Tcl_DString temp;
sl@0
  1125
    CONST char *fileName;
sl@0
  1126
    Tcl_Channel errChannel;
sl@0
  1127
sl@0
  1128
    fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY);
sl@0
  1129
sl@0
  1130
    if (fileName != NULL) {
sl@0
  1131
        Tcl_Channel c;
sl@0
  1132
	CONST char *fullName;
sl@0
  1133
sl@0
  1134
        Tcl_DStringInit(&temp);
sl@0
  1135
	fullName = Tcl_TranslateFileName(interp, fileName, &temp);
sl@0
  1136
	if (fullName == NULL) {
sl@0
  1137
	    /*
sl@0
  1138
	     * Couldn't translate the file name (e.g. it referred to a
sl@0
  1139
	     * bogus user or there was no HOME environment variable).
sl@0
  1140
	     * Just do nothing.
sl@0
  1141
	     */
sl@0
  1142
	} else {
sl@0
  1143
sl@0
  1144
	    /*
sl@0
  1145
	     * Test for the existence of the rc file before trying to read it.
sl@0
  1146
	     */
sl@0
  1147
sl@0
  1148
            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
sl@0
  1149
            if (c != (Tcl_Channel) NULL) {
sl@0
  1150
                Tcl_Close(NULL, c);
sl@0
  1151
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
sl@0
  1152
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
sl@0
  1153
		    if (errChannel) {
sl@0
  1154
			Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
sl@0
  1155
			Tcl_WriteChars(errChannel, "\n", 1);
sl@0
  1156
		    }
sl@0
  1157
		}
sl@0
  1158
	    }
sl@0
  1159
	}
sl@0
  1160
        Tcl_DStringFree(&temp);
sl@0
  1161
    }
sl@0
  1162
}
sl@0
  1163

sl@0
  1164
/*
sl@0
  1165
 *----------------------------------------------------------------------
sl@0
  1166
 *
sl@0
  1167
 * TclpCheckStackSpace --
sl@0
  1168
 *
sl@0
  1169
 *	Detect if we are about to blow the stack.  Called before an 
sl@0
  1170
 *	evaluation can happen when nesting depth is checked.
sl@0
  1171
 *
sl@0
  1172
 * Results:
sl@0
  1173
 *	1 if there is enough stack space to continue; 0 if not.
sl@0
  1174
 *
sl@0
  1175
 * Side effects:
sl@0
  1176
 *	None.
sl@0
  1177
 *
sl@0
  1178
 *----------------------------------------------------------------------
sl@0
  1179
 */
sl@0
  1180
sl@0
  1181
int
sl@0
  1182
TclpCheckStackSpace()
sl@0
  1183
{
sl@0
  1184
    /*
sl@0
  1185
     * This function is unimplemented on Unix platforms.
sl@0
  1186
     */
sl@0
  1187
sl@0
  1188
    return 1;
sl@0
  1189
}
sl@0
  1190

sl@0
  1191
/*
sl@0
  1192
 *----------------------------------------------------------------------
sl@0
  1193
 *
sl@0
  1194
 * MacOSXGetLibraryPath --
sl@0
  1195
 *
sl@0
  1196
 *	If we have a bundle structure for the Tcl installation,
sl@0
  1197
 *	then check there first to see if we can find the libraries
sl@0
  1198
 *	there.
sl@0
  1199
 *
sl@0
  1200
 * Results:
sl@0
  1201
 *	TCL_OK if we have found the tcl library; TCL_ERROR otherwise.
sl@0
  1202
 *
sl@0
  1203
 * Side effects:
sl@0
  1204
 *	Same as for Tcl_MacOSXOpenVersionedBundleResources.
sl@0
  1205
 *
sl@0
  1206
 *----------------------------------------------------------------------
sl@0
  1207
 */
sl@0
  1208
sl@0
  1209
#ifdef HAVE_COREFOUNDATION
sl@0
  1210
static int
sl@0
  1211
MacOSXGetLibraryPath(Tcl_Interp *interp, int maxPathLen, char *tclLibPath)
sl@0
  1212
{
sl@0
  1213
    int foundInFramework = TCL_ERROR;
sl@0
  1214
#ifdef TCL_FRAMEWORK
sl@0
  1215
    foundInFramework = Tcl_MacOSXOpenVersionedBundleResources(interp, 
sl@0
  1216
	"com.tcltk.tcllibrary", TCL_FRAMEWORK_VERSION, 0, maxPathLen, tclLibPath);
sl@0
  1217
#endif
sl@0
  1218
    return foundInFramework;
sl@0
  1219
}
sl@0
  1220
#endif /* HAVE_COREFOUNDATION */