diff options
Diffstat (limited to 'win/winMain.c')
-rw-r--r-- | win/winMain.c | 300 |
1 files changed, 100 insertions, 200 deletions
diff --git a/win/winMain.c b/win/winMain.c index 62bcbd8..01a5e23 100644 --- a/win/winMain.c +++ b/win/winMain.c @@ -1,29 +1,29 @@ /* * winMain.c -- * - * Provides a default version of the main program and Tcl_AppInit - * procedure for wish and other Tk-based applications. + * Main entry point for wish and other Tk-based applications. * - * Copyright (c) 1993 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 Scriptics Corporation. + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "tk.h" +#include "tkInt.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN #include <locale.h> -#include <stdlib.h> -#include <tchar.h> #if defined(__GNUC__) int _CRT_glob = 0; #endif /* __GNUC__ */ +/* + * The following declarations refer to internal Tk routines. These interfaces + * are available for use, but are not supported. + */ #ifdef TK_TEST extern Tcl_PackageInitProc Tktest_Init; #endif /* TK_TEST */ @@ -34,14 +34,12 @@ extern Tcl_PackageInitProc Dde_Init; extern Tcl_PackageInitProc Dde_SafeInit; #endif -#ifdef TCL_BROKEN_MAINARGS -static void setargv(int *argcPtr, TCHAR ***argvPtr); -#endif - /* * Forward declarations for procedures defined later in this file: */ +static void WishPanic(CONST char *format, ...); + static BOOL consoleRequired = TRUE; /* @@ -53,10 +51,7 @@ static BOOL consoleRequired = TRUE; #ifndef TK_LOCAL_APPINIT #define TK_LOCAL_APPINIT Tcl_AppInit #endif -#ifndef MODULE_SCOPE -# define MODULE_SCOPE extern -#endif -MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *interp); +extern int TK_LOCAL_APPINIT(Tcl_Interp *interp); /* * The following #if block allows you to change how Tcl finds the startup @@ -65,17 +60,13 @@ MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *interp); */ #ifdef TK_LOCAL_MAIN_HOOK -MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); +extern int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv); #endif - -/* Make sure the stubbed variants of those are never used. */ -#undef Tcl_ObjSetVar2 -#undef Tcl_NewStringObj /* *---------------------------------------------------------------------- * - * _tWinMain -- + * WinMain -- * * Main entry point from Windows. * @@ -89,23 +80,17 @@ MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); */ int APIENTRY -#ifdef TCL_BROKEN_MAINARGS WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) -#else -_tWinMain( - HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPTSTR lpszCmdLine, - int nCmdShow) -#endif { - TCHAR **argv; + char **argv; int argc; - TCHAR *p; + char *p; + + Tcl_SetPanicProc(WishPanic); /* * Create the console channels and install them as the standard channels. @@ -126,12 +111,8 @@ _tWinMain( * Get our args from the c-runtime. Ignore lpszCmdLine. */ -#if defined(TCL_BROKEN_MAINARGS) - setargv(&argc, &argv); -#else argc = __argc; - argv = __targv; -#endif + argv = __argv; /* * Forward slashes substituted for backslashes. @@ -148,7 +129,7 @@ _tWinMain( #endif Tk_Main(argc, argv, TK_LOCAL_APPINIT); - return 0; /* Needed only to prevent compiler warning. */ + return 1; } /* @@ -174,11 +155,14 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { - if ((Tcl_Init)(interp) == TCL_ERROR) { - return TCL_ERROR; +#define TK_MAX_WARN_LEN 1024 + WCHAR msgString[TK_MAX_WARN_LEN + 5]; + + if (Tcl_Init(interp) == TCL_ERROR) { + goto error; } if (Tk_Init(interp) == TCL_ERROR) { - return TCL_ERROR; + goto error; } Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit); @@ -189,26 +173,26 @@ Tcl_AppInit( if (consoleRequired) { if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) { - return TCL_ERROR; + goto error; } } #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES if (Registry_Init(interp) == TCL_ERROR) { - return TCL_ERROR; + goto error; } - Tcl_StaticPackage(interp, "registry", Registry_Init, 0); + Tcl_StaticPackage(interp, "registry", Registry_Init, NULL); if (Dde_Init(interp) == TCL_ERROR) { - return TCL_ERROR; + goto error; } - Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit); + Tcl_StaticPackage(interp, "dde", Dde_Init, NULL); #endif #ifdef TK_TEST if (Tktest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; + goto error; } - Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0); + Tcl_StaticPackage(interp, "Tktest", Tktest_Init, NULL); #endif /* TK_TEST */ /* @@ -224,7 +208,7 @@ Tcl_AppInit( */ /* - * Call Tcl_CreateObjCommand for application-specific commands, if they + * Call Tcl_CreateCommand for application-specific commands, if they * weren't already created by the init procedures called above. */ @@ -235,198 +219,114 @@ Tcl_AppInit( * specific startup file will be run under any conditions. */ - Tcl_ObjSetVar2(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, - Tcl_NewStringObj("~/wishrc.tcl", -1), TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY); return TCL_OK; + +error: + MultiByteToWideChar(CP_UTF8, 0, Tcl_GetStringResult(interp), -1, + msgString, TK_MAX_WARN_LEN); + /* + * Truncate MessageBox string if it is too long to not overflow the screen + * and cause possible oversized window error. + */ + memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR)); + MessageBeep(MB_ICONEXCLAMATION); + MessageBoxW(NULL, msgString, L"Error in Wish", + MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND); + ExitProcess(1); + + /* + * We won't reach this, but we need the return. + */ + + return TCL_ERROR; } -#if defined(TK_TEST) /* *---------------------------------------------------------------------- * - * _tmain -- + * WishPanic -- * - * Main entry point from the console. + * Display a message and exit. * * Results: - * None: Tk_Main never returns here, so this procedure never returns - * either. + * None. * * Side effects: - * Whatever the applications does. + * Exits the program. * *---------------------------------------------------------------------- */ -#ifdef TCL_BROKEN_MAINARGS -int -main( - int argc, - char **dummy) +void +WishPanic( + CONST char *format, ...) { - TCHAR **argv; -#else -int -_tmain( - int argc, - TCHAR **argv) -{ -#endif - /* - * Set up the default locale to be standard "C" locale so parsing is - * performed correctly. - */ + va_list argList; + char buf[TK_MAX_WARN_LEN]; + WCHAR msgString[TK_MAX_WARN_LEN + 5]; - setlocale(LC_ALL, "C"); + va_start(argList, format); + vsprintf(buf, format, argList); -#ifdef TCL_BROKEN_MAINARGS + MultiByteToWideChar(CP_UTF8, 0, buf, -1, msgString, TK_MAX_WARN_LEN); /* - * Get our args from the c-runtime. Ignore argc/argv. + * Truncate MessageBox string if it is too long to not overflow the screen + * and cause possible oversized window error. */ - - setargv(&argc, &argv); + memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR)); + MessageBeep(MB_ICONEXCLAMATION); + MessageBoxW(NULL, msgString, L"Fatal Error in Wish", + MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND); +#ifdef _MSC_VER + DebugBreak(); #endif - /* - * Console emulation widget not required as this entry is from the - * console subsystem, thus stdin,out,err already have end-points. - */ - - consoleRequired = FALSE; - -#ifdef TK_LOCAL_MAIN_HOOK - TK_LOCAL_MAIN_HOOK(&argc, &argv); -#endif - - Tk_Main(argc, argv, Tcl_AppInit); - return 0; + ExitProcess(1); } -#endif /* !__GNUC__ || TK_TEST */ - - + +#if defined(TK_TEST) /* - *------------------------------------------------------------------------- - * - * 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. + * main -- * - * 2N backslashes + quote -> N backslashes + begin quoted string - * 2N + 1 backslashes + quote -> literal - * N backslashes + non-quote -> literal - * quote + quote in a quoted string -> single quote - * quote + quote not in quoted string -> empty string - * quote -> begin quoted string + * Main entry point from the console. * * Results: - * Fills argcPtr with the number of arguments and argvPtr with the array - * of arguments. + * None: Tk_Main never returns here, so this procedure never returns + * either. * * Side effects: - * Memory allocated. + * Whatever the applications does. * - *-------------------------------------------------------------------------- + *---------------------------------------------------------------------- */ -#ifdef TCL_BROKEN_MAINARGS -static void -setargv( - int *argcPtr, /* Filled with number of argument strings. */ - TCHAR ***argvPtr) /* Filled with argument strings (malloc'd). */ +int +main( + int argc, + char **argv) { - TCHAR *cmdLine, *p, *arg, *argSpace; - TCHAR **argv; - int argc, size, inquote, copy, slashes; - - cmdLine = GetCommandLine(); + Tcl_SetPanicProc(WishPanic); /* - * Precompute an overly pessimistic guess at the number of arguments in - * the command line by counting non-space spans. + * Set up the default locale to be standard "C" locale so parsing is + * performed correctly. */ - size = 2; - for (p = cmdLine; *p != '\0'; p++) { - if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - size++; - while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - p++; - } - if (*p == '\0') { - break; - } - } - } + setlocale(LC_ALL, "C"); - /* 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; - for (argc = 0; argc < size; argc++) { - argv[argc] = arg = argSpace; - while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - p++; - } - if (*p == '\0') { - break; - } + /* + * Console emulation widget not required as this entry is from the + * console subsystem, thus stdin,out,err already have end-points. + */ - inquote = 0; - slashes = 0; - while (1) { - copy = 1; - while (*p == '\\') { - slashes++; - p++; - } - if (*p == '"') { - if ((slashes & 1) == 0) { - copy = 0; - if ((inquote) && (p[1] == '"')) { - p++; - copy = 1; - } else { - inquote = !inquote; - } - } - slashes >>= 1; - } - - while (slashes) { - *arg = '\\'; - arg++; - slashes--; - } - - if ((*p == '\0') || (!inquote && - ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ - break; - } - if (copy != 0) { - *arg = *p; - arg++; - } - p++; - } - *arg = '\0'; - argSpace = arg + 1; - } - argv[argc] = NULL; + consoleRequired = FALSE; - *argcPtr = argc; - *argvPtr = argv; + Tk_Main(argc, argv, Tcl_AppInit); + return 0; } -#endif /* TCL_BROKEN_MAINARGS */ - +#endif /* TK_TEST */ /* * Local Variables: * mode: c |