home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / win / winMain.c < prev   
Encoding:
C/C++ Source or Header  |  1997-08-15  |  7.1 KB  |  324 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * winMain.c --
  3.  *
  4.  *    Main entry point for wish and other Tk-based applications.
  5.  *
  6.  * Copyright (c) 1995 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * SCCS: @(#) winMain.c 1.33 96/12/17 12:56:14
  12.  */
  13.  
  14. #include <tk.h>
  15. #define WIN32_LEAN_AND_MEAN
  16. #include <windows.h>
  17. #undef WIN32_LEAN_AND_MEAN
  18. #include <malloc.h>
  19. #include <locale.h>
  20.  
  21. /*
  22.  * The following declarations refer to internal Tk routines.  These
  23.  * interfaces are available for use, but are not supported.
  24.  */
  25.  
  26. EXTERN void        TkConsoleCreate(void);
  27. EXTERN int        TkConsoleInit(Tcl_Interp *interp);
  28.  
  29. /*
  30.  * Forward declarations for procedures defined later in this file:
  31.  */
  32.  
  33. static void        setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
  34. static void        WishPanic _ANSI_ARGS_(TCL_VARARGS(char *,format));
  35.  
  36. #ifdef TK_TEST
  37. EXTERN int        Tktest_Init(Tcl_Interp *interp);
  38. #endif /* TK_TEST */
  39.  
  40.  
  41. /*
  42.  *----------------------------------------------------------------------
  43.  *
  44.  * WinMain --
  45.  *
  46.  *    Main entry point from Windows.
  47.  *
  48.  * Results:
  49.  *    Returns false if initialization fails, otherwise it never
  50.  *    returns. 
  51.  *
  52.  * Side effects:
  53.  *    Just about anything, since from here we call arbitrary Tcl code.
  54.  *
  55.  *----------------------------------------------------------------------
  56.  */
  57.  
  58. int APIENTRY
  59. WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  60.     HINSTANCE hInstance;
  61.     HINSTANCE hPrevInstance;
  62.     LPSTR lpszCmdLine;
  63.     int nCmdShow;
  64. {
  65.     char **argv, *p;
  66.     int argc;
  67.     char buffer[MAX_PATH];
  68.  
  69.     Tcl_SetPanicProc(WishPanic);
  70.  
  71.     /*
  72.      * Set up the default locale to be standard "C" locale so parsing
  73.      * is performed correctly.
  74.      */
  75.  
  76.     setlocale(LC_ALL, "C");
  77.  
  78.  
  79.     /*
  80.      * Increase the application queue size from default value of 8.
  81.      * At the default value, cross application SendMessage of WM_KILLFOCUS
  82.      * will fail because the handler will not be able to do a PostMessage!
  83.      * This is only needed for Windows 3.x, since NT dynamically expands
  84.      * the queue.
  85.      */
  86.     SetMessageQueue(64);
  87.  
  88.     /*
  89.      * Create the console channels and install them as the standard
  90.      * channels.  All I/O will be discarded until TkConsoleInit is
  91.      * called to attach the console to a text widget.
  92.      */
  93.  
  94.     TkConsoleCreate();
  95.  
  96.     setargv(&argc, &argv);
  97.  
  98.     /*
  99.      * Replace argv[0] with full pathname of executable, and forward
  100.      * slashes substituted for backslashes.
  101.      */
  102.  
  103.     GetModuleFileName(NULL, buffer, sizeof(buffer));
  104.     argv[0] = buffer;
  105.     for (p = buffer; *p != '\0'; p++) {
  106.     if (*p == '\\') {
  107.         *p = '/';
  108.     }
  109.     }
  110.  
  111.     Tk_Main(argc, argv, Tcl_AppInit);
  112.     return 1;
  113. }
  114.  
  115.  
  116. /*
  117.  *----------------------------------------------------------------------
  118.  *
  119.  * Tcl_AppInit --
  120.  *
  121.  *    This procedure performs application-specific initialization.
  122.  *    Most applications, especially those that incorporate additional
  123.  *    packages, will have their own version of this procedure.
  124.  *
  125.  * Results:
  126.  *    Returns a standard Tcl completion code, and leaves an error
  127.  *    message in interp->result if an error occurs.
  128.  *
  129.  * Side effects:
  130.  *    Depends on the startup script.
  131.  *
  132.  *----------------------------------------------------------------------
  133.  */
  134.  
  135. int
  136. Tcl_AppInit(interp)
  137.     Tcl_Interp *interp;        /* Interpreter for application. */
  138. {
  139.     if (Tcl_Init(interp) == TCL_ERROR) {
  140.     goto error;
  141.     }
  142.     if (Tk_Init(interp) == TCL_ERROR) {
  143.     goto error;
  144.     }
  145.     Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
  146.  
  147.     /*
  148.      * Initialize the console only if we are running as an interactive
  149.      * application.
  150.      */
  151.  
  152.     if (TkConsoleInit(interp) == TCL_ERROR) {
  153.     goto error;
  154.     }
  155.  
  156. #ifdef TK_TEST
  157.     if (Tktest_Init(interp) == TCL_ERROR) {
  158.     goto error;
  159.     }
  160.     Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
  161.             (Tcl_PackageInitProc *) NULL);
  162. #endif /* TK_TEST */
  163.  
  164.     Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);
  165.     return TCL_OK;
  166.  
  167. error:
  168.     WishPanic(interp->result);
  169.     return TCL_ERROR;
  170. }
  171.  
  172. /*
  173.  *----------------------------------------------------------------------
  174.  *
  175.  * WishPanic --
  176.  *
  177.  *    Display a message and exit.
  178.  *
  179.  * Results:
  180.  *    None.
  181.  *
  182.  * Side effects:
  183.  *    Exits the program.
  184.  *
  185.  *----------------------------------------------------------------------
  186.  */
  187.  
  188. void
  189. WishPanic TCL_VARARGS_DEF(char *,arg1)
  190. {
  191.     va_list argList;
  192.     char buf[1024];
  193.     char *format;
  194.     
  195.     format = TCL_VARARGS_START(char *,arg1,argList);
  196.     vsprintf(buf, format, argList);
  197.  
  198.     MessageBeep(MB_ICONEXCLAMATION);
  199.     MessageBox(NULL, buf, "Fatal Error in Wish",
  200.         MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  201. #ifdef _MSC_VER
  202.     _asm {
  203.         int 3
  204.     }
  205. #endif
  206.     ExitProcess(1);
  207. }
  208. /*
  209.  *-------------------------------------------------------------------------
  210.  *
  211.  * setargv --
  212.  *
  213.  *    Parse the Windows command line string into argc/argv.  Done here
  214.  *    because we don't trust the builtin argument parser in crt0.  
  215.  *    Windows applications are responsible for breaking their command
  216.  *    line into arguments.
  217.  *
  218.  *    2N backslashes + quote -> N backslashes + begin quoted string
  219.  *    2N + 1 backslashes + quote -> literal
  220.  *    N backslashes + non-quote -> literal
  221.  *    quote + quote in a quoted string -> single quote
  222.  *    quote + quote not in quoted string -> empty string
  223.  *    quote -> begin quoted string
  224.  *
  225.  * Results:
  226.  *    Fills argcPtr with the number of arguments and argvPtr with the
  227.  *    array of arguments.
  228.  *
  229.  * Side effects:
  230.  *    Memory allocated.
  231.  *
  232.  *--------------------------------------------------------------------------
  233.  */
  234.  
  235. static void
  236. setargv(argcPtr, argvPtr)
  237.     int *argcPtr;        /* Filled with number of argument strings. */
  238.     char ***argvPtr;        /* Filled with argument strings (malloc'd). */
  239. {
  240.     char *cmdLine, *p, *arg, *argSpace;
  241.     char **argv;
  242.     int argc, size, inquote, copy, slashes;
  243.     
  244.     cmdLine = GetCommandLine();
  245.  
  246.     /*
  247.      * Precompute an overly pessimistic guess at the number of arguments
  248.      * in the command line by counting non-space spans.
  249.      */
  250.  
  251.     size = 2;
  252.     for (p = cmdLine; *p != '\0'; p++) {
  253.     if (isspace(*p)) {
  254.         size++;
  255.         while (isspace(*p)) {
  256.         p++;
  257.         }
  258.         if (*p == '\0') {
  259.         break;
  260.         }
  261.     }
  262.     }
  263.     argSpace = (char *) ckalloc((unsigned) (size * sizeof(char *) 
  264.         + strlen(cmdLine) + 1));
  265.     argv = (char **) argSpace;
  266.     argSpace += size * sizeof(char *);
  267.     size--;
  268.  
  269.     p = cmdLine;
  270.     for (argc = 0; argc < size; argc++) {
  271.     argv[argc] = arg = argSpace;
  272.     while (isspace(*p)) {
  273.         p++;
  274.     }
  275.     if (*p == '\0') {
  276.         break;
  277.     }
  278.  
  279.     inquote = 0;
  280.     slashes = 0;
  281.     while (1) {
  282.         copy = 1;
  283.         while (*p == '\\') {
  284.         slashes++;
  285.         p++;
  286.         }
  287.         if (*p == '"') {
  288.         if ((slashes & 1) == 0) {
  289.             copy = 0;
  290.             if ((inquote) && (p[1] == '"')) {
  291.             p++;
  292.             copy = 1;
  293.             } else {
  294.             inquote = !inquote;
  295.             }
  296.                 }
  297.                 slashes >>= 1;
  298.             }
  299.  
  300.             while (slashes) {
  301.         *arg = '\\';
  302.         arg++;
  303.         slashes--;
  304.         }
  305.  
  306.         if ((*p == '\0') || (!inquote && isspace(*p))) {
  307.         break;
  308.         }
  309.         if (copy != 0) {
  310.         *arg = *p;
  311.         arg++;
  312.         }
  313.         p++;
  314.         }
  315.     *arg = '\0';
  316.     argSpace = arg + 1;
  317.     }
  318.     argv[argc] = NULL;
  319.  
  320.     *argcPtr = argc;
  321.     *argvPtr = argv;
  322. }
  323.  
  324.