diff options
Diffstat (limited to 'win/tclAppInit.c')
| -rw-r--r-- | win/tclAppInit.c | 243 | 
1 files changed, 160 insertions, 83 deletions
| diff --git a/win/tclAppInit.c b/win/tclAppInit.c index d157656..a6c1a67 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -1,35 +1,66 @@ -/*  +/*   * tclAppInit.c --   *   *	Provides a default version of the main program and Tcl_AppInit - *	procedure for Tcl applications (without Tk).  Note that this - *	program must be built in Win32 console mode to work properly. - * - * Copyright (c) 1996-1997 by Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. + *	procedure for tclsh and other Tcl-based applications (without Tk). + *	Note that this program must be built in Win32 console mode to work + *	properly.   * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 Scriptics Corporation.   * - * RCS: @(#) $Id: tclAppInit.c,v 1.5 1999/04/16 00:48:07 stanton Exp $ + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES.   */  #include "tcl.h" +#define WIN32_LEAN_AND_MEAN  #include <windows.h> +#undef WIN32_LEAN_AND_MEAN  #include <locale.h> +#include <stdlib.h> +#include <tchar.h>  #ifdef TCL_TEST -extern int		Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int		Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); -extern int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#ifdef TCL_THREADS -extern int		TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif +extern Tcl_PackageInitProc Tcltest_Init; +extern Tcl_PackageInitProc Tcltest_SafeInit;  #endif /* TCL_TEST */ -static void		setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr)); +#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES +extern Tcl_PackageInitProc Registry_Init; +extern Tcl_PackageInitProc Dde_Init; +extern Tcl_PackageInitProc Dde_SafeInit; +#endif +#ifdef TCL_BROKEN_MAINARGS +int _CRT_glob = 0; +static void setargv(int *argcPtr, TCHAR ***argvPtr); +#endif /* TCL_BROKEN_MAINARGS */ + +/* + * The following #if block allows you to change the AppInit function by using + * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The + * #if checks for that #define and uses Tcl_AppInit if it does not exist. + */ + +#ifndef TCL_LOCAL_APPINIT +#define TCL_LOCAL_APPINIT Tcl_AppInit +#endif +#ifndef MODULE_SCOPE +#   define MODULE_SCOPE extern +#endif +MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); + +/* + * The following #if block allows you to change how Tcl finds the startup + * script, prime the library or encoding paths, fiddle with the argv, etc., + * without needing to rewrite Tcl_Main() + */ + +#ifdef TCL_LOCAL_MAIN_HOOK +MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); +#endif  /*   *---------------------------------------------------------------------- @@ -39,45 +70,76 @@ static void		setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));   *	This is the main program for the application.   *   * Results: - *	None: Tcl_Main never returns here, so this procedure never - *	returns either. + *	None: Tcl_Main never returns here, so this procedure never returns + *	either.   *   * Side effects: - *	Whatever the application does. + *	Just about anything, since from here we call arbitrary Tcl code.   *   *----------------------------------------------------------------------   */ +#ifdef TCL_BROKEN_MAINARGS +int +main( +    int argc,			/* Number of command-line arguments. */ +    char *dummy[])		/* Not used. */ +{ +    TCHAR **argv; +#else  int -main(argc, argv) -    int argc;			/* Number of command-line arguments. */ -    char **argv;		/* Values of command-line arguments. */ +_tmain( +    int argc,			/* Number of command-line arguments. */ +    TCHAR *argv[])		/* Values of command-line arguments. */  { +#endif +    TCHAR *p; +      /* -     * Set up the default locale to be standard "C" locale so parsing -     * is performed correctly. +     * Set up the default locale to be standard "C" locale so parsing is +     * performed correctly.       */      setlocale(LC_ALL, "C"); + +#ifdef TCL_BROKEN_MAINARGS +    /* +     * Get our args from the c-runtime. Ignore command line. +     */ +      setargv(&argc, &argv); +#endif -    Tcl_Main(argc, argv, Tcl_AppInit); +    /* +     * Forward slashes substituted for backslashes. +     */ + +    for (p = argv[0]; *p != '\0'; p++) { +	if (*p == '\\') { +	    *p = '/'; +	} +    } + +#ifdef TCL_LOCAL_MAIN_HOOK +    TCL_LOCAL_MAIN_HOOK(&argc, &argv); +#endif + +    Tcl_Main(argc, argv, TCL_LOCAL_APPINIT);      return 0;			/* Needed only to prevent compiler warning. */  } -  /*   *----------------------------------------------------------------------   *   * Tcl_AppInit --   * - *	This procedure performs application-specific initialization. - *	Most applications, especially those that incorporate additional - *	packages, will have their own version of this procedure. + *	This procedure performs application-specific initialization. Most + *	applications, especially those that incorporate additional packages, + *	will have their own version of this procedure.   *   * Results: - *	Returns a standard Tcl completion code, and leaves an error - *	message in the interp's result if an error occurs. + *	Returns a standard Tcl completion code, and leaves an error message in + *	the interp's result if an error occurs.   *   * Side effects:   *	Depends on the startup script. @@ -86,58 +148,58 @@ main(argc, argv)   */  int -Tcl_AppInit(interp) -    Tcl_Interp *interp;		/* Interpreter for application. */ +Tcl_AppInit( +    Tcl_Interp *interp)		/* Interpreter for application. */  { -    if (Tcl_Init(interp) == TCL_ERROR) { +    if ((Tcl_Init)(interp) == TCL_ERROR) {  	return TCL_ERROR;      } -#ifdef TCL_TEST -    if (Tcltest_Init(interp) == TCL_ERROR) { -	return TCL_ERROR; -    } -    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, -            (Tcl_PackageInitProc *) NULL); -    if (TclObjTest_Init(interp) == TCL_ERROR) { +#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES +    if (Registry_Init(interp) == TCL_ERROR) {  	return TCL_ERROR;      } -#ifdef TCL_THREADS -    if (TclThread_Init(interp) == TCL_ERROR) { +    Tcl_StaticPackage(interp, "registry", Registry_Init, NULL); + +    if (Dde_Init(interp) == TCL_ERROR) {  	return TCL_ERROR;      } +    Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit);  #endif -    if (Procbodytest_Init(interp) == TCL_ERROR) { + +#ifdef TCL_TEST +    if (Tcltest_Init(interp) == TCL_ERROR) {  	return TCL_ERROR;      } -    Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init, -            Procbodytest_SafeInit); +    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit);  #endif /* TCL_TEST */      /* -     * Call the init procedures for included packages.  Each call should -     * look like this: +     * Call the init procedures for included packages. Each call should look +     * like this:       *       * if (Mod_Init(interp) == TCL_ERROR) {       *     return TCL_ERROR;       * }       * -     * where "Mod" is the name of the module. +     * where "Mod" is the name of the module. (Dynamically-loadable packages +     * should have the same entry-point name.)       */      /* -     * Call Tcl_CreateCommand for application-specific commands, if -     * they weren't already created by the init procedures called above. +     * Call Tcl_CreateCommand for application-specific commands, if they +     * weren't already created by the init procedures called above.       */      /* -     * Specify a user-specific startup file to invoke if the application -     * is run interactively.  Typically the startup file is "~/.apprc" -     * where "app" is the name of the application.  If this line is deleted -     * then no user-specific startup file will be run under any conditions. +     * Specify a user-specific startup file to invoke if the application is +     * run interactively. Typically the startup file is "~/.apprc" where "app" +     * is the name of the application. If this line is deleted then no +     * user-specific startup file will be run under any conditions.       */ -    Tcl_SetVar(interp, "tcl_rcFileName", "~/tclshrc.tcl", TCL_GLOBAL_ONLY); +    (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, +	    Tcl_NewStringObj("~/tclshrc.tcl", -1), TCL_GLOBAL_ONLY);      return TCL_OK;  } @@ -146,10 +208,10 @@ Tcl_AppInit(interp)   *   * setargv --   * - *	Parse the Windows command line string into argc/argv.  Done here - *	because we don't trust the builtin argument parser in crt0.   - *	Windows applications are responsible for breaking their command - *	line into arguments. + *	Parse the Windows command line string into argc/argv. Done here + *	because we don't trust the builtin argument parser in crt0. Windows + *	applications are responsible for breaking their command line into + *	arguments.   *   *	2N backslashes + quote -> N backslashes + begin quoted string   *	2N + 1 backslashes + quote -> literal @@ -159,8 +221,8 @@ Tcl_AppInit(interp)   *	quote -> begin quoted string   *   * Results: - *	Fills argcPtr with the number of arguments and argvPtr with the - *	array of arguments. + *	Fills argcPtr with the number of arguments and argvPtr with the array + *	of arguments.   *   * Side effects:   *	Memory allocated. @@ -168,20 +230,21 @@ Tcl_AppInit(interp)   *--------------------------------------------------------------------------   */ +#ifdef TCL_BROKEN_MAINARGS  static void -setargv(argcPtr, argvPtr) -    int *argcPtr;		/* Filled with number of argument strings. */ -    char ***argvPtr;		/* Filled with argument strings (malloc'd). */ +setargv( +    int *argcPtr,		/* Filled with number of argument strings. */ +    TCHAR ***argvPtr)		/* Filled with argument strings (malloc'd). */  { -    char *cmdLine, *p, *arg, *argSpace; -    char **argv; +    TCHAR *cmdLine, *p, *arg, *argSpace; +    TCHAR **argv;      int argc, size, inquote, copy, slashes; -     -    cmdLine = GetCommandLine();	/* INTL: BUG */ + +    cmdLine = GetCommandLine();      /* -     * Precompute an overly pessimistic guess at the number of arguments -     * in the command line by counting non-space spans. +     * Precompute an overly pessimistic guess at the number of arguments in +     * the command line by counting non-space spans.       */      size = 2; @@ -196,10 +259,15 @@ setargv(argcPtr, argvPtr)  	    }  	}      } -    argSpace = (char *) Tcl_Alloc( -	    (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1)); -    argv = (char **) argSpace; -    argSpace += size * sizeof(char *); + +    /* Make sure we don't call ckalloc through the (not yet initialized) stub table */ +    #undef Tcl_Alloc +    #undef Tcl_DbCkalloc + +    argSpace = ckalloc(size * sizeof(char *) +	    + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); +    argv = (TCHAR **) argSpace; +    argSpace += size * (sizeof(char *)/sizeof(TCHAR));      size--;      p = cmdLine; @@ -229,18 +297,18 @@ setargv(argcPtr, argvPtr)  		    } else {  			inquote = !inquote;  		    } -                } -                slashes >>= 1; -            } +		} +		slashes >>= 1; +	    } -            while (slashes) { +	    while (slashes) {  		*arg = '\\';  		arg++;  		slashes--;  	    } -	    if ((*p == '\0') -		    || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ +	    if ((*p == '\0') || (!inquote && +		    ((*p == ' ') || (*p == '\t')))) {	/* INTL: ISO space. */  		break;  	    }  	    if (copy != 0) { @@ -248,7 +316,7 @@ setargv(argcPtr, argvPtr)  		arg++;  	    }  	    p++; -        } +	}  	*arg = '\0';  	argSpace = arg + 1;      } @@ -257,3 +325,12 @@ setargv(argcPtr, argvPtr)      *argcPtr = argc;      *argvPtr = argv;  } +#endif /* TCL_BROKEN_MAINARGS */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ | 
