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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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