source: tol/tolbase/generic/tkAppInit.c @ 6d7779d

1941-docker-image-to-testdevel
Last change on this file since 6d7779d was 6d7779d, checked in by Jorge Pérez <josp.jorge@…>, 18 years ago

initial import

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 11.8 KB
Line 
1/*
2 * tkAppInit.c --
3 *
4 *      Provides a default version of the Tcl_AppInit procedure for
5 *      use in wish and similar Tk-based applications.
6 *
7 * Copyright (c) 1993 The Regents of the University of California.
8 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
9 *
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id: tkAppInit.c,v 1.4 2004/07/13 17:24:10 josp Exp $
14 */
15
16#include <tk.h>
17#include <locale.h>
18#include <string.h>
19
20#include <sys/stat.h>
21#ifdef __WIN32__
22#include <windows.h>
23#define setenv(a,b,c) SetEnvironmentVariable(a,b)
24
25static void             setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
26static void             WishPanic _ANSI_ARGS_(TCL_VARARGS(char *,format));
27
28static BOOL consoleRequired = TRUE;
29
30#else
31#include <unistd.h>
32/*
33 * The following variable is a special hack that is needed in order for
34 * Sun shared libraries to be used for Tcl.
35 */
36
37extern int matherr();
38int *tclDummyMathPtr = (int *) matherr;
39#endif
40
41int  LoadMainTcl          _ANSI_ARGS_ ((Tcl_Interp * interp));
42void TolTk_SetEnvironment _ANSI_ARGS_ ((Tcl_Interp * interp, int * argc, char *** argv));
43
44/*
45 *----------------------------------------------------------------------
46 *
47 * main --
48 *
49 *      This is the main program for the application.
50 *
51 * Results:
52 *      None: Tk_Main never returns here, so this procedure never
53 *      returns either.
54 *
55 * Side effects:
56 *      Whatever the application does.
57 *
58 *----------------------------------------------------------------------
59 */
60
61int
62main(argc, argv)
63    int argc;                   /* Number of command-line arguments. */
64    char **argv;                /* Values of command-line arguments. */
65{
66    /*
67     * The following #if block allows you to change the AppInit
68     * function by using a #define of TCL_LOCAL_APPINIT instead
69     * of rewriting this entire file.  The #if checks for that
70     * #define and uses Tcl_AppInit if it doesn't exist.
71     */
72   
73#ifndef TK_LOCAL_APPINIT
74#define TK_LOCAL_APPINIT Tcl_AppInit   
75#endif
76    extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
77   
78    Tcl_Interp *interp;
79
80    interp = Tcl_CreateInterp();
81
82    TolTk_SetEnvironment(interp,&argc,&argv);
83    Tk_MainEx(argc, argv, TK_LOCAL_APPINIT,interp);
84    return 0;                   /* Needed only to prevent compiler warning. */
85}
86
87
88/*
89 *----------------------------------------------------------------------
90 *
91 * Tcl_AppInit --
92 *
93 *      This procedure performs application-specific initialization.
94 *      Most applications, especially those that incorporate additional
95 *      packages, will have their own version of this procedure.
96 *
97 * Results:
98 *      Returns a standard Tcl completion code, and leaves an error
99 *      message in the interp's result if an error occurs.
100 *
101 * Side effects:
102 *      Depends on the startup script.
103 *
104 *----------------------------------------------------------------------
105 */
106
107int
108Tcl_AppInit(interp)
109    Tcl_Interp *interp;         /* Interpreter for application. */
110{
111  int tcl_code;
112
113  if (Tcl_Init(interp) == TCL_ERROR) {
114    return TCL_ERROR;
115  }
116
117 if (Tk_Init(interp) == TCL_ERROR) {
118    return TCL_ERROR;
119  }
120  Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
121 
122 
123  /*
124   * Call the init procedures for included packages.  Each call should
125   * look like this:
126   *
127   * if (Mod_Init(interp) == TCL_ERROR) {
128   *     return TCL_ERROR;
129   * }
130   *
131   * where "Mod" is the name of the module.
132   */
133
134  /*
135   * Call Tcl_CreateCommand for application-specific commands, if
136   * they weren't already created by the init procedures called above.
137   */
138 
139  /*
140   * Specify a user-specific startup file to invoke if the application
141   * is run interactively.  Typically the startup file is "~/.apprc"
142   * where "app" is the name of the application.  If this line is deleted
143   * then no user-specific startup file will be run under any conditions.
144   *     */
145 
146  // Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
147
148 
149
150  //tcl_code = LoadMainTcl( interp );
151
152  return TCL_OK;
153}
154
155int LoadMainTcl( Tcl_Interp * interp )
156{
157  Tcl_DString ds;
158  CONST char * pathv[2];
159  int tcl_code = TCL_ERROR;
160
161  pathv[0] = Tcl_GetVar(interp, "toltk_library", TCL_GLOBAL_ONLY);
162  if ( pathv[0] ) {
163    Tcl_DStringInit(&ds);
164    pathv[1] = "toltk/init_toltk.tcl";
165    Tcl_JoinPath(2, pathv, &ds);
166    tcl_code = Tcl_EvalFile(interp,ds.string );
167  }
168  return tcl_code;
169}
170
171/*
172 *----------------------------------------------------------------------
173 *
174 * TolTk_SetEnvironment --
175 *
176 *   Set the variable toltk_library to:
177 *
178 *     ..\lib in case of instalation
179 *
180 *     ..\..\lib in case of development 
181 *
182 *----------------------------------------------------------------------
183 */
184
185void TolTk_SetEnvironment( Tcl_Interp * interp, int * argc, char *** argv )
186{
187  static char ** new_argv;
188 
189  int pathc;
190  CONST char ** pathv, * pathv1[2];
191  char * argv0;
192  Tcl_DString ds, ds1, ds_argv0;
193  struct stat stat_buf;
194  int sys_res, i;
195
196  if ( (*argv)[0] ) {
197    Tcl_DStringInit(&ds_argv0);
198    argv0 = Tcl_ExternalToUtfDString(NULL, (*argv)[0], -1, &ds_argv0);
199    Tcl_SplitPath(argv0, &pathc, &pathv);
200
201    /* set toltk_bin */
202
203    /* look for ../lib */
204   
205    Tcl_DStringInit(&ds);
206    pathv[pathc - 1] = "../lib";
207    Tcl_JoinPath(pathc,pathv,&ds);
208    if ( stat(ds.string, &stat_buf) == -1 ) {
209      Tcl_DStringFree( &ds );
210
211      /* look for ../../lib */
212     
213      pathv[pathc - 1] = "../../lib";
214      Tcl_JoinPath(pathc,pathv,&ds);
215      if ( stat(ds.string, &stat_buf) == -1 ) {
216              Tcl_DStringFree( &ds );
217              Tcl_Free((char*)pathv);
218              /* lib not found */
219        return;
220      }
221    }
222    /* lib has being found */
223   
224    Tcl_SetVar(interp, "toltk_library", ds.string, TCL_GLOBAL_ONLY);
225
226    /* set TCL_LIBRARY */
227
228    Tcl_DStringInit(&ds1);
229    pathv1[0] = ds.string;
230    pathv1[1] = "tcl";
231    Tcl_JoinPath(2, pathv1, &ds1);
232    sys_res = setenv("TCL_LIBRARY", ds1.string, 1);
233    Tcl_SetVar(interp, "tcl_library", ds1.string, TCL_GLOBAL_ONLY);
234        Tcl_VarEval(interp, "set tcl_library", NULL);
235
236    /* set TK_LIBRARY */
237   
238    Tcl_DStringFree(&ds1);
239    pathv1[1] = "tk";
240    Tcl_JoinPath(2, pathv1, &ds1);
241    sys_res = setenv("TK_LIBRARY", ds1.string, 1);
242    Tcl_SetVar(interp, "tk_library", ds1.string, TCL_GLOBAL_ONLY);
243
244    /* set BLT_LIBRARY */
245
246    Tcl_DStringFree(&ds1);
247    pathv1[1] = "blt";
248    Tcl_JoinPath(2, pathv1, &ds1);
249    sys_res = setenv("BLT_LIBRARY", ds1.string, 1);
250    Tcl_SetVar(interp, "blt_libPath", ds1.string, TCL_GLOBAL_ONLY);
251
252    Tcl_DStringFree(&ds1);
253    Tcl_DStringFree(&ds);
254    Tcl_DStringFree(&ds_argv0);
255    Tcl_Free((char*)pathv);
256
257    /* now insert init_toltk.tcl  as the first argument */
258    new_argv = (char**)Tcl_Alloc(sizeof(char*)*(*argc+1));
259    new_argv[0] = (*argv)[0];
260    for (i = 1; i < *argc; i++)
261      new_argv[i+1] = (*argv)[i];
262    /*new_argv[1] = strdup("-");*/
263   
264    pathv1[0] = Tcl_GetVar(interp, "toltk_library", TCL_GLOBAL_ONLY);
265    pathv1[1] = "toltk/init_toltk.tcl";
266    Tcl_DStringInit(&ds);
267    Tcl_JoinPath(2, pathv1, &ds);
268    new_argv[1] = strdup(Tcl_DStringValue(&ds));
269    Tcl_DStringFree(&ds);
270    ++*argc;
271    *argv = new_argv;
272  }
273}
274
275#ifdef __WIN32__
276int WINAPI WinMain( HINSTANCE hInstance,  // handle to current instance
277                    HINSTANCE hPrevInstance,  // handle to previous instance
278                    LPSTR lpCmdLine,      // pointer to command line
279                    int nCmdShow          // show state of window
280                  )
281{
282    char **argv;
283    int argc;
284    char buffer[MAX_PATH+1];
285    char *p;
286
287    /*
288     * Increase the application queue size from default value of 8.
289     * At the default value, cross application SendMessage of WM_KILLFOCUS
290     * will fail because the handler will not be able to do a PostMessage!
291     * This is only needed for Windows 3.x, since NT dynamically expands
292     * the queue.
293     */
294
295    SetMessageQueue(64);
296
297    Tcl_SetPanicProc(WishPanic);
298
299    /*
300     * Create the console channels and install them as the standard
301     * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is
302     * called to attach the console to a text widget.
303     */
304
305    consoleRequired = TRUE;
306
307    /*
308     * Set up the default locale to be standard "C" locale so parsing
309     * is performed correctly.
310     */
311
312    setlocale(LC_ALL, "C");
313    setargv(&argc, &argv);
314
315    /*
316     * Replace argv[0] with full pathname of executable, and forward
317     * slashes substituted for backslashes.
318     */
319
320    GetModuleFileName(NULL, buffer, sizeof(buffer));
321    argv[0] = buffer;
322    for (p = buffer; *p != '\0'; p++) {
323        if (*p == '\\') {
324            *p = '/';
325        }
326    }
327
328    return main(argc,argv);
329
330}
331 
332
333/*
334 *----------------------------------------------------------------------
335 *
336 * WishPanic --
337 *
338 *      Display a message and exit.
339 *
340 * Results:
341 *      None.
342 *
343 * Side effects:
344 *      Exits the program.
345 *
346 *----------------------------------------------------------------------
347 */
348
349void
350WishPanic TCL_VARARGS_DEF(char *,arg1)
351{
352    va_list argList;
353    char buf[1024];
354    char *format;
355   
356    format = TCL_VARARGS_START(char *,arg1,argList);
357    vsprintf(buf, format, argList);
358
359    MessageBeep(MB_ICONEXCLAMATION);
360    MessageBox(NULL, buf, "Fatal Error in Wish",
361            MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
362#ifdef _MSC_VER
363    DebugBreak();
364#endif
365    ExitProcess(1);
366}
367/*
368 *-------------------------------------------------------------------------
369 *
370 * setargv --
371 *
372 *      Parse the Windows command line string into argc/argv.  Done here
373 *      because we don't trust the builtin argument parser in crt0. 
374 *      Windows applications are responsible for breaking their command
375 *      line into arguments.
376 *
377 *      2N backslashes + quote -> N backslashes + begin quoted string
378 *      2N + 1 backslashes + quote -> literal
379 *      N backslashes + non-quote -> literal
380 *      quote + quote in a quoted string -> single quote
381 *      quote + quote not in quoted string -> empty string
382 *      quote -> begin quoted string
383 *
384 * Results:
385 *      Fills argcPtr with the number of arguments and argvPtr with the
386 *      array of arguments.
387 *
388 * Side effects:
389 *      Memory allocated.
390 *
391 *--------------------------------------------------------------------------
392 */
393
394static void
395setargv(argcPtr, argvPtr)
396    int *argcPtr;               /* Filled with number of argument strings. */
397    char ***argvPtr;            /* Filled with argument strings (malloc'd). */
398{
399    char *cmdLine, *p, *arg, *argSpace;
400    char **argv;
401    int argc, size, inquote, copy, slashes;
402   
403    cmdLine = GetCommandLine(); /* INTL: BUG */
404
405    /*
406     * Precompute an overly pessimistic guess at the number of arguments
407     * in the command line by counting non-space spans.
408     */
409
410    size = 2;
411    for (p = cmdLine; *p != '\0'; p++) {
412        if ((*p == ' ') || (*p == '\t')) {      /* INTL: ISO space. */
413            size++;
414            while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
415                p++;
416            }
417            if (*p == '\0') {
418                break;
419            }
420        }
421    }
422    argSpace = (char *) Tcl_Alloc(
423            (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
424    argv = (char **) argSpace;
425    argSpace += size * sizeof(char *);
426    size--;
427
428    p = cmdLine;
429    for (argc = 0; argc < size; argc++) {
430        argv[argc] = arg = argSpace;
431        while ((*p == ' ') || (*p == '\t')) {   /* INTL: ISO space. */
432            p++;
433        }
434        if (*p == '\0') {
435            break;
436        }
437
438        inquote = 0;
439        slashes = 0;
440        while (1) {
441            copy = 1;
442            while (*p == '\\') {
443                slashes++;
444                p++;
445            }
446            if (*p == '"') {
447                if ((slashes & 1) == 0) {
448                    copy = 0;
449                    if ((inquote) && (p[1] == '"')) {
450                        p++;
451                        copy = 1;
452                    } else {
453                        inquote = !inquote;
454                    }
455                }
456                slashes >>= 1;
457            }
458
459            while (slashes) {
460                *arg = '\\';
461                arg++;
462                slashes--;
463            }
464
465            if ((*p == '\0')
466                    || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
467                break;
468            }
469            if (copy != 0) {
470                *arg = *p;
471                arg++;
472            }
473            p++;
474        }
475        *arg = '\0';
476        argSpace = arg + 1;
477    }
478    argv[argc] = NULL;
479
480    *argcPtr = argc;
481    *argvPtr = argv;
482}
483
484#endif
Note: See TracBrowser for help on using the repository browser.