Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/win/tclAppInit.c @ 43

Last change on this file since 43 was 25, checked in by landauf, 17 years ago

added tcl to libs

File size: 7.5 KB
Line 
1/*
2 * tclAppInit.c --
3 *
4 *      Provides a default version of the main program and Tcl_AppInit
5 *      function for Tcl applications (without Tk). Note that this program
6 *      must be built in Win32 console mode to work properly.
7 *
8 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
9 * Copyright (c) 1998-1999 by Scriptics Corporation.
10 *
11 * See the file "license.terms" for information on usage and redistribution of
12 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 *
14 * RCS: @(#) $Id: tclAppInit.c,v 1.25 2007/04/16 13:36:36 dkf Exp $
15 */
16
17#include "tcl.h"
18#include <windows.h>
19#include <locale.h>
20
21#ifdef TCL_TEST
22extern Tcl_PackageInitProc      Procbodytest_Init;
23extern Tcl_PackageInitProc      Procbodytest_SafeInit;
24extern Tcl_PackageInitProc      Tcltest_Init;
25extern Tcl_PackageInitProc      TclObjTest_Init;
26#endif /* TCL_TEST */
27
28#if defined(__GNUC__)
29static void             setargv(int *argcPtr, char ***argvPtr);
30#endif /* __GNUC__ */
31
32/*
33 *----------------------------------------------------------------------
34 *
35 * main --
36 *
37 *      This is the main program for the application.
38 *
39 * Results:
40 *      None: Tcl_Main never returns here, so this function never returns
41 *      either.
42 *
43 * Side effects:
44 *      Whatever the application does.
45 *
46 *----------------------------------------------------------------------
47 */
48
49int
50main(
51    int argc,
52    char *argv[])
53{
54    /*
55     * The following #if block allows you to change the AppInit function by
56     * using a #define of TCL_LOCAL_APPINIT instead of rewriting this entire
57     * file. The #if checks for that #define and uses Tcl_AppInit if it
58     * doesn't exist.
59     */
60
61#ifndef TCL_LOCAL_APPINIT
62#define TCL_LOCAL_APPINIT Tcl_AppInit
63#endif
64    extern int TCL_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
65
66    /*
67     * The following #if block allows you to change how Tcl finds the startup
68     * script, prime the library or encoding paths, fiddle with the argv,
69     * etc., without needing to rewrite Tcl_Main()
70     */
71
72#ifdef TCL_LOCAL_MAIN_HOOK
73    extern int TCL_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
74#endif
75
76    char *p;
77
78    /*
79     * Set up the default locale to be standard "C" locale so parsing is
80     * performed correctly.
81     */
82
83#if defined(__GNUC__)
84    setargv( &argc, &argv );
85#endif
86    setlocale(LC_ALL, "C");
87
88    /*
89     * Forward slashes substituted for backslashes.
90     */
91
92    for (p = argv[0]; *p != '\0'; p++) {
93        if (*p == '\\') {
94            *p = '/';
95        }
96    }
97
98#ifdef TCL_LOCAL_MAIN_HOOK
99    TCL_LOCAL_MAIN_HOOK(&argc, &argv);
100#endif
101
102    Tcl_Main(argc, argv, TCL_LOCAL_APPINIT);
103
104    return 0;                   /* Needed only to prevent compiler warning. */
105}
106
107/*
108 *----------------------------------------------------------------------
109 *
110 * Tcl_AppInit --
111 *
112 *      This function performs application-specific initialization. Most
113 *      applications, especially those that incorporate additional packages,
114 *      will have their own version of this function.
115 *
116 * Results:
117 *      Returns a standard Tcl completion code, and leaves an error message in
118 *      the interp's result if an error occurs.
119 *
120 * Side effects:
121 *      Depends on the startup script.
122 *
123 *----------------------------------------------------------------------
124 */
125
126int
127Tcl_AppInit(
128    Tcl_Interp *interp)         /* Interpreter for application. */
129{
130    if (Tcl_Init(interp) == TCL_ERROR) {
131        return TCL_ERROR;
132    }
133
134#ifdef TCL_TEST
135    if (Tcltest_Init(interp) == TCL_ERROR) {
136        return TCL_ERROR;
137    }
138    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, NULL);
139    if (TclObjTest_Init(interp) == TCL_ERROR) {
140        return TCL_ERROR;
141    }
142    if (Procbodytest_Init(interp) == TCL_ERROR) {
143        return TCL_ERROR;
144    }
145    Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
146            Procbodytest_SafeInit);
147#endif /* TCL_TEST */
148
149#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
150    {
151        extern Tcl_PackageInitProc Registry_Init;
152        extern Tcl_PackageInitProc Dde_Init;
153        extern Tcl_PackageInitProc Dde_SafeInit;
154
155        if (Registry_Init(interp) == TCL_ERROR) {
156            return TCL_ERROR;
157        }
158        Tcl_StaticPackage(interp, "registry", Registry_Init, NULL);
159
160        if (Dde_Init(interp) == TCL_ERROR) {
161            return TCL_ERROR;
162        }
163        Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit);
164   }
165#endif
166
167    /*
168     * Call the init functions for included packages. Each call should look
169     * like this:
170     *
171     * if (Mod_Init(interp) == TCL_ERROR) {
172     *     return TCL_ERROR;
173     * }
174     *
175     * where "Mod" is the name of the module.
176     */
177
178    /*
179     * Call Tcl_CreateCommand for application-specific commands, if they
180     * weren't already created by the init functions called above.
181     */
182
183    /*
184     * Specify a user-specific startup file to invoke if the application is
185     * run interactively. Typically the startup file is "~/.apprc" where "app"
186     * is the name of the application. If this line is deleted then no
187     * user-specific startup file will be run under any conditions.
188     */
189
190    Tcl_SetVar(interp, "tcl_rcFileName", "~/tclshrc.tcl", TCL_GLOBAL_ONLY);
191    return TCL_OK;
192}
193
194/*
195 *-------------------------------------------------------------------------
196 *
197 * setargv --
198 *
199 *      Parse the Windows command line string into argc/argv. Done here
200 *      because we don't trust the builtin argument parser in crt0. Windows
201 *      applications are responsible for breaking their command line into
202 *      arguments.
203 *
204 *      2N backslashes + quote -> N backslashes + begin quoted string
205 *      2N + 1 backslashes + quote -> literal
206 *      N backslashes + non-quote -> literal
207 *      quote + quote in a quoted string -> single quote
208 *      quote + quote not in quoted string -> empty string
209 *      quote -> begin quoted string
210 *
211 * Results:
212 *      Fills argcPtr with the number of arguments and argvPtr with the array
213 *      of arguments.
214 *
215 * Side effects:
216 *      Memory allocated.
217 *
218 *--------------------------------------------------------------------------
219 */
220
221#if defined(__GNUC__)
222static void
223setargv(
224    int *argcPtr,               /* Filled with number of argument strings. */
225    char ***argvPtr)            /* Filled with argument strings (malloc'd). */
226{
227    char *cmdLine, *p, *arg, *argSpace;
228    char **argv;
229    int argc, size, inquote, copy, slashes;
230
231    cmdLine = GetCommandLine(); /* INTL: BUG */
232
233    /*
234     * Precompute an overly pessimistic guess at the number of arguments in
235     * the command line by counting non-space spans.
236     */
237
238    size = 2;
239    for (p = cmdLine; *p != '\0'; p++) {
240        if ((*p == ' ') || (*p == '\t')) {      /* INTL: ISO space. */
241            size++;
242            while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
243                p++;
244            }
245            if (*p == '\0') {
246                break;
247            }
248        }
249    }
250    argSpace = (char *) ckalloc(
251            (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
252    argv = (char **) argSpace;
253    argSpace += size * sizeof(char *);
254    size--;
255
256    p = cmdLine;
257    for (argc = 0; argc < size; argc++) {
258        argv[argc] = arg = argSpace;
259        while ((*p == ' ') || (*p == '\t')) {   /* INTL: ISO space. */
260            p++;
261        }
262        if (*p == '\0') {
263            break;
264        }
265
266        inquote = 0;
267        slashes = 0;
268        while (1) {
269            copy = 1;
270            while (*p == '\\') {
271                slashes++;
272                p++;
273            }
274            if (*p == '"') {
275                if ((slashes & 1) == 0) {
276                    copy = 0;
277                    if ((inquote) && (p[1] == '"')) {
278                        p++;
279                        copy = 1;
280                    } else {
281                        inquote = !inquote;
282                    }
283                }
284                slashes >>= 1;
285            }
286
287            while (slashes) {
288                *arg = '\\';
289                arg++;
290                slashes--;
291            }
292
293            if ((*p == '\0') || (!inquote &&
294                    ((*p == ' ') || (*p == '\t')))) {   /* INTL: ISO space. */
295                break;
296            }
297            if (copy != 0) {
298                *arg = *p;
299                arg++;
300            }
301            p++;
302        }
303        *arg = '\0';
304        argSpace = arg + 1;
305    }
306    argv[argc] = NULL;
307
308    *argcPtr = argc;
309    *argvPtr = argv;
310}
311#endif /* __GNUC__ */
312
313/*
314 * Local Variables:
315 * mode: c
316 * c-basic-offset: 4
317 * fill-column: 78
318 * End:
319 */
Note: See TracBrowser for help on using the repository browser.