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

Last change on this file was 14, checked in by cecile, 13 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.