/[ascend]/trunk/tcltk/generic/interface/DriverNoTickle.c
ViewVC logotype

Contents of /trunk/tcltk/generic/interface/DriverNoTickle.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 586 - (show annotations) (download) (as text)
Thu May 11 00:47:54 2006 UTC (14 years, 6 months ago) by johnpye
File MIME type: text/x-csrc
File size: 14555 byte(s)
Working on improving handling of paths.
1 /*
2 * DriverNoGUI.c
3 * by Ben Allan
4 * Created: 7/2004
5 * Version: $Revision: 1.1 $
6 * Version control file: $RCSfile: DriverNoTickle.c,v $
7 * Date last modified: $Date: 2004/07/13 07:42:30 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the ASCEND Tcl interface
11 *
12 * Copyright 1997, Carnegie Mellon University
13 *
14 * The ASCEND Tcl interface is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The ASCEND Tcl interface is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING. COPYING is found in ../compiler.
28 */
29
30 #define WITH_TK 0
31 #define CONST84 const
32
33 #include <stdarg.h>
34 #include <ctype.h>
35 #include <signal.h>
36 #include <time.h>
37 #include <utilities/ascConfig.h>
38
39 #ifndef __WIN32__
40 # include <unistd.h>
41 #else
42 # define WIN32_LEAN_AND_MEAN
43 # include <windows.h>
44 # include <locale.h>
45 # undef WIN32_LEAN_AND_MEAN
46 #endif /* __WIN32__ */
47
48 #include <utilities/config.h>
49 #include <utilities/ascMalloc.h> /* for ascshutdown */
50 #include <utilities/ascPanic.h> /* for Asc_Panic */
51 #include <utilities/ascEnvVar.h>
52 #include <compiler/compiler.h>
53 #include <compiler/ascCompiler.h>
54 #include <compiler/instance_enum.h>
55 #include <compiler/fractions.h>
56 #include <compiler/dimen.h>
57 #include <compiler/compiler.h> /* for symchar for units.h */
58 #include <compiler/units.h>
59 #include <solver/slv_types.h>
60 #include <solver/var.h>
61 #include <solver/rel.h>
62 #include <solver/logrel.h>
63 #include <solver/discrete.h>
64 #include <solver/mtx.h>
65 #include <solver/slv_stdcalls.h>
66
67 #ifndef lint
68 static CONST char DriverID[] = "$Id: DriverNoTickle.c,v 1.1 2004/07/13 07:42:30 ballan Exp $";
69 #endif
70
71 /*
72 * EXPORTED VARIABLES
73 */
74
75 /**
76 * g_compiler_timing
77 *
78 * TRUE if compiler timing is to be printed.
79 * default is false, set to TRUE by passing -t on the command line
80 */
81 int g_compiler_timing = 0;
82
83
84 /*
85 * zz_debug
86 *
87 * Comes from the yacc file if yacc was built with debugging information
88 */
89 #ifdef ZZ_DEBUG
90 extern int zz_debug;
91 #endif
92
93
94 /*
95 * Forward declarations for procedures defined later in this file.
96 */
97 static int AscDriver(int, CONST84 char * argv[]);
98 static void AscTrap(int);
99 static void AscPrintHelpExit(CONST char *);
100 static int AscProcessCommandLine( int argc, CONST84 char **argv);
101 #ifdef DEBUG_MALLOC
102 static void InitDebugMalloc(void);
103 #endif /* DEBUG_MALLOC */
104 #ifdef __WIN32__
105 static void setargv(int*, char ***);
106 #endif /* __WIN32__ */
107
108
109 /*
110 * LOCALLY GLOBAL VARIABLES
111 */
112
113 /*
114 * g_interface_simplify_relations
115 *
116 * TRUE for compiler optimizations
117 * default is TRUE, set to FALSE by passing +s on the command line
118 */
119 static int g_interface_simplify_relations = TRUE;
120
121 /*
122 * g_interfacever
123 *
124 * TRUE if windows to be built; default is TRUE, false is not supported
125 */
126 static int g_interfacever = 0;
127
128 /*
129 * tty
130 *
131 * Non-zero means standard input is a terminal-like device.
132 * Zero means it's a file.
133 */
134 static int tty;
135
136 /*
137 * This assumes tcl_library has been found and that tcl8.0 and tk8.0
138 * are installed in the same lib directory -- the default tcl/tk install.
139 */
140
141 /*
142 * build_name
143 *
144 * who built this binary and when
145 */
146 #ifndef TIMESTAMP
147 static char build_name[]="by anonymous";
148 #else
149 static char build_name[]=TIMESTAMP;
150 #endif /* TIMESTAMP */
151
152
153
154 /*
155 * main or WinMain
156 *
157 * The main entry point for a Unix or Windows application.
158 *
159 * Each just calls AscDriver().
160 * These are based on functions from the Tk 8.0 distribution.
161 * See unix/tkAppInit.c and win/winMain.c in their sources.
162 */
163 #ifndef __WIN32__
164
165 int main(int argc, CONST84 char *argv[])
166 {
167 AscDriver(argc, argv);
168 return 0;
169 }
170
171 #else /* __WIN32__ */
172 /* this may need fixing undfer windows, if winmain requires tk */
173 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
174 LPSTR lpszCmdLine, int nCmdShow)
175 {
176 int argc;
177 char **argv;
178 char *p;
179 char buffer[MAX_PATH];
180
181 /*
182 * Set up the default locale to be standard "C" locale so parsing
183 * is performed correctly.
184 */
185 setlocale(LC_ALL, "C");
186
187 /*
188 * Increase the application queue size from default value of 8.
189 * At the default value, cross application SendMessage of WM_KILLFOCUS
190 * will fail because the handler will not be able to do a PostMessage!
191 * This is only needed for Windows 3.x, since NT dynamically expands
192 * the queue.
193 */
194 SetMessageQueue(64);
195
196 /*
197 * Create the console channels and install them as the standard
198 * channels. All I/O will be discarded until TkConsoleInit is
199 * called to attach the console to a text widget.
200 */
201
202 /*
203 * Windows expects us to parse our arguments ourselves.
204 */
205 setargv(&argc, &argv);
206
207 /*
208 * Replace argv[0] with full pathname of executable, and forward
209 * slashes substituted for backslashes.
210 */
211 GetModuleFileName(NULL, buffer, sizeof(buffer));
212 argv[0] = buffer;
213 for (p = buffer; *p != '\0'; p++) {
214 if (*p == '\\') {
215 *p = '/';
216 }
217 }
218
219 AscDriver(argc, argv);
220 return 1;
221 }
222 #endif /* __WIN32__ */
223
224
225 /*
226 * int AscDriver( argc, argv )
227 * int argc;
228 * char *argv;
229 *
230 * A common entry point for Windows and Unix. The corresponding
231 * WinMain() and main() functions just call this function.
232 *
233 * This function creates a Tcl interpreter, initializes Tcl and Tk,
234 * initializes the Ascend data structures, sets up the user's
235 * environment, sources ASCEND's startup script, and calls Tk_MainLoop
236 * so the user can interact with ASCEND. Cleans up and exits the
237 * program when Tk_MainLoop returns.
238 *
239 * This function is based on the functions Tk_Main and Tcl_AppInit
240 * from the Tk8.0 distribution. See the files tkMain.c and tkAppInit.c
241 * in the Tk sources.
242 *
243 */
244 static int AscDriver(int argc, CONST84 char *argv[])
245 {
246
247 /*
248 * Set the "tcl_interactive" variable.
249 *
250 * ASCEND sets tty to `1', since we assume ASCEND is always interactive.
251 */
252 tty = 1;
253 #ifdef USE_ASC_PRINTF
254 Asc_PrintInit();
255 #endif /* USE_ASC_PRINTF */
256
257 /*
258 * Now that our console and printing functions are properly
259 * initialized, print our startup banner.
260 */
261 PRINTF("ASCEND VERSION IV\n");
262 PRINTF("Compiler Implemention Version: 2.0\n");
263 PRINTF("Written by Tom Epperly,Kirk Abbott, and Ben Allan\n");
264 PRINTF("Copyright(C) 1990, 1993, 1994 Thomas Guthrie Epperly\n");
265 PRINTF(" Built: %s %s %s\n",__DATE__,__TIME__,build_name);
266 PRINTF("Copyright(C) 1993-1996 Kirk Andre Abbott, Ben Allan\n");
267 PRINTF("Copyright(C) 1997 Carnegie Mellon University\n");
268
269
270 /*
271 * Initialize ASCEND C Structures
272 * Create ASCEND Tcl Commands
273 */
274 clock();
275 /* the next line should NOT be Asc_SignalHandlerPush */
276 (void)signal(SIGINT, AscTrap);
277 #ifdef DEBUG_MALLOC
278 InitDebugMalloc();
279 ascstatus("Memory status after calling InitDebugMalloc()");
280 #endif /* DEBUG_MALLOC */
281 if ( Asc_CompilerInit(g_interface_simplify_relations) != 0 ) {
282 Asc_Panic(2, "Asc_CompilerInit",
283 "Insufficient memory to initialize compiler.");
284 }
285 SlvRegisterStandardClients();
286 /*
287 * Loop infinitely, waiting for commands to execute. When there
288 * are no windows left, Tk_MainLoop returns and we exit.
289 */
290 #ifdef DEBUG_MALLOC
291 ascstatus("Memory status before calling Tk_MainLoop()");
292 #endif /* DEBUG_MALLOC */
293 #ifdef DEBUG_MALLOC
294 ascstatus("Memory status after Tk_MainLoop() exits");
295 #endif /* DEBUG_MALLOC */
296
297 AscProcessCommandLine( argc, argv);
298 /* * App goes here. */
299
300
301 /* app done now. */
302
303 /*
304 * Do ASCEND Cleanup
305 */
306 Asc_HelpDestroy();
307 Asc_UnitValue(NULL);
308 Asc_SolvMemoryCleanup();
309 Asc_CompilerDestroy();
310 Asc_DestroyEnvironment();
311 #ifdef DEBUG_MALLOC
312 ascshutdown("Memory status just before exiting");
313 #endif /* DEBUG_MALLOC */
314
315 return 0;
316 }
317
318
319 static int AscProcessCommandLine( int argc, CONST84 char **argv)
320 {
321 int i;
322 int flag; /* set to 1 for `+arg', -1 for `-arg' */
323 size_t length; /* length of an argv */
324 char *args;
325 char buf[MAXIMUM_NUMERIC_LENGTH]; /* space for integer->string conversion */
326 int new_argc = 0; /* the argc we will pass to Tcl */
327 #ifdef ZZ_DEBUG
328 zz_debug = 0; /* nonzero to print parser debugging info*/
329 #endif
330
331 for( i = 1; i < argc; i++ ) {
332 if( (length = strlen(argv[i])) == 0 ) {
333 /* ignore 0-length arguments */
334 continue;
335 }
336
337 if(( length >= 2 ) && ( strncmp(argv[i],"-h",2) == 0 )) {
338 AscPrintHelpExit(argv[0]);
339 }
340 if(( length >= 2 ) && ( strncmp(argv[i],"-H",2) == 0 )) {
341 AscPrintHelpExit(argv[0]);
342 }
343 if(( length >= 4 ) && ( strncmp(argv[i],"help",4) == 0 )) {
344 AscPrintHelpExit(argv[0]);
345 }
346
347 if( argv[i][0] == '-' ) {
348 flag = -1;
349 } else if( argv[i][0] == '+' ) {
350 flag = 1;
351 } else {
352 flag = 0;
353 }
354
355 if(( length == 2 ) && ( flag != 0 )) {
356 switch( argv[i][1] ) {
357 case 'd':
358 /* '-d' turns on scanner debugging (if ascend was built with it)
359 * '+d' turns off scanner debugging [default]
360 */
361 if( flag == -1 ) {
362 #ifdef ZZ_DEBUG
363 zz_debug = 1;
364 } else {
365 zz_debug = 0;
366 #else
367 FPRINTF(ASCERR, "Sorry, %s wasn't compiled with %s defined.\n",
368 argv[0], "ZZ_DEBUG");
369 #endif /* ZZ_DEBUG */
370 }
371 break;
372 case 's':
373 /* '-s' turns on compiler optimizations [default]
374 * '+s' turns off compiler optimizations
375 */
376 if( flag == -1 ) {
377 g_interface_simplify_relations = 1;
378 } else {
379 g_interface_simplify_relations = 0;
380 }
381 break;
382 case 't':
383 /* '-t' turns on timing of compiler optimizations
384 * '+t' turns off timing of compiler optimizations [default]
385 */
386 if( flag == 0 ) {
387 g_compiler_timing = 1;
388 } else {
389 g_compiler_timing = 0;
390 }
391 break;
392 case 'c':
393 case 'g':
394 fprintf(ASCERR, "WARNING! Obsolete ASCEND option \"%s\"\n", argv[i]);
395 break;
396 default:
397 /* unknown ASCEND option, pass it on to Tcl
398 */
399 argv[++new_argc] = argv[i];
400 break;
401 }
402 } else {
403 /* unknown ASCEND option, pass it on to Tcl
404 */
405 argv[++new_argc] = argv[i];
406 }
407 }
408
409 return 0;
410 }
411
412 /*
413 * AscPrintHelpExit(invoke_name)
414 * CONST char *invoke_name;
415 *
416 * Print a help message and exit. Use invoke_name as the name of
417 * the binary
418 */
419 static
420 void AscPrintHelpExit(CONST char *invoke_name)
421 {
422 PRINTF("usage: %s [options]\n"
423 "\n"
424 "where options include [default value]:\n"
425 " -h print this message\n"
426 " -/+d turn on/off yacc debugging [off]\n"
427 " -/+s turn on/off compiler optimizations [on]\n"
428 " -/+t turn on/off timing of compiler operations [off]\n",
429 invoke_name);
430 exit(0);
431 }
432
433
434 /*
435 * AscTrap(sig)
436 * int sig;
437 *
438 * Function to call when we receive an interrupt.
439 */
440 static
441 void AscTrap(int sig)
442 {
443 putchar('\n');
444 Asc_Panic(sig, "AscTrap", "Caught Signal: %d", sig);
445 }
446
447
448
449 /*
450 *----------------------------------------------------------------------
451 * Tom Epperly's Malloc Debugger
452 *----------------------------------------------------------------------
453 */
454 #ifdef DEBUG_MALLOC
455 static void InitDebugMalloc(void)
456 {
457 union dbmalloptarg m;
458 m.str = NULL;
459 m.i = 0;
460 dbmallopt(MALLOC_CKDATA,&m);
461 }
462
463 #endif /* DEBUG_MALLOC */
464
465 #ifdef __WIN32__
466 /*
467 *-------------------------------------------------------------------------
468 *
469 * setargv --
470 *
471 * Parse the Windows command line string into argc/argv. Done here
472 * because we don't trust the builtin argument parser in crt0.
473 * Windows applications are responsible for breaking their command
474 * line into arguments.
475 *
476 * 2N backslashes + quote -> N backslashes + begin quoted string
477 * 2N + 1 backslashes + quote -> literal
478 * N backslashes + non-quote -> literal
479 * quote + quote in a quoted string -> single quote
480 * quote + quote not in quoted string -> empty string
481 * quote -> begin quoted string
482 *
483 * Results:
484 * Fills argcPtr with the number of arguments and argvPtr with the
485 * array of arguments.
486 *
487 * Side effects:
488 * Memory allocated.
489 *
490 * This function is from the Tk 8.0 distribution. See win/winMain.c in
491 * their sources.
492 *
493 *--------------------------------------------------------------------------
494 */
495 static void
496 setargv(argcPtr, argvPtr)
497 int *argcPtr; /* Filled with number of argument strings. */
498 char ***argvPtr; /* Filled with argument strings (malloc'd). */
499 {
500 char *cmdLine, *p, *arg, *argSpace;
501 char **argv;
502 int argc, size, inquote, copy, slashes;
503
504 cmdLine = GetCommandLine();
505
506 /*
507 * Precompute an overly pessimistic guess at the number of arguments
508 * in the command line by counting non-space spans.
509 */
510
511 size = 2;
512 for (p = cmdLine; *p != '\0'; p++) {
513 if (isspace(*p)) {
514 size++;
515 while (isspace(*p)) {
516 p++;
517 }
518 if (*p == '\0') {
519 break;
520 }
521 }
522 }
523 argSpace = (char *) ckalloc((unsigned) (size * sizeof(char *)
524 + strlen(cmdLine) + 1));
525 argv = (char **) argSpace;
526 argSpace += size * sizeof(char *);
527 size--;
528
529 p = cmdLine;
530 for (argc = 0; argc < size; argc++) {
531 argv[argc] = arg = argSpace;
532 while (isspace(*p)) {
533 p++;
534 }
535 if (*p == '\0') {
536 break;
537 }
538
539 inquote = 0;
540 slashes = 0;
541 while (1) {
542 copy = 1;
543 while (*p == '\\') {
544 slashes++;
545 p++;
546 }
547 if (*p == '"') {
548 if ((slashes & 1) == 0) {
549 copy = 0;
550 if ((inquote) && (p[1] == '"')) {
551 p++;
552 copy = 1;
553 } else {
554 inquote = !inquote;
555 }
556 }
557 slashes >>= 1;
558 }
559
560 while (slashes) {
561 *arg = '\\';
562 arg++;
563 slashes--;
564 }
565
566 if ((*p == '\0') || (!inquote && isspace(*p))) {
567 break;
568 }
569 if (copy != 0) {
570 *arg = *p;
571 arg++;
572 }
573 p++;
574 }
575 *arg = '\0';
576 argSpace = arg + 1;
577 }
578 argv[argc] = NULL;
579
580 *argcPtr = argc;
581 *argvPtr = argv;
582 }
583
584 #endif /* __WIN32__ */

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22