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

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