source: vis_dev/vis-2.3/src/cmd/cmdMisc.c@ 31

Last change on this file since 31 was 14, checked in by cecile, 15 years ago

vis2.3

File size: 57.2 KB
Line 
1/**CFile***********************************************************************
2
3 FileName [cmdMisc.c]
4
5 PackageName [cmd]
6
7 Synopsis [Variable table; miscellaneous commands related to the general
8 system.]
9
10 Author [SIS]
11
12 Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California.
13 All rights reserved.
14
15 Permission is hereby granted, without written agreement and without license
16 or royalty fees, to use, copy, modify, and distribute this software and its
17 documentation for any purpose, provided that the above copyright notice and
18 the following two paragraphs appear in all copies of this software.
19
20 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
21 DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
22 OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
23 CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
26 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
27 FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
28 "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
29 MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
30
31******************************************************************************/
32
33#include "cmdInt.h"
34#include <errno.h>
35
36static char rcsid[] UNUSED = "$Id: cmdMisc.c,v 1.59 2009/04/11 18:25:50 fabio Exp $";
37
38/*---------------------------------------------------------------------------*/
39/* Constant declarations */
40/*---------------------------------------------------------------------------*/
41/* The maximum length of an input line */
42#define MAX_STR 32768
43
44
45/*---------------------------------------------------------------------------*/
46/* Variable declarations */
47/*---------------------------------------------------------------------------*/
48avl_tree *cmdAliasTable;
49avl_tree *cmdFlagTable;
50
51static boolean fileCreated;
52
53
54/**AutomaticStart*************************************************************/
55
56/*---------------------------------------------------------------------------*/
57/* Static function prototypes */
58/*---------------------------------------------------------------------------*/
59
60static int CommandTime(Hrc_Manager_t ** hmgr, int argc, char ** argv);
61static int CommandEcho(Hrc_Manager_t ** hmgr, int argc, char ** argv);
62static int CommandSetBddParameters(Hrc_Manager_t ** hmgr, int argc, char ** argv);
63static int CommandMemoryProfile(Hrc_Manager_t ** hmgr, int argc, char ** argv);
64static int CommandQuit(Hrc_Manager_t ** hmgr, int argc, char ** argv);
65static int CommandUsage(Hrc_Manager_t ** hmgr, int argc, char ** argv);
66static int CommandWhich(Hrc_Manager_t ** hmgr, int argc, char ** argv);
67static int CommandHistory(Hrc_Manager_t ** hmgr, int argc, char ** argv);
68static int CommandAlias(Hrc_Manager_t ** hmgr, int argc, char ** argv);
69static int CommandUnalias(Hrc_Manager_t ** hmgr, int argc, char ** argv);
70static int CommandSetVariable(Hrc_Manager_t ** hmgr, int argc, char ** argv);
71static int CommandUnsetVariable(Hrc_Manager_t ** hmgr, int argc, char ** argv);
72static int CommandHelp(Hrc_Manager_t ** hmgr, int argc, char ** argv);
73static int CommandSource(Hrc_Manager_t ** hmgr, int argc, char ** argv);
74static void print_alias(char * value);
75static char * command_alias_help(char * command);
76static void FlushBuffers(int sigtype);
77
78/**AutomaticEnd***************************************************************/
79
80
81/*---------------------------------------------------------------------------*/
82/* Definition of exported functions */
83/*---------------------------------------------------------------------------*/
84
85
86/**Function********************************************************************
87
88 Synopsis [Looks up value of flag in table of named values.]
89
90 Description [The command parser maintains a table of named values. These
91 are manipulated using the 'set' and 'unset' commands. The value of the
92 named flag is returned, or NIL(char) is returned if the flag has not been
93 set.]
94
95 SideEffects []
96
97******************************************************************************/
98char *
99Cmd_FlagReadByName(
100 char * flag)
101{
102 char *value;
103
104 if (avl_lookup(cmdFlagTable, flag, &value)) {
105 return value;
106 }
107 else {
108 return NIL(char);
109 }
110}
111
112
113/**Function********************************************************************
114
115 Synopsis [Updates a set value by calling instead of set command.]
116
117 Description [Updates a set value by calling instead of set command.]
118
119 SideEffects []
120
121******************************************************************************/
122void
123Cmd_FlagUpdateValue(
124 char * key, char * value)
125{
126 char *oldValue, *newValue;
127
128 if (!key)
129 return;
130 if (value)
131 newValue = util_strsav(value);
132 else
133 newValue = util_strsav("");
134
135 if (avl_delete(cmdFlagTable, &key, &oldValue))
136 FREE(oldValue);
137
138 (void) avl_insert(cmdFlagTable, key, newValue);
139}
140
141
142/**Function********************************************************************
143
144 Synopsis [Deletes a set value by calling instead of unset command.]
145
146 Description [Deletes a set value by calling instead of unset command.]
147
148 SideEffects []
149
150******************************************************************************/
151void
152Cmd_FlagDeleteByName(
153 char * key)
154{
155 char *value;
156
157 if (!key)
158 return;
159
160 if (avl_delete(cmdFlagTable, &key, &value)) {
161 FREE(key);
162 FREE(value);
163 }
164}
165
166
167/**Function********************************************************************
168
169 Synopsis [Initializes the command package.]
170
171 SideEffects [Commands are added to the command table.]
172
173 SeeAlso [Cmd_End]
174
175******************************************************************************/
176void
177Cmd_Init(void)
178{
179 char *path;
180 char *lib_name;
181
182
183 cmdCommandTable = avl_init_table((int(*)(const void *, const void *))strcmp);
184 cmdFlagTable = avl_init_table((int(*)(const void *, const void *))strcmp);
185 cmdAliasTable = avl_init_table((int(*)(const void *, const void *))strcmp);
186
187 Cmd_CommandAdd("alias", CommandAlias, 0);
188 Cmd_CommandAdd("echo", CommandEcho, 0);
189 Cmd_CommandAdd("help", CommandHelp, 0);
190 Cmd_CommandAdd("quit", CommandQuit, 0);
191 Cmd_CommandAdd("source", CommandSource, 0);
192/* Cmd_CommandAdd("undo", CommandUndo, 0); */
193 Cmd_CommandAdd("set", CommandSetVariable, 0);
194 Cmd_CommandAdd("unalias", CommandUnalias, 0);
195 Cmd_CommandAdd("unset", CommandUnsetVariable, 0);
196 Cmd_CommandAdd("time", CommandTime, 0);
197 Cmd_CommandAdd("usage", CommandUsage, 0);
198 Cmd_CommandAdd("history", CommandHistory, 0);
199 Cmd_CommandAdd("which", CommandWhich, 0);
200 Cmd_CommandAdd("set_bdd_parameters" , CommandSetBddParameters, 0);
201 Cmd_CommandAdd("_memory_profile", CommandMemoryProfile, 0);
202 fileCreated = FALSE;
203
204 /* Program the signal of type USR1 to flush vis_stdout and vis_stderr */
205#ifdef SIGUSR1
206 (void) signal(SIGUSR1, FlushBuffers);
207#endif
208
209 /* set the default open_path */
210 lib_name = Vm_VisObtainLibrary();
211 path = ALLOC(char, strlen(lib_name) + 20);
212 sprintf(path, "set open_path .:%s", lib_name);
213 Cmd_CommandExecute(NULL, path);
214 FREE(lib_name);
215 FREE(path);
216}
217
218
219/**Function********************************************************************
220
221 Synopsis [Ends the command package.]
222
223 Description [Ends the command package. Tables are freed, and the global
224 error string is freed.]
225
226 SideEffects []
227
228 SeeAlso [Cmd_Init]
229
230******************************************************************************/
231void
232Cmd_End(void)
233{
234 avl_free_table(cmdFlagTable, (void (*)(char *))free, (void (*)(char *))free);
235 avl_free_table(cmdCommandTable, (void (*)(char *)) 0, CmdCommandFree);
236 avl_free_table(cmdAliasTable, (void (*)(char *)) 0, CmdAliasFree);
237 if (cmdBackupHmgr != NIL(Hrc_Manager_t)) {
238 Hrc_ManagerFree(cmdBackupHmgr);
239 }
240 error_cleanup();
241
242 if (fileCreated == TRUE) {
243 (void) fprintf(vis_stdout, "Purify has created a temporary file. The file");
244 (void) fprintf(vis_stdout, " must be deleted.\n");
245 }
246}
247
248
249/**Function********************************************************************
250
251 Synopsis [Test that the given string is an integer. Returns 0 if string is
252 not an integer, 1 if the integer is too big for int, and 2 if integer fits
253 in int.]
254
255 SideEffects [Sets the pointer value if the string is an integer small enough
256 for int.]
257
258******************************************************************************/
259int
260Cmd_StringCheckIsInteger(
261 char *string,
262 int *value)
263{
264 char *ptr;
265 long l;
266
267 errno = 0 ;
268 l = strtol (string, &ptr, 0) ;
269 if(*ptr != '\0')
270 return 0;
271 if (errno != 0)
272 return 1;
273 if ((l > MAXINT) || (l < -1 - MAXINT))
274 return 1 ;
275 *value = (int) l;
276 return 2 ;
277}
278
279
280/*---------------------------------------------------------------------------*/
281/* Definition of internal functions */
282/*---------------------------------------------------------------------------*/
283
284
285/**Function********************************************************************
286
287 Synopsis [required]
288
289 Description [optional]
290
291 SideEffects [required]
292
293 SeeAlso [optional]
294
295******************************************************************************/
296void
297CmdFreeArgv(int argc, char ** argv)
298{
299 int i;
300
301 for(i = 0; i < argc; i++) {
302 FREE(argv[i]);
303 }
304 FREE(argv);
305}
306
307
308/**Function********************************************************************
309
310 Synopsis [required]
311
312 Description [optional]
313
314 SideEffects [required]
315
316 SeeAlso [optional]
317
318******************************************************************************/
319void
320CmdAliasFree(
321 char * value)
322{
323 CmdAliasDescr_t *alias = (CmdAliasDescr_t *) value;
324
325 CmdFreeArgv(alias->argc, alias->argv);
326 FREE(alias->name); /* same as key */
327 FREE(alias);
328}
329
330
331
332/*---------------------------------------------------------------------------*/
333/* Definition of static functions */
334/*---------------------------------------------------------------------------*/
335
336/**Function********************************************************************
337
338 Synopsis [Implements the time command.]
339
340 CommandName [time]
341 CommandSynopsis [provide a simple elapsed time value]
342 CommandArguments [\[-h\]\[-u\]]
343 CommandDescription [Prints the processor time used since the last time
344 command, and the total processor time used since VIS was started. <p>
345 By default, the time reported is the CPU time spent executing instructions
346 of the calling process and the time this process waited for children that
347 terminated.<p>
348 Command options:<p>
349 <dl><dt> -h
350 <dd> Print the command usage.
351 </dl>
352 <dl><dt> -u
353 <dd> Exclude child process time.
354 </dl>]
355
356 SideEffects []
357
358******************************************************************************/
359static int
360CommandTime(
361 Hrc_Manager_t ** hmgr,
362 int argc,
363 char ** argv)
364{
365 static long last_time_u = 0;
366 static long last_time_c = 0;
367 long time;
368 int c;
369 boolean excludeChildren = FALSE;
370
371 util_getopt_reset();
372 while ((c = util_getopt(argc,argv,"hu")) != EOF){
373 switch(c){
374 case 'h':
375 goto usage;
376 case 'u':
377 excludeChildren = TRUE;
378 break;
379 default:
380 goto usage;
381 }
382 }
383
384 if (argc != util_optind) {
385 goto usage;
386 }
387
388 if (excludeChildren) {
389 time = util_cpu_time();
390 (void) fprintf(vis_stdout,
391 "elapse: %2.1f seconds, total: %2.1f seconds\n",
392 (time - last_time_u) / 1000.0, time / 1000.0);
393 last_time_u = time;
394 } else {
395 time = util_cpu_ctime();
396 (void) fprintf(vis_stdout,
397 "elapse: %2.1f seconds, total: %2.1f seconds\n",
398 (time - last_time_c) / 1000.0, time / 1000.0);
399 last_time_c = time;
400 }
401 return 0;
402
403usage:
404 (void) fprintf(vis_stderr, "usage: time [-h][-u]\n");
405 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
406 (void) fprintf(vis_stderr, " -u \t\texclude child process time\n");
407 return 1;
408}
409
410/**Function********************************************************************
411
412 Synopsis [Implements the echo command.]
413
414 CommandName [echo]
415 CommandSynopsis [merely echo the arguments]
416 CommandArguments [\[-h\] &lt;args&gt;]
417 CommandDescription [Echoes the arguments to standard output.<p>
418 Command options:<p>
419 <dl><dt> -h
420 <dd> Print the command usage.
421 </dl>]
422
423 SideEffects []
424
425******************************************************************************/
426static int
427CommandEcho(
428 Hrc_Manager_t ** hmgr,
429 int argc,
430 char ** argv)
431{
432 int i;
433 int c;
434
435 util_getopt_reset();
436 while ((c = util_getopt(argc, argv, "h")) != EOF) {
437 switch(c) {
438 case 'h':
439 goto usage;
440 default:
441 goto usage;
442 }
443 }
444
445 for(i = 1; i < argc; i++) {
446 (void) fprintf(vis_stdout, "%s ", argv[i]);
447 }
448 (void) fprintf(vis_stdout, "\n");
449 return 0;
450
451 usage:
452 (void) fprintf(vis_stderr, "usage: echo [-h] string \n");
453 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
454 return (1);
455}
456
457/**Function********************************************************************
458
459 Synopsis [Implements the set_bdd_parameters command.]
460
461 SideEffects []
462
463 CommandName [set_bdd_parameters]
464
465 CommandSynopsis [Creates a table with the value of all the flags currently
466 active in VIS and calls the function bdd_set_parameters with the manager of
467 the current place in the hierarchy and the table.]
468
469 CommandArguments [\[-h\]\[-s\]]
470
471 CommandDescription [The command obtains the bdd manager of the current point
472 in the hierarchy. Given this manager and the set of pairs (variable,value) of
473 the VIS environment, the function sets specific BDD parameters to the given
474 values. This command works in conjunction with print_bdd_stats.<p>
475
476 Print_bdd_stats first prints a report of the parameters and statistics of the
477 current bdd_manager. By using the command "set", the user may modify the
478 value of any of the parameters of the underlying bdd package. The way to do
479 it is by setting a value in the variable <tt>BDD.parameter name</tt> where
480 <tt>parameter name<\tt> is the name of the parameter exactly as printed by
481 the print_bdd_stats command. In order to "re-program" the underlying bdd
482 package this command must be invoked.<p>
483
484 Command options:<p>
485
486 <dl>
487
488 <dt> -h
489 <dd> Print the command usage.
490
491 <dt> -s
492 <dd> Print the bdd parameter and statistics after the modification.
493
494 </dl>
495 ]
496
497******************************************************************************/
498static int
499CommandSetBddParameters(
500 Hrc_Manager_t ** hmgr,
501 int argc,
502 char ** argv)
503{
504 Ntk_Network_t *network;
505 boolean showAfter;
506 int c;
507
508 showAfter = FALSE;
509 network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
510
511 /*
512 * Parse the command line.
513 */
514 util_getopt_reset();
515 while ((c = util_getopt(argc, argv, "hs")) != EOF) {
516 switch (c) {
517 case 'h':
518 goto usage;
519 case 's':
520 showAfter = TRUE;
521 break;
522 default:
523 goto usage;
524 }
525 }
526
527 /* flatten_hierarchy and static_order must have been invoked already. */
528 if (network == NIL(Ntk_Network_t)) {
529 return 1;
530 }
531 if (!Ntk_NetworkReadMddManager(network)) {
532 (void) fprintf(vis_stderr, "The MDD variables have not been ordered. ");
533 (void) fprintf(vis_stderr, "Use static_order.\n");
534 return 1;
535 }
536
537 /* Create the table of variable->value */
538 bdd_set_parameters(Ntk_NetworkReadMddManager(network), cmdFlagTable,
539 vis_stdout);
540
541 if (showAfter) {
542 bdd_print_stats(Ntk_NetworkReadMddManager(network), vis_stdout);
543 }
544
545 return 0; /* Everything okay */
546
547usage:
548 (void) fprintf(vis_stderr, "usage: set_bdd_parameters [-h] [-s]\n");
549 (void) fprintf(vis_stderr, " -h print the command usage\n");
550 (void) fprintf(vis_stderr, " -s print also the bdd statistics\n");
551
552 return 1;
553}
554
555/**Function********************************************************************
556
557 Synopsis [Implements the _memory_profile command.]
558
559 CommandName [_memory_profile]
560
561 CommandSynopsis [It shows the amount of memory used by every pacakge.]
562
563 CommandArguments [\[-f &lt;filename&gt;\] \[-h\] \[-p\] \[-u &lt;units&gt;\]]
564
565 CommandDescription [This command intregrates the output from purify with a
566 function map generated by a perlscript plus another perlscript to generate a
567 memory profile of vis.<p>
568
569 This command relies on the output of purify to a file to call the script
570 "memoryaccount" and produce a summary of how much memory has been allocated
571 by each package. Although this command may appear simple it requires the
572 interaction of two scripts and three files, so special care should be taken
573 when attempting to modify it.<p>
574
575 Here is the way it works. The code in this command is conditionally compiled
576 depending on the definition of the symbol <tt>PURIFY</tt>. If the symbol is
577 not defined, the program prints a message notifying that the command is not
578 operative in this executable. If <tt>PURIFY</tt> has been defined, there are
579 certain things that are assumed. The executable has been linked with
580 purify. The output of purify is being redirected to a file with name
581 <tt>purify.log</tt>. The perl script <tt>memoryaccount</tt> is in
582 <tt>$VIS/common/share</tt> and it is executable. There exists a file mapping
583 function names to packages in the same place whose name is <tt>.fmap</tt>.<p>
584
585 The command then calls <tt>purify_all_inuse()</tt> to force purify to dump to
586 the file <tt>purify.log</tt> the information about the memory that is
587 currently visible to the program. This memory is not the total memory
588 allocated by the program since there may be leaked memory that is no longer
589 accessible. A temporary file is created and the script <tt>memoryaccount</tt>
590 is called to analyze the file <tt>purify.log</tt> and write in the temporary
591 file the memory profile obtained from it. Once the script is done, the
592 temporary file is dumped to <tt>vis_stdout</tt> and deleted.<p>
593
594 Since most of the computation in this command is done by the pearlscript
595 <tt>memoryaccount</tt>, for more information please refer to the message
596 printed when the script is invoked with the option <tt>-h</tt>.
597
598 Command options:<p>
599
600 <dl>
601 <dt> -f &lt;filename&gt;
602 <dd> File to read the dump from. The default is purify.log. This option
603 should be used if and only if the option <tt>-log-file</tt> has been used at
604 the linking stage when building the executable.
605 <dt> -h
606 <dd> Print the command usage.
607 <dt> -p
608 <dd> Print also the packages that did not allocated any visible memory
609 <dt> -u &lt;units&gt;
610 <dd> Units to print the memory usage in. It may be "b" for
611 bytes, "k" for kilobytes, "m" for megabytes and "g" for gigabytes. The default
612 is bytes.
613 </dl>
614 ]
615
616 SideEffects []
617
618******************************************************************************/
619static int
620CommandMemoryProfile(
621 Hrc_Manager_t ** hmgr,
622 int argc,
623 char ** argv)
624{
625
626 int c;
627 char options[128];
628#ifdef PURIFY
629 char tmpFileName[128];
630 FILE *fp;
631 char command[256];
632 char *visDirectoryName;
633 int systemStatus;
634#endif
635
636 /*
637 * Parse command line options.
638 */
639 options[0] = 0;
640 util_getopt_reset();
641 while ((c = util_getopt(argc, argv, "f:hpu:")) != EOF) {
642 switch(c) {
643 case 'f':
644 strcat(options, " -f ");
645 strcat(options, util_optarg);
646 break;
647 case 'h':
648 goto usage;
649 case 'p':
650 strcat(options, " -p ");
651 break;
652 case 'u':
653 strcat(options, " -u ");
654 strcat(options, util_optarg);
655 break;
656 default:
657 goto usage;
658 }
659 }
660
661
662#ifdef PURIFY
663 /* Flag to remember that a file has been created by purify */
664 fileCreated = TRUE;
665
666 /* Obtain the name of a temporary file */
667 tmpnam(tmpFileName);
668
669 /* Kick purify to dump the data in the file */
670 purify_all_inuse();
671
672 /* Obtain the path to the perl script */
673 visDirectoryName = Vm_VisObtainLibrary();
674
675 /* Prepare the string to be sent to a shell */
676 (void)sprintf(command, "%s/memoryaccount %s %s/.fmap ./.fmap >%s",
677 visDirectoryName, options, visDirectoryName,
678 tmpFileName);
679
680 /* Effectively execute the perlscript */
681 systemStatus = system(command);
682 if (systemStatus != 0) {
683 return 1;
684 }
685
686 fp = Cmd_FileOpen(tmpFileName, "r", NIL(char *), 1);
687
688 /* Check if the open has been successful */
689 if (fp == NIL(FILE)) {
690 (void) fprintf(vis_stderr, "** cmd error: File %s was not found\n", tmpFileName);
691 return 1;
692 }
693
694 /* Dump the contents of the result file in vis_stdout */
695 while(fgets(command, 128, fp) != NIL(char)) {
696 (void) fprintf(vis_stdout, "%s", command);
697 }
698 fclose(fp);
699
700 /* Remove the temporary file */
701#if HAVE_UNLINK
702 unlink(tmpFileName);
703#endif
704#else
705 (void) fprintf(vis_stderr, "** cmd error: Command not available: Vis has not been ");
706 (void) fprintf(vis_stderr, "compiled with purify.\n");
707#endif
708
709 return 0; /* normal exit */
710
711 usage:
712 (void) fprintf(vis_stderr, "usage: _memory_profile [-f <filename>] [-h] ");
713 (void) fprintf(vis_stderr, "[-p] [-u <units>] <filenames>\n");
714 (void) fprintf(vis_stderr, " -f <file>\tFile to read the purify dump");
715 (void) fprintf(vis_stderr, " from. The default is purify.log\n");
716 (void) fprintf(vis_stderr, " -h\t\tprint the command usage\n");
717 (void) fprintf(vis_stderr, " -p\t\tPrint also the packages that do not ");
718 (void) fprintf(vis_stderr, " allocate any memory\n");
719 (void) fprintf(vis_stderr, " -u <units>\tUnits to print the memory usage");
720 (void) fprintf(vis_stderr, " in. It may be b for bytes\n");
721 (void) fprintf(vis_stderr, " \t\tk for kilobytes, m for megabytes and ");
722 (void) fprintf(vis_stderr, "g for gigabutes.\n");
723 return 1; /* error exit */
724}
725
726
727/**Function********************************************************************
728
729 Synopsis [Implements the quit command.]
730
731 Description [A return value of -1 indicates a quick quit, -2 return frees
732 the memory.]
733
734 CommandName [quit]
735 CommandSynopsis [exit VIS]
736 CommandArguments [\[-h\] \[-s\]]
737 CommandDescription [Stops the program. Does not save the current network
738 before exiting.<p>
739 Command options:<p>
740 <dl><dt> -h
741 <dd> Print the command usage.
742 </dl>
743 <dl><dt> -s
744 <dd> Free all the memory before quitting.
745 This is slower, and is used for finding memory leaks.
746 </dl>
747 ]
748
749 SideEffects []
750
751******************************************************************************/
752static int
753CommandQuit(
754 Hrc_Manager_t ** hmgr,
755 int argc,
756 char ** argv)
757{
758 int c;
759
760 util_getopt_reset();
761 while ((c = util_getopt(argc,argv,"hs")) != EOF){
762 switch(c){
763 case 'h':
764 goto usage;
765 case 's':
766 return -2;
767 default:
768 goto usage;
769 }
770 }
771
772 if ( argc != util_optind){
773 goto usage;
774 }
775 return -1;
776
777 usage:
778 (void)fprintf(vis_stderr, "usage: quit [-h] [-s]\n");
779 (void)fprintf(vis_stderr, " -h print the command usage\n");
780 (void)fprintf(vis_stderr, " -s frees all the memory before quitting\n");
781 return 1;
782}
783
784/**Function********************************************************************
785
786 Synopsis [Implements the usage command.]
787
788 CommandName [usage]
789 CommandSynopsis [provide a dump of process statistics]
790 CommandArguments [\[-h\]]
791 CommandDescription [Prints a formatted dump of processor-specific usage
792 statistics. For Berkeley Unix, this includes all of the information in the
793 getrusage() structure.<p>
794 Command options:<p>
795 <dl><dt> -h
796 <dd> Print the command usage.
797 </dl> ]
798
799 SideEffects []
800
801******************************************************************************/
802static int
803CommandUsage(
804 Hrc_Manager_t ** hmgr,
805 int argc,
806 char ** argv)
807{
808 int c;
809
810 util_getopt_reset();
811 while ((c = util_getopt(argc,argv,"h")) != EOF){
812 switch(c){
813 case 'h':
814 goto usage;
815 default:
816 goto usage;
817 }
818 }
819
820 if (argc != util_optind){
821 goto usage;
822 }
823 util_print_cpu_stats(vis_stdout);
824 return 0;
825
826 usage:
827 (void) fprintf(vis_stderr, "usage: usage [-h]\n");
828 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
829 return 1;
830}
831
832/**Function********************************************************************
833
834 Synopsis [Implements the which command.]
835
836 CommandName [which]
837 CommandSynopsis [look for a file called name]
838 CommandArguments [\[-h\] &lt;file_name&gt;]
839 CommandDescription [Looks for a file in a set of directories
840 which includes the current directory as well as those in the VIS path.
841 If it finds it, it reports the path.
842 The path is specified through the "set open_path" command in the .visrc.<p>
843 Command options:<p>
844 <dl><dt> -h
845 <dd> Print the command usage.
846 </dl>
847 <dl><dt> &lt;file_name&gt;
848 <dd> File to be searched
849 </dl>]
850
851 SideEffects []
852
853 SeeAlso [set]
854
855******************************************************************************/
856static int
857CommandWhich(
858 Hrc_Manager_t ** hmgr,
859 int argc,
860 char ** argv)
861{
862 FILE *fp;
863 char *filename;
864 int c;
865
866 util_getopt_reset();
867 while ((c = util_getopt(argc,argv,"h")) != EOF){
868 switch(c){
869 case 'h':
870 goto usage;
871 default:
872 goto usage;
873 }
874 }
875
876 if (argc-1 != util_optind){
877 goto usage;
878 }
879
880 fp = Cmd_FileOpen(argv[1], "r", &filename, 0);
881 if (fp != 0) {
882 (void) fprintf(vis_stdout, "%s\n", filename);
883 (void) fclose(fp);
884 }
885 FREE(filename);
886 return 0;
887
888 usage:
889 (void)fprintf(vis_stderr,"usage: which [-h] file_name\n");
890 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
891 return 1;
892}
893
894
895/**Function********************************************************************
896
897 Synopsis [Implements the history command.]
898
899 CommandName [history]
900
901 CommandSynopsis [list previous commands and their event numbers]
902
903 CommandArguments [\[-h\] \[&lt;num&gt;\]]
904
905 CommandDescription [Lists previous commands and their event numbers.
906 This is a UNIX-like history mechanism inside the VIS shell.<p>
907 Command options:<p>
908 <dl><dt> -h
909 <dd> Print the command usage.
910 </dl>
911 <dl><dt> &lt;num&gt;
912 <dd> Lists the last &lt;num&gt; events. Lists the last
913 30 events if &lt;num&gt; is not specified.
914 </dl><p>
915
916 History Substitution:<p>
917
918 The history substitution mechanism is a simpler version of the csh history
919 substitution mechanism. It enables you to reuse words from previously typed
920 commands.<p>
921
922 The default history substitution character is the `%' (`!' is default for
923 shell escapes, and `#' marks the beginning of a comment). This can be changed
924 using the "set" command. In this description '%' is used as the history_char.
925 The `%' can appear anywhere in a line. A line containing a history
926 substitution is echoed to the screen after the substitution takes place.
927 `%' can be preceded by a `\\' in order to escape the substitution,
928 for example, to enter a `%' into an alias or to set the prompt.<br><p>
929
930 Each valid line typed at the prompt is saved. If the "history" variable
931 is set (see help page for "set"), each line is also echoed to the history
932 file. You can use the "history" command to list the previously typed
933 commands. <p>
934
935 Substitutions: <p>
936
937 At any point in a line these history substitutions are
938 available.<p>
939 <dl><dt>%:0 <dd> Initial word of last command.</dl>
940 <dl><dt>%:n <dd> n-th argument of last command.</dl>
941 <dl><dt>%$ <dd> Last argument of last command.</dl>
942 <dl><dt>%* <dd> All but initial word of last command.</dl>
943
944 <dl><dt>%% <dd> Last command.</dl>
945 <dl><dt>%stuf <dd> Last command beginning with "stuf".</dl>
946 <dl><dt>%n <dd> Repeat the n-th command.</dl>
947 <dl><dt>%-n <dd> Repeat the n-th previous command.</dl>
948 <dl><dt>^old^new <dd> Replace "old" with "new" in previous command.
949 Trailing spaces are significant during substitution.
950 Initial spaces are not significant.</dl> ]
951
952 SideEffects []
953
954 SeeAlso [set]
955
956******************************************************************************/
957static int
958CommandHistory(
959 Hrc_Manager_t ** hmgr,
960 int argc,
961 char ** argv)
962{
963 int i, num, lineno;
964 int size;
965 int c;
966
967 util_getopt_reset();
968 while ((c = util_getopt(argc, argv, "h")) != EOF) {
969 switch(c) {
970 case 'h':
971 goto usage;
972 default:
973 goto usage;
974 }
975 }
976
977 if (argc > 3) {
978 goto usage;
979 }
980 num = 30;
981 lineno = 1;
982 for (i = 1; i < argc; i++) {
983 if (argv[i][0] == '-') {
984 if (argv[i][1] == 'h') {
985 lineno = 0;
986 }
987 else {
988 goto usage;
989 }
990 }
991 else {
992 num = atoi(argv[i]);
993 if (num <= 0) {
994 goto usage;
995 }
996 }
997 }
998 size = array_n(vm_commandHistoryArray);
999 num = (num < size) ? num : size;
1000 for (i = size - num; i < size; i++) {
1001 if (lineno != 0) {
1002 (void) fprintf(vis_stdout, "%d\t", i + 1);
1003 }
1004 (void) fprintf(vis_stdout, "%s\n", array_fetch(char *, vm_commandHistoryArray, i));
1005 }
1006 return(0);
1007
1008usage:
1009 (void) fprintf(vis_stderr, "usage: history [-h] [num]\n");
1010 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
1011 (void) fprintf(vis_stderr, " num \t\tprint the last num commands\n");
1012 return(1);
1013}
1014
1015
1016
1017
1018/**Function********************************************************************
1019
1020 Synopsis [Implements the alias command.]
1021
1022 CommandName [alias]
1023
1024 CommandSynopsis [provide an alias for a command]
1025
1026 CommandArguments [\[-h\] \[&lt;name&gt; \[&lt;string&gt;\]\]]
1027
1028 CommandDescription [The "alias" command, if given no arguments, will print
1029 the definition of all current aliases. <p>
1030
1031 Given a single argument, it will print the definition of that alias (if any).
1032
1033 Given two arguments, the keyword "name" becomes an alias for
1034 the command string "string", replacing any other alias with the
1035 same name.<p>
1036
1037 Command options:
1038 <dl><dt> -h
1039 <dd> Print the command usage.
1040 </dl>
1041 <dl><dt> &lt;name&gt;
1042 <dd> Alias
1043 </dl>
1044 <dl><dt> &lt;string&gt;
1045 <dd> Command string
1046 </dl>
1047
1048 It is possible to create aliases that take arguments by using the history
1049 substitution mechanism. To protect the history substitution character `%'
1050 from immediate expansion, it must be preceded by a `\\' when entering the
1051 alias. <p>
1052
1053 For example:<p>
1054 <pre>
1055 vis> alias read read_\\%:1 \\%:2.\\%:1
1056 vis> read blif lion
1057 </pre>
1058 will create an alias `read', execute "read_blif lion.blif". <p>
1059
1060 And...<p>
1061 <pre>
1062 vis> alias echo2 "echo Hi ; echo \\%* !"
1063 vis> echo2 happy birthday
1064 </pre>
1065 will print:<p>
1066 <pre>
1067 Hi
1068 happy birthday !
1069 </pre>
1070
1071 CAVEAT: Currently there is no check to see if there is a circular
1072 dependency in the alias definition. e.g.<p>
1073
1074 <pre>
1075 vis> alias foo "print_network_stats; print_network; foo"
1076 </pre>
1077
1078 creates an alias which refers to itself. Executing the command "foo" will
1079 result an infinite loop during which the commands "print_network_stats"
1080 and "print_network" will be executed.<p>
1081
1082 ]
1083
1084 SideEffects []
1085
1086 SeeAlso [unalias]
1087
1088******************************************************************************/
1089static int
1090CommandAlias(
1091 Hrc_Manager_t ** hmgr,
1092 int argc,
1093 char ** argv)
1094{
1095 int i;
1096 char *key, *value;
1097 CmdAliasDescr_t *alias;
1098 avl_generator *gen;
1099 int status;
1100 int c;
1101
1102 util_getopt_reset();
1103 while ((c = util_getopt(argc, argv, "h")) != EOF) {
1104 switch(c) {
1105 case 'h':
1106 goto usage;
1107 default:
1108 goto usage;
1109 }
1110 }
1111
1112
1113 if (argc == 1) {
1114 avl_foreach_item(cmdAliasTable, gen, AVL_FORWARD, &key, &value) {
1115 print_alias(value);
1116 }
1117 return 0;
1118
1119 }
1120 else if (argc == 2) {
1121 if (avl_lookup(cmdAliasTable, argv[1], &value)) {
1122 print_alias(value);
1123 }
1124 return 0;
1125 }
1126
1127 /* delete any existing alias */
1128 key = argv[1];
1129 if (avl_delete(cmdAliasTable, &key, &value)) {
1130 CmdAliasFree(value);
1131 }
1132
1133 alias = ALLOC(CmdAliasDescr_t, 1);
1134 alias->name = util_strsav(argv[1]);
1135 alias->argc = argc - 2;
1136 alias->argv = ALLOC(char *, alias->argc);
1137 for(i = 2; i < argc; i++) {
1138 alias->argv[i-2] = util_strsav(argv[i]);
1139 }
1140 status = avl_insert(cmdAliasTable, alias->name, (char *) alias);
1141 assert(!status); /* error here in SIS version, TRS, 8/4/95 */
1142 return 0;
1143
1144 usage:
1145 (void) fprintf(vis_stderr, "usage: alias [-h] [command [string]]\n");
1146 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
1147 return (1);
1148}
1149
1150
1151/**Function********************************************************************
1152
1153 Synopsis [Implements the unalias command.]
1154
1155 CommandName [unalias]
1156 CommandSynopsis [remove the definition of an alias.]
1157 CommandArguments [\[-h\] &lt;alias_names&gt;]
1158 CommandDescription [Removes the definition of an alias.<p>
1159 Command options:<p>
1160 <dl><dt> -h
1161 <dd> Print the command usage.
1162 </dl>
1163 <dl><dt> &lt;alias_names&gt;
1164 <dd> Aliases to be removed
1165 </dl>]
1166
1167 SideEffects []
1168
1169 SeeAlso [alias]
1170
1171******************************************************************************/
1172static int
1173CommandUnalias(
1174 Hrc_Manager_t ** hmgr,
1175 int argc,
1176 char ** argv)
1177{
1178 int i;
1179 char *key, *value;
1180 int c;
1181
1182 util_getopt_reset();
1183 while ((c = util_getopt(argc, argv, "h")) != EOF) {
1184 switch(c) {
1185 case 'h':
1186 goto usage;
1187 default:
1188 goto usage;
1189 }
1190 }
1191
1192 if (argc < 2) {
1193 goto usage;
1194 }
1195
1196 for(i = 1; i < argc; i++) {
1197 key = argv[i];
1198 if (avl_delete(cmdAliasTable, &key, &value)) {
1199 CmdAliasFree(value);
1200 }
1201 }
1202 return 0;
1203
1204 usage:
1205 (void) fprintf(vis_stderr, "usage: unalias [-h] alias_names\n");
1206 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
1207 return 1;
1208}
1209
1210
1211/**Function********************************************************************
1212
1213 Synopsis [Implements the set command.]
1214
1215 CommandName [set]
1216
1217 CommandSynopsis [set an environment variable]
1218
1219 CommandArguments [\[-h\] \[&lt;name&gt;\] \[&lt;value&gt;\]]
1220
1221 CommandDescription [ A variable environment is maintained by the command
1222 interpreter.
1223 The "set" command sets a variable to a particular value, and the
1224 "unset" command removes the definition of a variable.
1225 If "set" is given no arguments, it prints the current value of all variables.<p>
1226
1227 Command options:<p>
1228 <dl> <dt> -h
1229 <dd> Print the command usage.
1230 </dl>
1231 <dl> <dt> &lt;name&gt;
1232 <dd> Variable name
1233 </dl>
1234 <dl> <dt> &lt;value&gt;
1235 <dd> Value to be assigned to the variable.
1236 </dl>
1237
1238 <p>
1239 Interpolation of variables is allowed when using the set command. The
1240 variables are referred to with the prefix of '$'. So for example, the following
1241 can be done to check the value of a set variable:<br>
1242 <code>
1243 vis> set foo bar <br>
1244 vis> echo $foo <br>
1245 bar <br>
1246 </code>
1247
1248 The last line "bar" will the output produced by vis.<p>
1249
1250 Variables can be extended by using the character ':' to concatenate
1251 values. For example : <br>
1252 <code>
1253 vis> set foo bar <br>
1254 vis> set foo $foo:foobar <br>
1255 vis> echo $foo <br>
1256 bar:foobar <br>
1257 </code>
1258 The variable <code> foo </code> is extended with the value <code>
1259 foobar </code>. <p>
1260
1261 Whitespace characters may be present within quotes. However, variable
1262 interpolation lays the restriction that the characters ':' and '/' may
1263 not be used within quotes. This is to allow for recursive interpolation.
1264 So for example, the following is allowed<br>
1265 <code>
1266 vis> set "foo bar" this <br>
1267 vis> echo $"foo bar"<br>
1268 this <br>
1269 </code>
1270 The last line will be the output produced by vis. <br>
1271 But in the following, the value of the variable <code> foo/bar </code>
1272 will not be interpreted correctly:<p>
1273 <code>
1274 vis> set "foo/bar" this <br>
1275 vis> echo $"foo/bar" <br>
1276 foo/bar <br>
1277 </code>
1278 If a variable is not set by the "set" command, then the variable is returned
1279 unchanged.
1280 <p>
1281
1282 Different commands use environment information for different purposes.
1283 The command interpreter makes use of the following parameters:<p>
1284
1285 <dl>
1286 <dt><b>autoexec</b>
1287 <dd> Defines a command string to be automatically executed after every
1288 command processed by the command interpreter.
1289 This is useful for things like timing commands, or tracing the
1290 progress of optimization.
1291</dl>
1292
1293
1294 <dl><dt><b>open_path</b>
1295 <dd> "open_path" (in analogy to the shell-variable PATH) is a list of
1296 colon-separated strings giving directories to be searched whenever
1297 a file is opened for read. Typically the current directory (.) is
1298 first in this list. The standard system library (typically
1299 $VIS_LIBRARY_PATH) is always implicitly appended to the current path.
1300 This provides a convenient short-hand mechanism for reaching
1301 standard library files.
1302 </dl>
1303 <dl><dt> <b>vis_stderr </b>
1304 <dd> Standard error (normally stderr) can be re-directed to a file
1305 by setting the variable vis_stderr.
1306 </dl>
1307
1308 <dl><dt> <b>vis_stdout</b>
1309 <dd> Standard output (normally stdout) can be re-directed to a file
1310 by setting the variable vis_stdout.
1311 </dl>
1312
1313 Building MDDs for the network makes use of following setting:
1314 <dl><dt> <b>partition_method</b>
1315 <dd> This parameter is used to select the method for creating the
1316 partition. The vertices of a partition correspond to the
1317 combinational inputs, combinational outputs, and any intermediate nodes used. Each vertex has a multi-valued
1318 function (represented by MDDs) expressing the function of the corresponding
1319 network node in terms of the partition vertices in its transitive fanin.
1320 Hence, the MDDs of the partition represent a partial collapsing of the
1321 network. The possible values of partition_method are:
1322 <dl>
1323 <dt> <b>inout</b>
1324 <dd>Expresses the combinational outputs in terms of the
1325 combinational inputs. This is the default partitioning method.
1326
1327 <dt> <b>total</b>
1328 <dd> The partition built is isomorphic to the combinational
1329 part of the network. The function of each node is expressed in terms of its
1330 immediate fanins.
1331
1332 <dt> <b>frontier</b>
1333 <dd> The partition built contains the combinational part of the
1334 network as well as vertices corresponding to some intermediate
1335 nodes. These vertices are generated to control the MDD sizes of the
1336 combinational outputs. The number of intermediate variables can be
1337 controlled by the parameter "partition_threshold". The method
1338 "inout" and "total" are special cases of this method (corresponding
1339 to a partition_threshold of infinity and 0 respectively).
1340
1341 </dl>
1342 </dl>
1343 <dl><dt> <b>partition_threshold</b>
1344 <dd> This parameter is used in
1345 conjuction with the selection of "frontier" as partition method. This
1346 determines the threshold at which a new MDD variable is created in
1347 the partition.
1348 </dl>
1349
1350 Image computation makes use of following settings:
1351
1352 <dl>
1353 <dt><b>image_method</b>
1354 <dd> The "image_method" parameter is used to control the image method used
1355 in various symbolic analysis techniques. Currently, two image methods are
1356 implemented. Use "set image_method &lt;method&gt;" to choose the appropriate
1357 method.
1358
1359 <dl>
1360 <dt><b>monolithic</b>
1361 <dd> This is the most naive approach possible. However, this method is not
1362 suitable for circuits with more than 20 latches.
1363
1364 <dt><b>tfm</b>
1365 <dd> This is the pure transition function method. This method is supposed
1366 not to be used in general fixpoint computations. Approximate traversal is
1367 an application of this method. Basically this method is made as a part of
1368 hybrid method. For more detailed options, see the help of
1369 print_tfm_options command.
1370
1371 <dt><b>hybrid</b>
1372 <dd> This is a hybrid method combining transition relation and function
1373 methods. Transition relation method is based on conjunction of partitioned
1374 transition relation, whereas transition function method is based on
1375 splitting on an input or output variable recursively. The hybrid method
1376 choose either splitting or conjunction at each recursion dynamically using
1377 the dependence matrix. For details, refer to the paper "To split or to
1378 Conjoin: The Question in Image Computation" by In-Ho Moon, James Kukula,
1379 Kavita Ravi, and Fabio Somenzi, DAC'00. Also for more detailed options,
1380 see the help of print_hybrid_options command.
1381
1382 <dt><b>iwls95</b>
1383 <dd> This technique is based on the early variable quantification and
1384 related heuristics of Ranjan, et al. "Efficient BDD Algorithms for FSM
1385 Synthesis and Verification", IWLS 1995. First, from the given multivalued
1386 functions, bit level relations are created. These relations are then
1387 clustered based on the value of threshold value controlled by
1388 <b>image_cluster_size</b> parameter. Next the relations are ordered for
1389 early variable quantification. This ordering is controlled by the
1390 parameters <b>image_W1, image_W2, image_W3,</b> and <b>image_W4</b>.
1391
1392 <dt><b>mlp</b>
1393 <dd> This technique is based on minimizing the variable lifetime
1394 in the conjunctions of the partitioned transition relation. The
1395 method is called MLP (Minimal Lifetime Permutation). For details,
1396 refer to the paper "Border-Block Triangular Form and Conjunction Schedule
1397 in Image Computation" by In-Ho Moon, Gary Hachtel, and Fabio Somenzi,
1398 FMCAD'00. Also for more detailed options, see the help of
1399 print_mlp_options command.
1400 </dl>
1401
1402
1403 <dt><b>image_farside_method</b>
1404 <dd> This parameter is used in conjunction with the selection of
1405 <b>iwls95</b>, <b>mlp</b>, or <b>linear</b> as the
1406 <b>image_method</b>. When the value is 1, the compositional far
1407 side image computation approach is enabled; when the value is 0,
1408 this feature is disabled (default).
1409
1410 <dt><b>image_cluster_size</b>
1411 <dd> This parameter is used in conjunction with the selection of
1412 <b>iwls95</b> as the <b>image_method</b>. The value of this parameter is
1413 used as threshold value for creating clusters. The default value of this
1414 parameter is 5000 which has been empirically proved to be an optimal value.
1415
1416 <dt><b>image_W1, image_W2, image_W3, image_W4</b>
1417 <dd> These parameters are used in conjunction with the selection of
1418 <b>iwls95</b> as the <b>image_method</b>. They control the weights
1419 associated with various factors in ordering the clusters. The default values
1420 are 6, 1, 1, and 2 respectively. For a detailed description of these
1421 parameters, please refer to the paper in IWLS'95 proceedings.
1422
1423 <dt><b>image_verbosity</b>
1424 <dd> Sets the verbosity mode (0 minimum to 4 maximum), for the image method
1425 <b>iwls95</b>.<p>
1426
1427 <dt>image_minimize_method &lt;method&gt;
1428 <dd> Sets a minimization method to minimize the transition relation or an
1429 image/preimage computaion with a set of dont-care states. <p>
1430 Methods:
1431 <code> 0 </code>: restrict (default). <p>
1432 <code> 1 </code>: constrain <p>
1433 <code> 2 </code>: compact (currently supported by only CUDD) <p>
1434 <code> 3 </code>: squeeze (currently supported by only CUDD) <p>
1435
1436 <dt>scc_method &lt;method&gt;
1437 <dd> Sets the symbolic method to enumerate strongly connected components
1438 (SCCs). Symbolic SCC enumeration is the core computation in LTL and
1439 fair-CTL model checking.
1440 <p> Methods: <code> lockstep </code>: the O(nlogn) time LockStep
1441 algorithm (default).
1442 <p> Methods: <code> linearstep </code>: the linear time symbolic
1443 algorithm (default).
1444
1445 </dl> ]
1446
1447 SideEffects []
1448
1449 SeeAlso [unset]
1450
1451******************************************************************************/
1452static int
1453CommandSetVariable(
1454 Hrc_Manager_t ** hmgr,
1455 int argc,
1456 char ** argv)
1457{
1458 char *flag_value, *key, *value;
1459 avl_generator *gen;
1460 int c;
1461
1462 util_getopt_reset();
1463 while ((c = util_getopt(argc, argv, "h")) != EOF) {
1464 switch(c) {
1465 case 'h':
1466 goto usage;
1467 default:
1468 goto usage;
1469 }
1470 }
1471 if (argc == 0 || argc > 3) {
1472 goto usage ;
1473 }
1474 else if (argc == 1) {
1475 avl_foreach_item(cmdFlagTable, gen, AVL_FORWARD, &key, &value) {
1476 (void) fprintf(vis_stdout, "%s\t%s\n", key, value);
1477 }
1478 return 0;
1479 }
1480 else {
1481 key = argv[1];
1482 if (avl_delete(cmdFlagTable, &key, &value)) {
1483 FREE(key);
1484 FREE(value);
1485 }
1486
1487 flag_value = argc == 2 ? util_strsav("") : util_strsav(argv[2]);
1488
1489 (void) avl_insert(cmdFlagTable, util_strsav(argv[1]), flag_value);
1490
1491 if (strcmp(argv[1], "vis_stdout") == 0) {
1492 if (vis_stdout != stdout) {
1493 (void) fclose(vis_stdout);
1494 }
1495 if (strcmp(flag_value, "") == 0) {
1496 flag_value = "-";
1497 }
1498 vis_stdout = Cmd_FileOpen(flag_value, "w", NIL(char *), 0);
1499 if (vis_stdout == NULL) {
1500 vis_stdout = stdout;
1501 }
1502#if HAVE_SETVBUF
1503 setvbuf(vis_stdout, (char *)NULL, _IOLBF, 0);
1504#endif
1505 }
1506 if (strcmp(argv[1], "vis_stderr") == 0) {
1507 if (vis_stderr != stderr) {
1508 (void) fclose(vis_stderr);
1509 }
1510 if (strcmp(flag_value, "") == 0) {
1511 flag_value = "-";
1512 }
1513 vis_stderr = Cmd_FileOpen(flag_value, "w", NIL(char *), 0);
1514 if (vis_stderr == NULL) {
1515 vis_stderr = stderr;
1516 }
1517#if HAVE_SETVBUF
1518 setvbuf(vis_stderr, (char *)NULL, _IOLBF, 0);
1519#endif
1520 }
1521 if (strcmp(argv[1], "history") == 0) {
1522 if (vis_historyFile != NIL(FILE)) {
1523 (void) fclose(vis_historyFile);
1524 }
1525 if (strcmp(flag_value, "") == 0) {
1526 vis_historyFile = NIL(FILE);
1527 }
1528 else {
1529 vis_historyFile = Cmd_FileOpen(flag_value, "w", NIL(char *), 0);
1530 if (vis_historyFile == NULL) {
1531 vis_historyFile = NIL(FILE);
1532 }
1533 }
1534 }
1535 return 0;
1536 }
1537
1538 usage:
1539 (void) printf("usage: set [-h] [name] [value]\n");
1540 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
1541 return 1;
1542
1543}
1544
1545
1546/**Function********************************************************************
1547
1548 Synopsis [Implements the unset command.]
1549
1550 CommandName [unset]
1551
1552 CommandSynopsis [unset an environment variable]
1553
1554 CommandArguments [\[-h\] &lt;variables&gt;]
1555
1556 CommandDescription [ A variable environment is maintained by the command
1557 interpreter.
1558 The "set" command sets a variable to a particular value, and the
1559 "unset" command removes the definition of a variable. <p>
1560 Command options:<p>
1561 </dl>
1562 <dl><dt> -h
1563 <dd> Print the command usage.
1564 </dl>
1565 <dl><dt> &lt;variables&gt;
1566 <dd> Variables to be unset
1567 </dl>
1568 ]
1569
1570 SideEffects []
1571
1572 SeeAlso [set]
1573
1574******************************************************************************/
1575static int
1576CommandUnsetVariable(
1577 Hrc_Manager_t ** hmgr,
1578 int argc,
1579 char ** argv)
1580{
1581 int i;
1582 char *key, *value;
1583 int c;
1584
1585 util_getopt_reset();
1586 while ((c = util_getopt(argc, argv, "h")) != EOF) {
1587 switch(c) {
1588 case 'h':
1589 goto usage;
1590 default:
1591 goto usage;
1592 }
1593 }
1594
1595 if (argc < 2) {
1596 goto usage;
1597 }
1598
1599 for(i = 1; i < argc; i++) {
1600 key = argv[i];
1601 if (avl_delete(cmdFlagTable, &key, &value)) {
1602 FREE(key);
1603 FREE(value);
1604 }
1605 }
1606 return 0;
1607
1608
1609 usage:
1610 (void) fprintf(vis_stderr, "usage: unset [-h] variables \n");
1611 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
1612 return 1;
1613}
1614
1615/**Function********************************************************************
1616
1617 Synopsis [Implements the help command.]
1618
1619 CommandName [help]
1620
1621 CommandSynopsis [provide on-line information on commands]
1622
1623 CommandArguments [\[-a\] \[-h\] \[&lt;command&gt;\]]
1624
1625 CommandDescription [Given no arguments, "help" prints a list of all commands
1626 known to the command interpreter.
1627 If a command name is given, detailed information for that command will be
1628 provided.<p>
1629
1630 Command options:<p>
1631 <dl><dt> -a
1632 <dd> Provides a list of all internal commands, which by convention begin with an underscore.
1633 </dl>
1634 <dl><dt> -h
1635 <dd> Print the command usage.
1636 </dl>]
1637
1638 SideEffects []
1639
1640******************************************************************************/
1641static int
1642CommandHelp(
1643 Hrc_Manager_t ** hmgr,
1644 int argc,
1645 char ** argv)
1646{
1647 int c, i, all;
1648 char *key;
1649 avl_generator *gen;
1650 char buffer[1024];
1651 char *command;
1652 char *lib_name;
1653#if HAVE_GETENV
1654 char *pager;
1655#endif
1656
1657
1658 util_getopt_reset();
1659 all = 0;
1660 while ((c = util_getopt(argc, argv, "ah")) != EOF) {
1661 switch(c) {
1662 case 'a':
1663 all = 1;
1664 break;
1665 case 'h':
1666 goto usage;
1667 default:
1668 goto usage;
1669 }
1670 }
1671
1672 if (argc - util_optind == 0) {
1673 fprintf(vis_stderr,"List of commands:\n");
1674 i = 0;
1675 avl_foreach_item(cmdCommandTable, gen, AVL_FORWARD, &key, NIL(char *)) {
1676 if ((key[0] == '_') == all) {
1677 (void) fprintf(vis_stdout, "%-26s", key);
1678 if ((++i%3) == 0) {
1679 (void) fprintf(vis_stdout, "\n");
1680 }
1681 }
1682 }
1683 if ((i%3) != 0) {
1684 (void) fprintf(vis_stdout, "\n");
1685 }
1686 }
1687 else if (argc - util_optind == 1) {
1688 command = command_alias_help(argv[util_optind]);
1689 lib_name = Vm_VisObtainLibrary();
1690#if HAVE_GETENV
1691 pager = getenv("PAGER");
1692 if (pager != NULL) {
1693 (void) sprintf(buffer, "%s %s/help/%sCmd.txt", pager, lib_name, command);
1694 } else {
1695 (void) sprintf(buffer, "more %s/help/%sCmd.txt", lib_name, command);
1696 }
1697#else
1698 (void) sprintf(buffer, "more %s/help/%sCmd.txt", lib_name, command);
1699#endif
1700 (void) system(buffer);
1701 FREE(lib_name);
1702 }
1703 else {
1704 goto usage;
1705 }
1706
1707 return 0;
1708
1709usage:
1710 (void) fprintf(vis_stderr, "usage: help [-a] [-h] [command]\n");
1711 (void) fprintf(vis_stderr, " -a \t\tprint help for all commands\n");
1712 (void) fprintf(vis_stderr, " -h \t\tprint the command usage\n");
1713
1714 return 1;
1715}
1716
1717#if 0
1718Change "/*!*Function" to "/**Function" when reactivate command
1719/*!*Function********************************************************************
1720
1721 Synopsis [Implements the undo command.]
1722
1723 CommandName [undo]
1724
1725 CommandSynopsis [undo the result of the last command which changed the network]
1726
1727 CommandDescription [ A simple 1-level undo is supported.
1728 It reverts the network to its state before the last command which
1729 changed the network. Note that interrupting a command (with ^C)
1730 which changes the network uses up the one level of undo.<p> ]
1731
1732 SideEffects []
1733
1734******************************************************************************/
1735static int
1736CommandUndo(
1737 Hrc_Manager_t ** hmgr,
1738 int argc,
1739 char ** argv)
1740{
1741 if (argc != 1) {
1742 (void) fprintf(vis_stderr, "usage: undo\n");
1743 return 1;
1744 }
1745
1746 (void) fprintf(vis_stderr, "** cmd error: undo: not yet implemented\n");
1747 return 1;
1748
1749#if 0
1750
1751 /*
1752 * FIX (Tom): can't enable "undo" until network_dup and hmgr_dup exist.
1753 */
1754 if (cmdBackupHmgr == NIL(Hrc_Manager_t)) {
1755 (void) fprintf(vis_stderr, "undo: no hmgr currently saved\n");
1756 return 1;
1757 }
1758 else {
1759
1760 /* Swap the current and backup. */
1761 Hrc_Manager_t *temp = *hmgr;
1762 *hmgr = cmdBackupHmgr;
1763 cmdBackupHmgr = temp;
1764 return 0;
1765 }
1766#endif
1767}
1768#endif
1769
1770
1771
1772/**Function********************************************************************
1773
1774 Synopsis [Implements the source command.]
1775
1776 CommandName [source]
1777
1778 CommandSynopsis [execute commands from a file]
1779
1780 CommandArguments [\[-h\] \[-p\] \[-s\] \[-x\] &lt;file&gt; \[&lt;args&gt;\]]
1781
1782 CommandDescription [Reads and executes commands from a file.<p>
1783 Command options:<p>
1784 <dl><dt> -h
1785 <dd> Print the command usage.
1786 </dl>
1787 <dl><dt> -p
1788 <dd> Print a prompt before reading each command.
1789 </dl>
1790 <dl><dt> -s
1791 <dd> Silently
1792 ignore an attempt to execute commands from a nonexistent file.
1793 </dl>
1794 <dl><dt> -x
1795 <dd> Echo each command before it is executed.
1796 </dl>
1797 <dl><dt> &lt;file&gt;
1798 <dd> File name
1799 </dl>
1800
1801 Arguments on the command line after the filename are remembered but not
1802 evaluated. Commands in the script file can then refer to these arguments
1803 using the history substitution mechanism.<p>
1804
1805 EXAMPLE:<p>
1806
1807 Contents of test.scr:<p>
1808
1809 <pre>
1810 read_blif_mv %:2
1811 init_verify
1812 simulate -n 10
1813 </pre>
1814
1815 Typing "source test.scr lion.mv" on the command line will execute the
1816 sequence<p>
1817
1818 <pre>
1819 read_blif_mv lion.mv
1820 init_verify
1821 simulate -n 10
1822 </pre>
1823
1824 (In this case <code>%:0</code> gets "source", <code>%:1</code> gets
1825 "test.scr", and <code>%:2</code> gets "lion.mv".)
1826 If you type "alias st source test.scr" and then type "st lion.blif bozo",
1827 you will execute<p>
1828
1829 <pre>
1830 read_blif_mv bozo
1831 init_verify
1832 simulate -n 10
1833 </pre>
1834
1835 because "bozo" was the second argument on the last command line typed. In
1836 other words, command substitution in a script file depends on how the script
1837 file was invoked. Switches passed to a command are also counted as
1838 positional parameters. Therefore, if you type "st -x lion.mv bozo",
1839 you will execute
1840
1841 <pre>
1842 read_blif_mv lion.mv
1843 init_verify
1844 simulate -n 10
1845 </pre>
1846
1847 To pass the "-x" switch (or any other switch) to "source" when the
1848 script uses positional parameters, you can define an alias. For
1849 instance, "alias srcx source -x".<p>
1850
1851
1852 ]
1853
1854 SideEffects [required]
1855
1856 SeeAlso [history]
1857
1858******************************************************************************/
1859static int
1860CommandSource(
1861 Hrc_Manager_t ** hmgr,
1862 int argc,
1863 char ** argv)
1864{
1865 int c, echo, prompt, silent, interactive, quit_count, lp_count;
1866 int status = 0; /* initialize so that lint doesn't complain */
1867 int lp_file_index, did_subst;
1868 char *prompt_string, *real_filename, line[MAX_STR], *command;
1869 FILE *fp;
1870
1871 interactive = silent = prompt = echo = 0;
1872
1873 util_getopt_reset();
1874 while ((c = util_getopt(argc, argv, "hipsx")) != EOF) {
1875 switch(c) {
1876 case 'h':
1877 goto usage ;
1878 case 'i': /* a hack to distinguish EOF from stdin */
1879 interactive = 1;
1880 break;
1881 case 'p':
1882 prompt = 1;
1883 break;
1884 case 's':
1885 silent = 1;
1886 break;
1887 case 'x':
1888 echo = 1;
1889 break;
1890 default:
1891 goto usage;
1892 }
1893 }
1894
1895 /* added to avoid core-dumping when no script file is specified */
1896 if (argc == util_optind){
1897 goto usage;
1898 }
1899
1900 lp_file_index = util_optind;
1901 lp_count = 0;
1902
1903 /*
1904 * FIX (Tom, 5/7/95): I'm not sure what the purpose of this outer do loop
1905 * is. In particular, lp_file_index is never modified in the loop, so it
1906 * looks it would just read the same file over again. Also, SIS had
1907 * lp_count initialized to -1, and hence, any file sourced by SIS (if -l or
1908 * -t options on "source" were used in SIS) would actually be executed
1909 * twice.
1910 */
1911 do {
1912 lp_count ++; /* increment the loop counter */
1913
1914 fp = Cmd_FileOpen(argv[lp_file_index], "r", &real_filename, silent);
1915 if (fp == NULL) {
1916 FREE(real_filename);
1917 return ! silent; /* error return if not silent */
1918 }
1919
1920 quit_count = 0;
1921 do {
1922 if (prompt) {
1923 prompt_string = Cmd_FlagReadByName("prompt");
1924 if (prompt_string == NIL(char)) {
1925 prompt_string = "vis> ";
1926 }
1927
1928 }
1929 else {
1930 prompt_string = NIL(char);
1931 }
1932
1933 /* clear errors -- e.g., EOF reached from stdin */
1934 clearerr(fp);
1935
1936 /* read another command line */
1937 if (CmdFgetsFilec(line, MAX_STR, fp, prompt_string) == NULL) {
1938 if (interactive) {
1939 if (quit_count++ < 5) {
1940 (void) fprintf(vis_stderr, "\nUse \"quit\" to leave VIS.\n");
1941 continue;
1942 }
1943 status = -1; /* fake a 'quit' */
1944 }
1945 else {
1946 status = 0; /* successful end of 'source' ; loop? */
1947 }
1948 break;
1949 }
1950 quit_count = 0;
1951
1952 if (echo) {
1953 (void) fprintf(vis_stdout, "%s", line);
1954 }
1955 command = CmdHistorySubstitution(line, &did_subst);
1956 if (command == NIL(char)) {
1957 status = 1;
1958 break;
1959 }
1960 if (did_subst) {
1961 if (interactive) {
1962 (void) fprintf(stdout, "%s\n", command);
1963 }
1964 }
1965 if (command != line) {
1966 (void) strcpy(line, command);
1967 }
1968 if (interactive && *line != '\0') {
1969 array_insert_last(char *, vm_commandHistoryArray, util_strsav(line));
1970 if (vis_historyFile != NIL(FILE)) {
1971 (void) fprintf(vis_historyFile, "%s\n", line);
1972 (void) fflush(vis_historyFile);
1973 }
1974 }
1975
1976 status = Cmd_CommandExecute(hmgr, line);
1977 } while (status == 0);
1978
1979 if (fp != stdin) {
1980 if (status > 0) {
1981 (void) fprintf(vis_stderr, "** cmd error: aborting 'source %s'\n", real_filename);
1982 }
1983 (void) fclose(fp);
1984 }
1985 FREE(real_filename);
1986
1987 } while ((status == 0) && (lp_count <= 0));
1988
1989 return status;
1990
1991usage:
1992 (void) fprintf(vis_stderr, "source [-h] [-p] [-s] [-x] file_name\n");
1993 (void) fprintf(vis_stderr, "\t-h print the command usage\n");
1994 (void) fprintf(vis_stderr, "\t-p supply prompt before reading each line\n");
1995 (void) fprintf(vis_stderr, "\t-s silently ignore nonexistent file\n");
1996 (void) fprintf(vis_stderr, "\t-x echo each line as it is executed\n");
1997 return 1;
1998}
1999
2000/**Function********************************************************************
2001
2002 Synopsis [required]
2003
2004 Description [optional]
2005
2006 SideEffects [required]
2007
2008 SeeAlso [optional]
2009
2010******************************************************************************/
2011static void
2012print_alias(
2013 char * value)
2014{
2015 int i;
2016 CmdAliasDescr_t *alias;
2017
2018 alias = (CmdAliasDescr_t *) value;
2019 (void) fprintf(vis_stdout, "%s\t", alias->name);
2020 for(i = 0; i < alias->argc; i++) {
2021 (void) fprintf(vis_stdout, " %s", alias->argv[i]);
2022 }
2023 (void) fprintf(vis_stdout, "\n");
2024}
2025
2026
2027/**Function********************************************************************
2028
2029 Synopsis [required]
2030
2031 Description [optional]
2032
2033 SideEffects [required]
2034
2035 SeeAlso [optional]
2036
2037******************************************************************************/
2038static char *
2039command_alias_help(
2040 char * command)
2041{
2042 char *value;
2043 CmdAliasDescr_t *alias;
2044
2045 if (!avl_lookup(cmdAliasTable, command, &value)) {
2046 return command;
2047 }
2048 alias = (CmdAliasDescr_t *) value;
2049 return alias->argv[0];
2050}
2051
2052/**Function********************************************************************
2053
2054 Synopsis [Function to flush vis_stdout and vis_stderr.]
2055
2056 Description [This function is the signal handler for the SIGUSR1
2057 signal. Whenever that signal is received, this function is executed and the
2058 output channels of VIS are flushed.]
2059
2060 SideEffects []
2061
2062 SeeAlso [Cmd_Init]
2063
2064******************************************************************************/
2065static void
2066FlushBuffers(
2067 int sigtype)
2068{
2069 fflush(vis_stdout);
2070 fflush(vis_stderr);
2071
2072 /* Reprogram again the handler */
2073#ifdef SIGUSR1
2074 (void) signal(SIGUSR1, FlushBuffers);
2075#endif
2076} /* End of FlushBuffers */
Note: See TracBrowser for help on using the repository browser.