home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / sources / 3107 < prev    next >
Encoding:
Text File  |  1993-01-28  |  56.4 KB  |  1,999 lines

  1. Path: sparky!uunet!ferkel.ucsb.edu!taco!rock!stanford.edu!ames!haven.umd.edu!darwin.sura.net!ukma!cs.widener.edu!dsinc!ub!galileo.cc.rochester.edu!ee.rochester.edu!rbc!al
  2. From: al@rbc.uucp (Al Davis)
  3. Newsgroups: alt.sources
  4. Subject: ACS  circuit simulator  part 16/20
  5. Message-ID: <1993Jan27.040952.11870@rbc.uucp>
  6. Date: 27 Jan 93 04:09:52 GMT
  7. Sender: al@rbc.uucp (Al Davis)
  8. Organization: Huh?
  9. Lines: 1988
  10.  
  11. #! /bin/sh
  12. # This is a shell archive, meaning:
  13. # 1. Remove everything above the #! /bin/sh line.
  14. # 2. Save the resulting text in a file.
  15. # 3. Execute the file with /bin/sh (not csh) to create the files:
  16. #    src/help.c
  17. #    src/inorder.c
  18. #    src/insert.c
  19. #    src/ipow.c
  20. #    src/isfloat.c
  21. #    src/isterm.c
  22. #    src/itos.c
  23. #    src/line.c
  24. #    src/list.c
  25. #    src/main.c
  26. #    src/match.c
  27. #    src/modify.c
  28. #    src/network.c
  29. #    src/nodes.c
  30. #    src/nodeset.c
  31. #    src/options.c
  32. #    src/outset.c
  33. #    src/outtext.c
  34. # This archive created: Tue Jan 26 22:51:06 1993
  35. export PATH; PATH=/bin:$PATH
  36. if test -f 'src/help.c'
  37. then
  38.     echo shar: will not over-write existing file "'src/help.c'"
  39. else
  40. cat << \SHAR_EOF > 'src/help.c'
  41. /* help     10/08/91
  42.  * Copyright 1983-1992   Albert Davis
  43.  * Accesses a help file to provide on-line documentation.
  44.  * Will follow the executables path to find it.
  45.  */
  46. #include "ecah.h"
  47. #include "error.h"
  48. #include "io.h"
  49. #include "declare.h"
  50. /*--------------------------------------------------------------------------*/
  51.     void    cmd_help(const char*,int*);
  52. /*--------------------------------------------------------------------------*/
  53. extern const struct ioctrl io;
  54. extern const char e_int[];
  55. /*--------------------------------------------------------------------------*/
  56. void cmd_help(cmd,cnt)
  57. const char *cmd;
  58. int  *cnt;
  59. {
  60.  static FILE *hfn;
  61.  char buffer[BUFLEN];
  62.  char *name;
  63.  
  64.  if (hfn)
  65.     (void)fclose(hfn);
  66.  name = findfile(HELPFILE, HELPPATH, R_OK);
  67.  if (!name)
  68.     error(bERROR, "Help not available\n");
  69.  hfn = fopen(name, "r");
  70.  if (!hfn)
  71.     error(bERROR, e_int, "help");
  72.  if (cmd[*cnt])
  73.     do {
  74.        if (!fgets(buffer, BUFLEN, hfn)) {
  75.       error(bWARNING, "No help on %s\n", &cmd[*cnt]);
  76.       break;
  77.        }
  78.     } while (buffer[0]!=':'  ||  !pmatch(cmd,cnt,&buffer[1]));
  79.  
  80.  for (;;) {
  81.     if (!fgets(buffer,BUFLEN,hfn))
  82.        break;
  83.     if (buffer[0]==':')
  84.        break;
  85.     mputs(buffer,io.mstderr);
  86.  }
  87.  (void)fclose(hfn);
  88.  hfn = (FILE*)NULL;
  89. }
  90. /*--------------------------------------------------------------------------*/
  91. /*--------------------------------------------------------------------------*/
  92. SHAR_EOF
  93. fi # end of overwriting check
  94. if test -f 'src/inorder.c'
  95. then
  96.     echo shar: will not over-write existing file "'src/inorder.c'"
  97. else
  98. cat << \SHAR_EOF > 'src/inorder.c'
  99. /* inorder  03/02/84-2
  100.  * Copyright 1983-1992   Albert Davis
  101.  * 3 way test
  102.  * returns true if the middle argument is between the outer 2
  103.  * else false
  104.  * uses "double" args
  105.  */
  106.  
  107. int inorder(arg1,arg2,arg3)
  108. double arg1,arg2,arg3;
  109. {
  110.  return ( (arg1<=arg2 && arg2<=arg3) || (arg1>=arg2 && arg2>=arg3) );
  111. }
  112. SHAR_EOF
  113. fi # end of overwriting check
  114. if test -f 'src/insert.c'
  115. then
  116.     echo shar: will not over-write existing file "'src/insert.c'"
  117. else
  118. cat << \SHAR_EOF > 'src/insert.c'
  119. /* insert  12/29/92
  120.  * Copyright 1983-1992   Albert Davis
  121.  * insert command
  122.  * insert new nodes
  123.  */
  124. #include "ecah.h"
  125. #include "branch.h"
  126. #include "error.h"
  127. #include "mode.h"
  128. #include "status.h"
  129. #include "declare.h"
  130. /*--------------------------------------------------------------------------*/
  131.     void    cmd_insert(const char*, int*);
  132. /*--------------------------------------------------------------------------*/
  133. extern const struct status stats;
  134. /*--------------------------------------------------------------------------*/
  135. void cmd_insert(cmd,cnt)
  136. const char *cmd;        /* pointer to command buffer        */
  137. int  *cnt;            /* pointer to position counter        */
  138. {
  139.  int nod;        /* first node number to insert            */
  140.  int ncnt;        /* how many nodes to insert            */
  141.  branch_t *brh;        /* branch pointer, for loop            */
  142.  branch_t *stop;    /* stop loop                    */
  143.  
  144.  dealloc(YES);
  145.  nod = ctoi(cmd,cnt);            /* get args..            */
  146.  if (nod <= 0)
  147.     error(bERROR, "insert which node?\n");
  148.  if (nod > stats.total_nodes)
  149.     error(bERROR, "%u nodes\n", stats.total_nodes);
  150.  
  151.  ncnt = ctoi(cmd,cnt);
  152.  if (ncnt <= 0)
  153.     ncnt = 1;
  154.  
  155.  stop = brh = firstbranch_dev();
  156.  do {
  157.     int ii;
  158.     for (ii = 0;  brh->n[ii].e != INVALIDNODE;  ii++){
  159.        if (brh->n[ii].e >= nod)        /* move them up            */
  160.       brh->n[ii].e += ncnt;
  161.     }
  162.  } while (brh = nextbranch_dev(brh),  brh != stop);
  163. }
  164. /*--------------------------------------------------------------------------*/
  165. /*--------------------------------------------------------------------------*/
  166. SHAR_EOF
  167. fi # end of overwriting check
  168. if test -f 'src/ipow.c'
  169. then
  170.     echo shar: will not over-write existing file "'src/ipow.c'"
  171. else
  172. cat << \SHAR_EOF > 'src/ipow.c'
  173. /* ipow     04/02/92
  174.  * Copyright 1983-1992   Albert Davis
  175.  * like pow() (std function) but y rounded to integer
  176.  * done by repeated multiplication
  177.  * returns zero if x
  178.  */            /* z = pow(x,y) */
  179. #include "ecah.h"
  180. #include "declare.h"
  181. /*--------------------------------------------------------------------------*/
  182.     double ipow(double,int);
  183. /*--------------------------------------------------------------------------*/
  184. /*--------------------------------------------------------------------------*/
  185. double ipow(x,y)
  186. double x;
  187. int y;
  188. {
  189.  struct exception z;
  190.  
  191.  if (y < 0){
  192.     if (x != 0.){
  193.        x = 1/x;
  194.        y = -y;
  195.     }else{
  196.        errno  = EDOM;
  197.        z.type = DOMAIN;
  198.        z.name = "ipow";
  199.        z.arg1 = x;
  200.        z.arg2 = (double)y;
  201.        z.retval = HUGE;
  202.        if (!matherr(&z)){
  203.       fputs("ipow: DOMAIN error\n",stderr);
  204.       errno = EDOM;
  205.        }
  206.        return z.retval;
  207.     }
  208.  }
  209.  
  210.  for ( z.retval=1.;  y>0;  y-- )
  211.     z.retval *= x;
  212.  
  213.  return z.retval;
  214. }
  215. /*--------------------------------------------------------------------------*/
  216. /*--------------------------------------------------------------------------*/
  217. SHAR_EOF
  218. fi # end of overwriting check
  219. if test -f 'src/isfloat.c'
  220. then
  221.     echo shar: will not over-write existing file "'src/isfloat.c'"
  222. else
  223. cat << \SHAR_EOF > 'src/isfloat.c'
  224. /* isfloat  03/13/84-3  04/10/90
  225.  * Copyright 1983-1992   Albert Davis
  226.  * return 1 if any character that a floating number string can start with
  227.  */
  228. #include "ecah.h"
  229. #include "declare.h"
  230.  
  231. int isfloat(chr)
  232. int chr;
  233. {
  234.  return ( isdigit(chr) || chr=='.' || chr=='-' || chr=='+' );
  235. }
  236. SHAR_EOF
  237. fi # end of overwriting check
  238. if test -f 'src/isterm.c'
  239. then
  240.     echo shar: will not over-write existing file "'src/isterm.c'"
  241. else
  242. cat << \SHAR_EOF > 'src/isterm.c'
  243. /* isterm   12/06/90
  244.  * Copyright 1983-1992   Albert Davis
  245.  * return 1 if terminator (space, comma, =, or null)
  246.  * else 0
  247.  */
  248. #include "ecah.h"
  249. #include "declare.h"
  250.  
  251. int isterm(chr)
  252. int chr;
  253. {
  254.  return (chr=='\0' || isspace(chr) || strchr(",=()[]",chr));
  255. }
  256. SHAR_EOF
  257. fi # end of overwriting check
  258. if test -f 'src/itos.c'
  259. then
  260.     echo shar: will not over-write existing file "'src/itos.c'"
  261. else
  262. cat << \SHAR_EOF > 'src/itos.c'
  263. /* itos     04/02/92
  264.  * Copyright 1983-1992   Albert Davis
  265.  * Integer to string (signed).
  266.  * num = number to convert.
  267.  * str = string to put it in.  Must be big enough, or else!!
  268.  *        Must have length at least len+1.
  269.  * len = number of significant digits.
  270.  *     If minus, left justify, else right.
  271.  * fmt = format : 0      = normal : sign if minus.
  272.  *          FMTSIGN = always sign.
  273.  */
  274. #include "ecah.h"
  275. #include "formats.h"
  276. #include "declare.h"
  277. /*--------------------------------------------------------------------------*/
  278.     char    *itos(int,char*,int,int);
  279. /*--------------------------------------------------------------------------*/
  280. char *itos( num, str, len, fmt )
  281. int num, len, fmt;
  282. char *str;
  283. {
  284.  int ii;
  285.  char sign;
  286.  
  287.  if (num < 0){
  288.     sign = '-';
  289.     num = -num;
  290.  }else if (fmt & FMTSIGN){
  291.     sign = '+';
  292.  }else{
  293.     sign = ' ';
  294.  }
  295.  
  296.  (void)utos( (unsigned)num, &str[1], len );
  297.  for ( ii=1; str[ii]==' '; ++ii )
  298.     ;
  299.  str[ii-1] = sign;
  300.  return str;
  301. }
  302. /*--------------------------------------------------------------------------*/
  303. /*--------------------------------------------------------------------------*/
  304. SHAR_EOF
  305. fi # end of overwriting check
  306. if test -f 'src/line.c'
  307. then
  308.     echo shar: will not over-write existing file "'src/line.c'"
  309. else
  310. cat << \SHAR_EOF > 'src/line.c'
  311. /* line     04/02/92
  312.  * from C-Ware, and modified to be user installable?
  313.  */
  314. #include "ecah.h"
  315. #include "pixelh.h"
  316. #include "declare.h"
  317. /*LINTLIBRARY*/
  318. /*--------------------------------------------------------------------------*/
  319.     void initgraph(struct graph *);
  320.     void stext(int,int,const char*,int);
  321.     void setpixel(int,int,int);
  322.     void box(int,int,int,int,int);
  323.     void line(int,int,int,int,int);
  324. static    void badpixel(int,int,int);
  325. static    void badbox(int,int,int,int,int);
  326. static    void badline(int,int,int,int,int);
  327. /*--------------------------------------------------------------------------*/
  328. #define sign(x)        ((x < 0) ? 1 : 0)
  329.  
  330. static void (*d_setpix)(int,int,int);        /* setpixel function */
  331. static void (*d_line)(int,int,int,int,int);    /* line function */
  332. static void (*d_box)(int,int,int,int,int);    /* box function */
  333. static void (*d_text)(int,int,const char*,int);    /* text function */
  334. /*--------------------------------------------------------------------------*/
  335. void initgraph(d)
  336. struct graph *d;
  337. {
  338. if (d->spx || d->lin)
  339.     {
  340.     if (d->spx)
  341.     d_setpix = d->spx;
  342.     else
  343.     d_setpix = badpixel;
  344.  
  345.     if (d->lin)
  346.     d_line = d->lin;
  347.     else
  348.     d_line = badline;
  349.  
  350.     if (d->box)
  351.     d_box = d->box;
  352.     else
  353.     d_box = badbox;
  354.  
  355.     d_text = (d->txt) ;
  356.     }
  357. }
  358. /*--------------------------------------------------------------------------*/
  359. void stext(x,y,str,color)
  360. int x,y,color;
  361. const char *str;
  362. {
  363. (*d_text)(x,y,str,color);
  364. }
  365. /*--------------------------------------------------------------------------*/
  366. void setpixel(x,y,color)
  367. int x,y,color;
  368. {
  369. (*d_setpix)(x,y,color);
  370. }
  371. /*--------------------------------------------------------------------------*/
  372. void box( x1, y1, x2, y2, color )
  373. int x1, y1, x2, y2, color;
  374. {
  375. (*d_box)(x1,y1,x2,y2,color);
  376. }
  377. /*--------------------------------------------------------------------------*/
  378. void line( x1, y1, x2, y2, color )
  379. int x1, y1, x2, y2, color;
  380. {
  381. (*d_line)(x1,y1,x2,y2,color);
  382. }
  383. /*--------------------------------------------------------------------------*/
  384.  
  385. static void badpixel(x,y,color)
  386. int x, y, color;
  387. {
  388. line(x,y,x,y,color);
  389. }
  390. /*--------------------------------------------------------------------------*/
  391. static void badbox( x1, y1, x2, y2, color )
  392. int x1, y1, x2, y2, color;
  393. {
  394. line(x1,y1,x2,y1,color);
  395. line(x2,y1,x2,y2,color);
  396. line(x2,y2,x1,y2,color);
  397. line(x1,y2,x1,y1,color);
  398. }
  399. /*--------------------------------------------------------------------------*/
  400. static void badline( x1, y1, x2, y2, color )
  401. int x1, y1, x2, y2, color;
  402. {
  403. int x, y, dx, dy, adx, ady, d, d1, d2, step;
  404.  
  405. dx  = x2 - x1;
  406. adx = abs(dx);
  407. dy  = y2 - y1;
  408. ady = abs(dy);
  409.  
  410. if (adx == 0)            /* Vertical line */
  411.     {
  412.     y = min(y1, y2);
  413.     ady++;
  414.     while (ady--)
  415.     (*d_setpix)(x1, y++, color);
  416.     return;
  417.     }
  418.  
  419. if (ady == 0)            /* Horizontal line */
  420.     {
  421.     x = min(x1, x2);
  422.     adx++;
  423.     while (adx--)
  424.     (*d_setpix)(x++, y1, color);
  425.     return;
  426.     }
  427.  
  428. if (adx < ady)
  429.     {
  430.     d  = (adx << 1) - ady;
  431.     d1 = adx << 1;
  432.     d2 = (adx - ady) << 1;
  433.     (y1 < y2) ? (x = x1, y = y1) : (x = x2, y = y2);
  434.     step = ((sign(dx) == sign(dy)) ? 1 : -1);
  435.     (*d_setpix)(x, y, color);
  436.     while (ady--)
  437.     {
  438.     y++;
  439.     if (d < 0)
  440.         d += d1;
  441.     else
  442.         {
  443.         x += step;
  444.         d += d2;
  445.         }
  446.     (*d_setpix)(x, y, color);
  447.     }
  448.     }
  449. else
  450.     {
  451.     d  = (ady << 1) - adx;
  452.     d1 = ady << 1;
  453.     d2 = (ady - adx) << 1;
  454.     (x1 < x2) ? (x = x1, y = y1) : (x = x2, y = y2);
  455.     step = ((sign(dx) == sign(dy)) ? 1 : -1);
  456.     (*d_setpix)(x, y,color);
  457.     while (adx--)
  458.     {
  459.     x++;
  460.     if (d < 0)
  461.         d += d1;
  462.     else
  463.         {
  464.         y += step;
  465.         d += d2;
  466.         }
  467.     (*d_setpix)(x, y, color);
  468.     }
  469.     }
  470. }
  471. /*--------------------------------------------------------------------------*/
  472. /*--------------------------------------------------------------------------*/
  473. SHAR_EOF
  474. fi # end of overwriting check
  475. if test -f 'src/list.c'
  476. then
  477.     echo shar: will not over-write existing file "'src/list.c'"
  478. else
  479. cat << \SHAR_EOF > 'src/list.c'
  480. /* list,save  11/19/91
  481.  * Copyright 1983-1992   Albert Davis
  482.  * list and save commands.
  483.  * save is list with direction to file
  484.  */
  485. #include "ecah.h"
  486. #include "branch.h"
  487. #include "dev.h"
  488. #include "error.h"
  489. #include "io.h"
  490. #include "declare.h"
  491. /*--------------------------------------------------------------------------*/
  492.     void    cmd_list(const char*,int*);
  493. /*--------------------------------------------------------------------------*/
  494. extern const struct ioctrl io;
  495. extern const char head[];
  496. /*--------------------------------------------------------------------------*/
  497. void cmd_list(cmd,cnt)
  498. const char *cmd;
  499. int  *cnt;
  500. {
  501.  branch_t *brh;
  502.  
  503.  *cnt = 0;              /* back up to beginning of input line        */
  504.  (void)outset(cmd,cnt,(char*)NULL,"ckt"); /* is it list or save??        */
  505.                   /* (outset will re-eat words save or list)*/
  506.                   /* its purpose is to set up where to send */
  507.                   /* the stuff.                    */
  508.  
  509.  mprintf(io.where&~io.mstdout, "%s\n", head);
  510.  
  511.  if (!cmd[*cnt]){            /* no args: list all            */
  512.     branch_t *stop;
  513.     brh = firstbranch_all();
  514.     stop = lastbranch_all();
  515.     for (;;){
  516.        print_branch(brh, io.where, NO);
  517.        if (brh == stop)
  518.           break;
  519.        brh = nextbranch_all(brh);
  520.     };
  521.  }else{                    /* some args: be selective        */
  522.     int arg;
  523.     arg = *cnt;
  524.     brh = findbranch(cmd,cnt, firstbranch_all(), lastbranch_all());
  525.     if (!exists(brh)){
  526.        syntax(cmd,cnt,bERROR);
  527.     }
  528.  
  529.     if (cmd[*cnt] == '-'){        /* there is a dash:  a range        */
  530.        branch_t *stop;
  531.        (*cnt)++;
  532.        stop = findbranch(cmd,cnt, brh, lastbranch_all());
  533.        if (!exists(stop)){
  534.       syntax(cmd,cnt,bERROR);
  535.       stop = lastbranch_all();
  536.        }
  537.        for (;;){
  538.       print_branch(brh, io.where, NO);
  539.       if (brh == stop)
  540.          break;
  541.       brh = nextbranch_all(brh);
  542.        }
  543.     }else{                /* no dash: a list            */
  544.        int next;
  545.        do {                /* each arg                */
  546.       next = *cnt;
  547.       for (;;){            /* all that match this arg        */
  548.          print_branch(brh, io.where, YES);
  549.          if (brh == lastbranch_all())
  550.             break;
  551.          *cnt = arg;
  552.          brh = findbranch(cmd, cnt, nextbranch_all(brh), lastbranch_all());
  553.          if (!exists(brh))
  554.             break;
  555.       }
  556.        } while (*cnt = arg = next,
  557.          brh = findbranch(cmd, cnt, firstbranch_all(), lastbranch_all()),
  558.          exists(brh));
  559.     }
  560.  }
  561. }
  562. /*--------------------------------------------------------------------------*/
  563. /*--------------------------------------------------------------------------*/
  564. SHAR_EOF
  565. fi # end of overwriting check
  566. if test -f 'src/main.c'
  567. then
  568.     echo shar: will not over-write existing file "'src/main.c'"
  569. else
  570. cat << \SHAR_EOF > 'src/main.c'
  571. /* main    01/24/93
  572.  * Copyright 1983-1992   Albert Davis
  573.  * top level module
  574.  * it all starts here
  575.  */
  576. #include "ecah.h"
  577. #include "argparse.h"
  578. #include "error.h"
  579. #include "io.h"
  580. #include "mode.h"
  581. #include "options.h"
  582. #include "status.h"
  583. #include <signal.h>
  584. #include "declare.h"
  585. /*--------------------------------------------------------------------------*/
  586.     void    main(int,const char*[]);
  587. static    void    initialize_io(void);
  588. static    void    sign_on(void);
  589. static    void    read_startup_files(void);
  590. static    void    process_cmd_line(int,const char*[]);
  591. static    void    setup_traps(void);
  592. static    void    finish(void);
  593.     void    cmdproc(const char*);
  594. /*--------------------------------------------------------------------------*/
  595. extern       struct ioctrl io;
  596. extern const struct options opt;
  597.  
  598. extern const double zero;
  599. extern const char e_int[];
  600.  
  601. extern int inc_mode;
  602. extern int errorcount;
  603. extern int run_mode;
  604. extern int sim_mode;
  605. extern int sim_phase;
  606. extern FILE *stream[];        /* reverse of fileno() */
  607. extern jmp_buf envp;
  608. extern int cmdcount;
  609. /*--------------------------------------------------------------------------*/
  610. void main(argc,argv)
  611. int argc;
  612. const char *argv[];
  613. {
  614.  initialize();            /* machine dependent initialization    */
  615.  initialize_io();
  616.  sign_on();
  617.  if (setjmp(envp)){        
  618.     finish();            /* error clean up (from longjmp())    */
  619.  }else{
  620.     read_startup_files();
  621.     process_cmd_line(argc,argv);
  622.     setup_traps();
  623.  }  
  624.  for (;;){
  625.     char cmdbuf[BUFLEN];
  626.     cmdcount++;
  627.     (void)getcmd("-->", cmdbuf, BUFLEN);
  628.     run_mode = rEXECUTE;
  629.     cmdproc(cmdbuf);
  630.  }
  631. }
  632. /*--------------------------------------------------------------------------*/
  633. static void initialize_io()
  634. {
  635.  stream[fileno(stdin )] = stdin;
  636.  stream[fileno(stdout)] = stdout;
  637.  stream[fileno(stderr)] = stderr;
  638.  io.mstdout = io.mstderr = 1<<fileno(stdout);
  639. }
  640. /*--------------------------------------------------------------------------*/
  641. static void sign_on()
  642. {
  643.  mprintf(io.mstdout,"ACS (Al's Circuit Simulator) 0.05xc\n");
  644.  mprintf(io.mstdout,"Never trust any version less than 1.0\n");
  645.  mprintf(io.mstdout,"Copyright 1992, Albert Davis\n");
  646.  mprintf(io.mstdout,"ACS comes with ABSOLUTELY NO WARRANTY\n");
  647.  mprintf(io.mstdout,"This is free software, and you are welcome\n");
  648.  mprintf(io.mstdout,"to redistribute it under certain conditions.\n");
  649.  mprintf(io.mstdout,"See the file \"COPYING\" for details\n");
  650. }
  651. /*--------------------------------------------------------------------------*/
  652. static void read_startup_files()
  653. {
  654.  char *name;
  655.  if (name = findfile(SYSTEMSTARTFILE, SYSTEMSTARTPATH, R_OK)){
  656.     char cmdbuf[BUFLEN];
  657.     sprintf(cmdbuf, "get %s", name);
  658.     cmdproc(cmdbuf);
  659.  }
  660.  if (name = findfile(USERSTARTFILE, USERSTARTPATH, R_OK)){
  661.     char cmdbuf[BUFLEN];
  662.     sprintf(cmdbuf, "get %s", name);
  663.     cmdproc(cmdbuf);
  664.  }
  665.  cmdproc("clear");
  666. }
  667. /*--------------------------------------------------------------------------*/
  668. static void process_cmd_line(argc,argv)
  669. int argc;
  670. const char *argv[];
  671. {
  672.  if (argc > 1){
  673.     char cmdbuf[BUFLEN];
  674.     sprintf(cmdbuf, "< %s", argv[1]);
  675.     cmdproc(cmdbuf);
  676.  }
  677. }
  678. /*--------------------------------------------------------------------------*/
  679. static void setup_traps()
  680. {
  681.  (void)signal(SIGFPE,sig_fpe);
  682.  (void)signal(SIGINT,sig_int);
  683. }
  684. /*--------------------------------------------------------------------------*/
  685. /* finish: clean up after a command
  686.  * deallocates space, closes plot windows, resets i/o redirection, etc.
  687.  * This is done separately for exception handling.
  688.  * If a command aborts, clean-up is still done, leaving a consistent state.
  689.  */
  690. static void finish()
  691. {
  692.  dc_finish();
  693.  plclose();
  694.  if (zero!=0.)
  695.     error(bWARNING, e_int, "zero");
  696.  errorcount = 0;
  697.  io.suppresserrors = NO;
  698.  inc_mode = NO;
  699.  outreset();
  700.  dealloc(NO);
  701. }
  702. /*--------------------------------------------------------------------------*/
  703. /* cmdproc: process a command
  704.  * parse, and act on, a command string
  705.  */
  706. void cmdproc(cmd)
  707. const char *cmd;
  708. {
  709.  volatile int cnt = 0;
  710.  static struct time_s timecheck;
  711.  int didsomething = YES;
  712.  
  713.  error(bTRACE, "%s\n", cmd);
  714.  
  715.  time_check(&timecheck);
  716.  time_zstart(&timecheck);
  717.  sim_mode = sNONE;
  718.  sim_phase = pNONE;
  719.  if (argparse(cmd,&cnt,ONEPASS,
  720.     "Ac",        aFUNCTION,         cmd_ac,
  721.     "ALter",    aFUNCTION,         cmd_alter,
  722.     "Build",    a2FUNCTION, plclear, cmd_build,
  723.     "CHDir",    a2FUNCTION, plclear, cmd_chdir,
  724.     "CDir",        a2FUNCTION, plclear, cmd_chdir,
  725.     "CLEAR",    a2FUNCTION, plclear, cmd_clear,
  726.     "CRTSET",   a2FUNCTION, plclear, cmd_crtset,
  727.     ""))
  728.     ;    /* split to hide sun lint bug. */
  729.  else if (argparse(cmd,&cnt,ONEPASS,
  730.     "DC",        aFUNCTION,             cmd_dc,
  731.     "DELete",   a2FUNCTION, plclear, cmd_delete,
  732.     "DIsto",    aFUNCTION,         cmd_disto,
  733.     "Edit",        a2FUNCTION, plclear, cmd_edit,
  734.     "END",        aFUNCTION,         cmd_quit,
  735.     "ENDS",        aFUNCTION,         cmd_ends,
  736.     "EXIt",        a2FUNCTION, plclear, cmd_quit,
  737.     "FAult",    aFUNCTION,            cmd_fault,
  738.     ""))
  739.     ;    /* split to hide sun lint bug. */
  740.  else if (argparse(cmd,&cnt,ONEPASS,
  741.     "FOurier",  aFUNCTION,            cmd_fourier,
  742.     "Generator",a2FUNCTION, plclear, cmd_generator,
  743.     "GET",        a2FUNCTION, plclear, cmd_get,
  744.     "Help",        a2FUNCTION, plclear, cmd_help,
  745.     "IC",        aFUNCTION,         cmd_ic,
  746.     "INsert",   a2FUNCTION, plclear, cmd_insert,
  747.     "List",        a2FUNCTION, plclear, cmd_list,
  748.     "LOg",        aFUNCTION,            cmd_log,
  749.     ""))
  750.     ;    /* split to hide sun lint bug. */
  751.  else if (argparse(cmd,&cnt,ONEPASS,
  752.     "MArk",        aFUNCTION,            cmd_keep,
  753.     "MErge",    a2FUNCTION, plclear, cmd_merge,
  754.     "MODEl",    aFUNCTION,         cmd_model,
  755.     "Modify",   a2FUNCTION, plclear, cmd_modify,
  756.     "Network",  a2FUNCTION, plclear, cmd_network,
  757.     "NODeset",  aFUNCTION,         cmd_nodeset,
  758.     "NOIse",    aFUNCTION,         cmd_noise,
  759.     "OP",        aFUNCTION,             cmd_op,
  760.     ""))
  761.     ;    /* split to hide sun lint bug. */
  762.  else if (argparse(cmd,&cnt,ONEPASS,
  763.     "OPTions",  a2FUNCTION, plclear, cmd_options,
  764.     "PAuse",    aFUNCTION,            cmd_pause,
  765.     "PLot",        a2FUNCTION, plclear, cmd_plot,
  766.     "PRint",    a2FUNCTION, plclear, cmd_print,
  767.     "PRobe",    a2FUNCTION, plclear, cmd_print,
  768.     "Quit",        a2FUNCTION, plclear, cmd_quit,
  769.     "Restore",  a2FUNCTION, plclear, cmd_restore,
  770.     "SAve",        a2FUNCTION, plclear, cmd_list,
  771.     ""))
  772.     ;    /* split to hide sun lint bug. */
  773.  else if (argparse(cmd,&cnt,ONEPASS,
  774.     "SENs",        aFUNCTION,         cmd_sens,
  775.     "SEt",        a2FUNCTION, plclear, cmd_options,
  776.     "SPectrum", aFUNCTION,            cmd_fourier,
  777.     "STatus",   a2FUNCTION, plclear, cmd_status,
  778.     "SUbckt",   aFUNCTION,         cmd_subckt,
  779.     "SWeep",    a2FUNCTION, plclear, cmd_sweep,
  780.     "TEmp",        aFUNCTION,         cmd_temp,
  781.     "TF",        aFUNCTION,         cmd_tf,
  782.     ""))
  783.     ;    /* split to hide sun lint bug. */
  784.  else if (argparse(cmd,&cnt,ONEPASS,
  785.     "TItle",    a2FUNCTION, plclear, cmd_title,
  786.     "TRansient",aFUNCTION,            cmd_tr,
  787.     "UNFault",  aFUNCTION,            cmd_unfault,
  788.     "UNMark",   aFUNCTION,            cmd_unkeep,
  789.     "Width",    aFUNCTION,         cmd_options,
  790.     "!",        a2FUNCTION, plclear, cmd_system,
  791.     "<",        aFUNCTION,            cmd_run,
  792.     ""))
  793.     ;    /* split to hide sun lint bug. */
  794.  else if (argparse(cmd,&cnt,ONEPASS,
  795.     ">",        aFUNCTION,            cmd_file,
  796.     ""))
  797.     ;
  798.  else{    /* comment or error */
  799.     cmd_comment(cmd,&cnt);
  800.     didsomething = NO;
  801.  }
  802.  if (opt.acct  &&  didsomething){
  803.     time_check(&timecheck);
  804.     mprintf(io.mstdout,"       user=%8.2f  sys=%8.2f\n",
  805.             timecheck.last_user, timecheck.last_system);
  806.     mprintf(io.mstdout,"total  user=%8.2f  sys=%8.2f\n",
  807.             timecheck.total_user, timecheck.total_system);
  808.  }
  809.  finish();
  810. }
  811. /*--------------------------------------------------------------------------*/
  812. /*--------------------------------------------------------------------------*/
  813. SHAR_EOF
  814. fi # end of overwriting check
  815. if test -f 'src/match.c'
  816. then
  817.     echo shar: will not over-write existing file "'src/match.c'"
  818. else
  819. cat << \SHAR_EOF > 'src/match.c'
  820. /* match  01/11/93
  821.  * Copyright 1983-1992   Albert Davis
  822.  * string compare
  823.  * compares characters until end of first string
  824.  * any non-alpha character is a terminator
  825.  * returns offset into string to legal start of next token
  826.  * (skips trailing spaces and comma, if any)
  827.  *     if they match so far, and enough matched,   else NO (0)
  828.  * Characters in reference string in UPPER case must match.
  829.  * Always requires at least one character to match.
  830.  */
  831. #include "ecah.h"
  832. #include "declare.h"
  833. /*--------------------------------------------------------------------------*/
  834.     int    pmatch(const char*,int*,const char*);
  835.     int    match(const char*,const char*);
  836. static    int    is_alpha(int);
  837.     void    setmatch(const char*,int*);
  838.     int    rematch(const char*);
  839. /*--------------------------------------------------------------------------*/
  840. /* pmatch: partial match -- match a keyword from command string
  841.  * tries to match a partial string &cmd[*cnt] against reference str2
  842.  * calls match, therefore depends on its definition of a match
  843.  * if no match, returns 0 and leaves cnt alone
  844.  * if match, updates cnt, (to eat string that was matched)
  845.  *    and returns the number of characters eaten.  (non zero)
  846.  * return value is usually interpreted as a truth value:
  847.  *    true if match exists.
  848.  */
  849. int pmatch(cmd,cnt,str2)
  850. const char *cmd, *str2;
  851. int  *cnt;
  852. {
  853.  int ind;
  854.  *cnt += ind = match(&cmd[*cnt],str2);
  855.  return ind;
  856. }
  857. /*--------------------------------------------------------------------------*/
  858. /* match: match str1 (under test) against str2 (reference)
  859.  * if no match, returns 0
  860.  * if match, returns the number of characters that match,
  861.  *    ---including whitespace---
  862.  * return value is usually interpreted as a truth value:
  863.  *    true if match exists.
  864.  * str1 (being tested) is considered to be case-insensitive
  865.  *    is terminated by a non-alpha character
  866.  * str2 (reference) has special considerations:
  867.  *    upper case characters must match, and must be present
  868.  *    lower case characters must match if present, but may be omitted
  869.  * strings are alpha only.
  870.  */
  871. int match (str1,str2)
  872. const char *str1, *str2;
  873. {
  874.  volatile int skp = 0;
  875.  
  876.  skipbl (str1,&skp);
  877.  while (to_lower(str1[skp]) == to_lower(*str2)){
  878.     str2++;
  879.     if (!is_alpha(str1[skp++]) || (!is_alpha(str1[skp]) && !isupper(*str2))){
  880.        skipcom(str1,&skp);
  881.        return skp;
  882.     }
  883.  }
  884.  return 0;
  885. }
  886. /*--------------------------------------------------------------------------*/
  887. /* is_alpha: a real function for isalpha
  888.  * because side-effects of c screw up the isalpha macro
  889.  */
  890. static int is_alpha(c)
  891. int c;
  892. {
  893.  return isalpha(toascii(c));
  894. }
  895. /*--------------------------------------------------------------------------*/
  896. /* setmatch, rematch: switch statement for strings
  897.  * call setmatch once, for the string being tested.
  898.  * repeated calls to rematch, one for each case
  899.  * pmatch always refers to the most recent setmatch: no nesting allowed
  900.  */
  901. static const char *cmdp;
  902. static int  *cntp;
  903.  
  904. /* setmatch: call with string being tested
  905.  */
  906. void setmatch(cmd,cnt)
  907. const char *cmd;
  908. int  *cnt;
  909. {
  910.  cmdp = cmd;
  911.  cntp = cnt;
  912. }
  913.  
  914. /* rematch: test for match.
  915.  * returns true (actually, see pmatch) if string in most recent call to
  916.  * setmatch matches its argument (see match), and updates i, so another
  917.  * call will match the next token
  918.  * returns false if match fails
  919.  */
  920. int rematch(ref)
  921. const char *ref;
  922. {
  923.  return pmatch(cmdp,cntp,ref);
  924. }
  925. /*--------------------------------------------------------------------------*/
  926. /*--------------------------------------------------------------------------*/
  927. SHAR_EOF
  928. fi # end of overwriting check
  929. if test -f 'src/modify.c'
  930. then
  931.     echo shar: will not over-write existing file "'src/modify.c'"
  932. else
  933. cat << \SHAR_EOF > 'src/modify.c'
  934. /* modify  12/29/92
  935.  * Copyright 1983-1992   Albert Davis
  936.  */
  937. #include "ecah.h"
  938. #include "branch.h"
  939. #include "error.h"
  940. #include "io.h"
  941. #include "declare.h"
  942. /*--------------------------------------------------------------------------*/
  943.     void    cmd_modify(const char*,int*);
  944.     void    cmd_restore(void);
  945.     void    cmd_fault(const char*,int*);
  946. static    double    sweep_fix(const char*,int*,const branch_t*,double);
  947. static    int    faultbranch(branch_t*,double);
  948.     void    cmd_unfault(void);
  949. /*--------------------------------------------------------------------------*/
  950. extern const struct ioctrl io;
  951.  
  952. extern const char e_int[], e_om[];
  953. extern const int crtplot;
  954. extern const int swp_type[];
  955. extern const int swp_count[], swp_steps[];
  956. extern const int swp_nest;
  957.  
  958. static branch_t *faultlist;
  959. static unsigned fcount = 0;        
  960. /*--------------------------------------------------------------------------*/
  961. /*ARGSUSED*/
  962. void cmd_modify(cmd,cnt)
  963. const char *cmd ;        /* command string                    */
  964. int *cnt ;            /* pointer to cmd string counter            */
  965. {
  966.  branch_t *brh;
  967.  volatile int cc;        /* character counter                */
  968.  int next = 0;            /* remember char counter, for next arg        */
  969.  int count;            /* count number of changes                */
  970.  double value;            /* new value                    */
  971.  
  972.  dealloc(YES);
  973.  for (    ; isalpha(cmd[*cnt]) ; *cnt=next){
  974.     count = 0;
  975.     for (brh = firstbranch_all();
  976.          cc= *cnt, brh = findbranch(cmd,&cc,brh,lastbranch_all()), exists(brh);
  977.     /**/ brh = nextbranch_all(brh)){
  978.        value = ctof(cmd,&cc);
  979.  
  980.        brh->val = value;
  981.        count++;
  982.        next = cc;
  983.     }
  984.     if (count == 0)
  985.        break;
  986.  }
  987.  syntax(cmd,cnt,bWARNING);
  988. }
  989. /*--------------------------------------------------------------------------*/
  990. void cmd_restore()
  991. {
  992.  cmd_unfault();
  993.  cmd_unkeep();
  994. }
  995. /*--------------------------------------------------------------------------*/
  996. void cmd_fault(cmd,cnt)
  997. const char *cmd;
  998. int  *cnt;
  999. {
  1000.  branch_t *brh;
  1001.  volatile int cc;        /* character counter                */
  1002.  int next = 0;            /* remember char counter, for next arg        */
  1003.  int count;            /* count number of faults                */
  1004.  double value;            /* new value                    */
  1005.  
  1006.  dealloc(YES);
  1007.  for (    ; isalpha(cmd[*cnt]) ; *cnt=next){
  1008.     count = 0;
  1009.     for (brh = firstbranch_all();
  1010.          cc= *cnt, brh = findbranch(cmd,&cc,brh,lastbranch_all()), exists(brh);
  1011.     /**/ brh = nextbranch_all(brh)){
  1012.        value = ctof(cmd,&cc);
  1013.        value = sweep_fix(cmd,&cc,brh,value);
  1014.  
  1015.        if (!faultbranch(brh,value))
  1016.       error(bWARNING, e_int, "fault");
  1017.        count++;
  1018.        next = cc;
  1019.     }
  1020.     if (count == 0)
  1021.        break;
  1022.  }
  1023.  syntax(cmd,cnt,bWARNING);
  1024. }
  1025. /*--------------------------------------------------------------------------*/
  1026. static double sweep_fix(cmd,cc,brh,value)
  1027. const char *cmd;            /* fix the value for sweep command.        */
  1028. int  *cc;                /* if not sweeping, return value.        */
  1029. const branch_t *brh;
  1030. double value;
  1031. {
  1032.  if (swp_steps[swp_nest] != 0   &&   isfloat(cmd[*cc])){
  1033.     double end, offset;
  1034.  
  1035.     end = ctof(cmd,cc);
  1036.     offset = (double)swp_count[swp_nest] / (double)swp_steps[swp_nest];
  1037.     if (swp_type[swp_nest]=='L'){
  1038.        if (value == 0.)
  1039.       error(bERROR, "log sweep can't pass zero\n");
  1040.        else
  1041.       value *= pow( (end/value), offset );
  1042.     }else{
  1043.        value += (end-value) * offset;
  1044.     }
  1045.  
  1046.     if (!crtplot)
  1047.        mprintf( io.mstdout, "%u> sweep %s =%s\n",
  1048.         swp_count[swp_nest]+1,
  1049.         printlabel(brh,NO),
  1050.         ftos(value,"             ",7,0)
  1051.         );
  1052.  }
  1053.  return value;
  1054. }
  1055. /*--------------------------------------------------------------------------*/
  1056. /* faultbranch: "fault" a single branch. (temporarily change a value)
  1057.  * save the existing branch in "faultlist"
  1058.  * put the modified branch in the parts list
  1059.  * does not fix extensions here, up to caller
  1060.  * needs rework for pointers, extensions, etc.
  1061.  * unreliable.  does not maintain list consistency
  1062.  */
  1063. static int faultbranch(brh,value)
  1064. branch_t *brh;
  1065. double value;
  1066. {
  1067.  if (!isdevice(brh))
  1068.     return NO;
  1069.  
  1070.  if (faultlist)
  1071.     faultlist=(branch_t*)realloc((void*)faultlist,(fcount+1)*sizeof(branch_t));
  1072.  else
  1073.     faultlist = (branch_t*)calloc(fcount+1, sizeof(branch_t));
  1074.  if (!faultlist)
  1075.     error(bERROR, e_om, "fault");
  1076.  faultlist[fcount] = *brh;
  1077.  fcount++;
  1078.  
  1079.  brh->val = value;
  1080.  brh->x = (generic_t*)NULL;
  1081.  brh->subckt = (branch_t*)NULL;
  1082.  
  1083.  return YES;
  1084. }
  1085. /*--------------------------------------------------------------------------*/
  1086. /* cmd_unfault: (command) remove faults and restore pre-fault values
  1087.  * the warnings are notices about known bugs
  1088.  * editing a list that has faults can corrupt it.
  1089.  */
  1090. void cmd_unfault()    /* remove all faults, and restore to normal    */
  1091. {            /* can be a command                */
  1092.  branch_t *prev;
  1093.  branch_t *next;
  1094.  
  1095.  while (fcount-- > 0){
  1096.     prev = faultlist[fcount].prev;
  1097.     next = faultlist[fcount].next;
  1098.     if (prev->next != next->prev)
  1099.         error(bERROR, e_int, "unfault: inconsistent links");
  1100.     if (prev != prev->next->prev)
  1101.     error(bERROR, e_int, "unfault: missing back link");
  1102.     if (next != next->prev->next)
  1103.         error(bERROR, e_int, "unfault: missing fwd link");
  1104.     *(prev->next) = faultlist[fcount];
  1105.  }
  1106.  fcount = 0;
  1107.  qfree((void**)&faultlist);
  1108. }
  1109. /*--------------------------------------------------------------------------*/
  1110. /*--------------------------------------------------------------------------*/
  1111. SHAR_EOF
  1112. fi # end of overwriting check
  1113. if test -f 'src/network.c'
  1114. then
  1115.     echo shar: will not over-write existing file "'src/network.c'"
  1116. else
  1117. cat << \SHAR_EOF > 'src/network.c'
  1118. /* network  12/29/92
  1119.  * Copyright 1983-1992   Albert Davis
  1120.  * Prints out a list of all node connections.
  1121.  */
  1122. #include "ecah.h"
  1123. #include "branch.h"
  1124. #include "error.h"
  1125. #include "io.h"
  1126. #include "status.h"
  1127. #include "declare.h"
  1128. /*--------------------------------------------------------------------------*/
  1129.     void    cmd_network(const char*,int*);
  1130. static    void    checklist(const branch_t*,int);
  1131. /*--------------------------------------------------------------------------*/
  1132. extern       struct ioctrl io;
  1133. extern const struct status stats;
  1134. /*--------------------------------------------------------------------------*/
  1135. void cmd_network(cmd,cnt)
  1136. const char *cmd;
  1137. int  *cnt;
  1138. {
  1139.  int nod;        /* the node we are trying to determine connections  */
  1140.  int start, stop;
  1141.  
  1142.  io.where |= io.mstdout;
  1143.  
  1144.  for (start = stop = -1;   ;    ){
  1145.     if (isdigit(cmd[*cnt])){
  1146.        int temp;
  1147.        temp = ctoi(cmd,cnt);
  1148.        if (cmd[*cnt] == '-'){
  1149.       ++*cnt;
  1150.       start = temp;
  1151.        }else if (start < 0){
  1152.       start = temp;
  1153.       if (stop < 0)
  1154.          stop = start;
  1155.        }else{
  1156.       stop = temp;
  1157.        }
  1158.     }else if (cmd[*cnt] == '-'){
  1159.        ++*cnt;
  1160.        skipbl(cmd,cnt);
  1161.        if (isdigit(cmd[*cnt]))
  1162.       stop = ctoi(cmd,cnt);
  1163.     }else if (outset(cmd,cnt,(char*)NULL,"   ")){
  1164.        /*nothing*/;
  1165.     }else{
  1166.        syntax(cmd,cnt,bWARNING);
  1167.        break;
  1168.     }
  1169.  }
  1170.  
  1171.  initio(io.where,(FILE*)NULL);
  1172.  if (start < 0) 
  1173.     start = 0;
  1174.  if (stop < 0  ||  stop > stats.total_nodes)
  1175.     stop = stats.user_nodes;
  1176.  if (!exists(firstbranch_all()))
  1177.     error(bERROR, "no circuit\n");
  1178.  if (start>stats.total_nodes)
  1179.     error(bERROR, "%u nodes\n", stats.total_nodes);
  1180.  
  1181.  mprintf(io.where,"Node:  Branches\n");
  1182.  for (nod = start;  nod <= stop;  ++nod){
  1183.     mprintf(io.where,"%4u:",nod);
  1184.     checklist(firstbranch_dev(),nod);
  1185.     mputc('\n',io.where);
  1186.  }
  1187. }
  1188. /*--------------------------------------------------------------------------*/
  1189. static void checklist(brh,nod)
  1190. const branch_t *brh;
  1191. int nod;
  1192. {
  1193.  const branch_t *stop;
  1194.  stop = brh;
  1195.  do {
  1196.     if (isdevice(brh)){
  1197.        int ii;
  1198.        for (ii = 0;  brh->n[ii].t != INVALIDNODE;  ii++){
  1199.           if (nod == brh->n[ii].t)
  1200.              mprintf(io.where," %s",printlabel(brh,NO));
  1201.        }
  1202.        if (brh->tracesubckt)
  1203.           checklist(brh->subckt,nod);
  1204.     }
  1205.  } while (brh = nextbranch_dev(brh),  brh != stop);
  1206. }
  1207. /*--------------------------------------------------------------------------*/
  1208. /*--------------------------------------------------------------------------*/
  1209. SHAR_EOF
  1210. fi # end of overwriting check
  1211. if test -f 'src/nodes.c'
  1212. then
  1213.     echo shar: will not over-write existing file "'src/nodes.c'"
  1214. else
  1215. cat << \SHAR_EOF > 'src/nodes.c'
  1216. /* nodes.c  01/11/93
  1217.  * Copyright 1983-1992   Albert Davis
  1218.  * functions to handle node mapping
  1219.  */
  1220. #include "ecah.h"
  1221. #include "branch.h"
  1222. #include "status.h"
  1223. #include "declare.h"
  1224. /*--------------------------------------------------------------------------*/
  1225.     int    newnode_subckt(void);
  1226.     int    newnode_model(void);
  1227.     int    parsenodes(branch_t*,const char*,int*,int);
  1228.     void    printnodes(const branch_t*,int);
  1229. static    int    name2number(const char*,int*);
  1230. static    char*    number2name(char*,int);
  1231. /*--------------------------------------------------------------------------*/
  1232. extern struct status stats;
  1233. /*--------------------------------------------------------------------------*/
  1234. /* newnode_subckt: get a new node number, unique internal nodes in subckts
  1235.  */
  1236. int newnode_subckt()
  1237. {
  1238.  ++stats.subckt_nodes;
  1239.  return ++stats.total_nodes;
  1240. }
  1241. /*--------------------------------------------------------------------------*/
  1242. /* newnode_model: get a new node number, unique internal nodes in models
  1243.  */
  1244. int newnode_model()
  1245. {
  1246.  ++stats.model_nodes;
  1247.  return ++stats.total_nodes;
  1248. }
  1249. /*--------------------------------------------------------------------------*/
  1250. /* parsenodes: parse circuit connections from input string
  1251.  * result in brh.
  1252.  * n array must hold at least nodecount+1
  1253.  * cnt updated.
  1254.  */
  1255. int parsenodes(brh,cmd,cnt,nodecount)
  1256. branch_t *brh;
  1257. const char *cmd;
  1258. int *cnt;
  1259. int nodecount;
  1260. {
  1261.  int ii;
  1262.  int count = 0;
  1263.  for (ii = 0;  ii < nodecount;  ii++){
  1264.     brh->n[ii].t = brh->n[ii].e = name2number(cmd,cnt);
  1265.     if (brh->n[ii].e != INVALIDNODE)
  1266.        count = ii+1;
  1267.  }
  1268.  brh->n[ii].t = brh->n[ii].e = INVALIDNODE;
  1269.  return count;
  1270. }
  1271. /*--------------------------------------------------------------------------*/
  1272. /* printnodes: print a node list
  1273.  */
  1274. void printnodes(brh,where)
  1275. const branch_t *brh;
  1276. int where;
  1277. {
  1278.  int ii;
  1279.  for (ii = 0;   brh->n[ii].e != INVALIDNODE;   ii++){
  1280.     char name[LABELEN+1];
  1281.     mprintf(where, " %s ", number2name(name,brh->n[ii].e));
  1282.  }
  1283. }
  1284. /*--------------------------------------------------------------------------*/
  1285. /* name2number: convert node name to node number
  1286.  * returns node number
  1287.  * cnt updated
  1288.  */
  1289. static int name2number(cmd,cnt)
  1290. const char *cmd;
  1291. int *cnt;
  1292. {
  1293.  int test;
  1294.  int node;
  1295.  
  1296.  test = *cnt;
  1297.  node = ctoi(cmd,cnt);
  1298.  return  (test == *cnt)  ?  INVALIDNODE  :  node;
  1299. }
  1300. /*--------------------------------------------------------------------------*/
  1301. /* number2name: convert node number to node name
  1302.  * result in name (must be big enough)
  1303.  * returns name
  1304.  */
  1305. static char* number2name(name,node)
  1306. char *name;
  1307. int node;
  1308. {
  1309.  (void)sprintf(name, "%d", node);
  1310.  return name;
  1311. }
  1312. /*--------------------------------------------------------------------------*/
  1313. /*--------------------------------------------------------------------------*/
  1314. SHAR_EOF
  1315. fi # end of overwriting check
  1316. if test -f 'src/nodeset.c'
  1317. then
  1318.     echo shar: will not over-write existing file "'src/nodeset.c'"
  1319. else
  1320. cat << \SHAR_EOF > 'src/nodeset.c'
  1321. /* nodeset.c  01/03/93
  1322.  * Copyright 1983-1992   Albert Davis
  1323.  * nodeset and ic commands
  1324.  */
  1325. #include "ecah.h"
  1326. #include "argparse.h"
  1327. #include "error.h"
  1328. #include "io.h"
  1329. #include "nodeset.h"
  1330. #include "declare.h"
  1331. /*--------------------------------------------------------------------------*/
  1332.     void    cmd_ic(const char*,int*);
  1333.     void    cmd_nodeset(const char*,int*);
  1334. static    void    nic(const char*,int*,nodeset_t*);
  1335. static    void    addnodeset(nodeset_t*,int,double);
  1336. static    void    clearnodeset(nodeset_t*,nodeset_t*);
  1337. static    void    deletenodeset(nodeset_t*,int);
  1338. static    void    listnodeset(const nodeset_t*);
  1339. /*--------------------------------------------------------------------------*/
  1340. extern const struct ioctrl io;
  1341. extern const char e_om[];
  1342. static nodeset_t ictop;
  1343. static nodeset_t nstop;
  1344. /*--------------------------------------------------------------------------*/
  1345. void cmd_ic(cmd,cnt)
  1346. const char *cmd;
  1347. int *cnt;
  1348. {
  1349.  nic(cmd,cnt,&ictop);
  1350. }
  1351. /*--------------------------------------------------------------------------*/
  1352. void cmd_nodeset(cmd,cnt)
  1353. const char *cmd;
  1354. int *cnt;
  1355. {
  1356.  nic(cmd,cnt,&nstop);
  1357. }
  1358. /*--------------------------------------------------------------------------*/
  1359. static void nic(cmd,cnt,top)
  1360. const char *cmd;
  1361. int *cnt;
  1362. nodeset_t *top;
  1363. {
  1364.  if (!cmd[*cnt]){
  1365.    listnodeset(top);
  1366.    return;
  1367.  }
  1368.  
  1369.  if (pmatch(cmd,cnt,"CLEAR")){
  1370.     clearnodeset(top,top);
  1371.  }else{
  1372.     while (pmatch(cmd,cnt,"V")){
  1373.        int node = ctoi(cmd,cnt);
  1374.        int cntold = *cnt;
  1375.        double voltage = ctof(cmd,cnt);
  1376.        if (cntold == *cnt){        /* no voltage value = unset */
  1377.       deletenodeset(top,node);
  1378.        }else{
  1379.       addnodeset(top,node,voltage);
  1380.        }
  1381.     }
  1382.     syntax(cmd,cnt,bWARNING);
  1383.  }
  1384. }
  1385. /*--------------------------------------------------------------------------*/
  1386. /* addnodeset: add a new nodeset or ic
  1387.  */
  1388. static void addnodeset(top,node,voltage)
  1389. nodeset_t *top;
  1390. int node;
  1391. double voltage;
  1392. {
  1393.  nodeset_t *ptr,*new;
  1394.  
  1395.  for (ptr=top;  (ptr->next)&&(ptr->next->node<node);  ptr=ptr->next)
  1396.     /* nothing */;
  1397.     
  1398.  if ((ptr->next)&&(ptr->next->node==node)){
  1399.     error(bWARNING, "replacing nodeset/ic at node %u\n", node);
  1400.  }else{
  1401.     new = (nodeset_t*)calloc(1,sizeof(nodeset_t));
  1402.     if (!new)
  1403.        error(bERROR, e_om, "addnodeset");
  1404.     new->node = node;
  1405.     new->next = ptr->next;
  1406.     ptr->next = new;
  1407.  }
  1408.  
  1409.  ptr = ptr->next;
  1410.  ptr->voltage = voltage;
  1411. }  
  1412. /*--------------------------------------------------------------------------*/
  1413. /* clearnodeset: deallocate and clear all from ptr on,
  1414.  * but leave top allocated  (recursive)
  1415.  */
  1416. static void clearnodeset(top,ptr)
  1417. nodeset_t *top,*ptr;
  1418. {
  1419.  if (ptr->next)
  1420.     clearnodeset(top,ptr->next);
  1421.  if (ptr != top){
  1422.     free((void*)ptr);
  1423.  }else{
  1424.     top->next=NULL;
  1425.     top->node=0;
  1426.     top->voltage=0.;
  1427.  }
  1428. }
  1429. /*--------------------------------------------------------------------------*/
  1430. /* deletenodeset: delete a node set  (unset a node)
  1431.  */
  1432. static void deletenodeset(top,node)
  1433. nodeset_t *top;
  1434. int node;
  1435. {
  1436.  nodeset_t *ptr;
  1437.  
  1438.  for(ptr=top;  (ptr->next)&&(ptr->next->node<node);  ptr=ptr->next)
  1439.     /* nothing */;            /* scan for node match */
  1440.  
  1441.  if ((ptr->next)&&(ptr->next->node==node)){
  1442.     nodeset_t *link;
  1443.     link = ptr->next->next;
  1444.     free((void*)ptr->next);
  1445.     ptr->next = link;
  1446.  }
  1447. }
  1448. /*--------------------------------------------------------------------------*/
  1449. /* listnodeset: list all nodes set
  1450.  */
  1451. static void listnodeset(top)
  1452. const nodeset_t *top;
  1453. {
  1454.  nodeset_t *ptr;
  1455.  
  1456.  for (ptr=top->next;  ptr;  ptr=ptr->next){
  1457.     mprintf(io.mstdout,"V(%d)=%s ",ptr->node,ftos(ptr->voltage,"",7,0));
  1458.  }  
  1459.  mprintf(io.mstdout,"\n");    
  1460. }
  1461. /*--------------------------------------------------------------------------*/
  1462. /*--------------------------------------------------------------------------*/
  1463. SHAR_EOF
  1464. fi # end of overwriting check
  1465. if test -f 'src/options.c'
  1466. then
  1467.     echo shar: will not over-write existing file "'src/options.c'"
  1468. else
  1469. cat << \SHAR_EOF > 'src/options.c'
  1470. /* options  01/26/93
  1471.  * Copyright 1983-1992   Albert Davis
  1472.  * set and view options and user controllable variables
  1473.  */
  1474. #include "ecah.h"
  1475. #include "argparse.h"
  1476. #include "error.h"
  1477. #include "io.h"
  1478. #include "options.h"
  1479. #include "declare.h"
  1480. /*--------------------------------------------------------------------------*/
  1481.     void    cmd_options(const char*,int*);
  1482. /*--------------------------------------------------------------------------*/
  1483. extern const struct ioctrl io;
  1484. extern       struct options opt;
  1485. /*--------------------------------------------------------------------------*/
  1486. void cmd_options(cmd,cnt)
  1487. const char *cmd;
  1488. int  *cnt;
  1489. {
  1490.  int where;
  1491.  int dummy;
  1492.  int ii;
  1493.  double arg1, arg2;
  1494.  
  1495.  where = (cmd[*cnt])? 0 : io.mstdout;
  1496.  while (cmd[*cnt]){
  1497.              /* didsomething avoids heap space problem in MSC */
  1498.     int didsomething = argparse(cmd,cnt,REPEAT,
  1499.         "ACCT",        aENUM,        &opt.acct,    YES,
  1500.         "NOACCT",    aENUM,        &opt.acct,    NO,
  1501.     "LIST",        aENUM,        &opt.list,    YES,
  1502.     "NOLIST",    aENUM,        &opt.list,    NO,
  1503.     "MOD",        aENUM,        &opt.nomod,    NO,
  1504.     "NOMOD",    aENUM,        &opt.nomod,    YES,
  1505.     "PAGE",        aENUM,        &opt.page,    YES,
  1506.     "NOPAGE",    aENUM,        &opt.page,    NO,
  1507.     "NODE",        aENUM,        &opt.node,    YES,
  1508.     "NONODE",    aENUM,        &opt.node,    NO,
  1509.     "OPTS",        aENUM,        &opt.opts,    YES,
  1510.     "NOOPTS",    aENUM,        &opt.opts,    NO,
  1511.     "GMIN",        aUDOUBLE,    &opt.gmin,
  1512.     "RELTOL",    aUDOUBLE,    &opt.reltol,
  1513.     "ABSTOL",    aUDOUBLE,    &opt.abstol,
  1514.     "VNTOL",    aUDOUBLE,    &opt.vntol,
  1515.     "TRTOL",    aUDOUBLE,    &opt.trtol,
  1516.     "CHGTOL",    aUDOUBLE,    &opt.chgtol,
  1517.     "PIVTOL",    aUDOUBLE,    &opt.pivtol,
  1518.     "PIVREL",    aUDOUBLE,    &opt.pivrel,
  1519.     "NUMDGT",    aFINT,        &opt.numdgt,
  1520.     "TNOM",        aODOUBLE,    &opt.tnom,    -ABS_ZERO,
  1521.     "CPTIME",    aFINT,        &opt.cptime,
  1522.     "LIMTIM",    aFINT,        &opt.limtim,
  1523.     "LIMPTS",    aFINT,        &opt.limpts,
  1524.     "LVLCOD",    aFINT,        &opt.lvlcod,
  1525.     "LVLTIM",    aFINT,        &opt.lvltim,
  1526.     "METHOD",    aENUM,        &dummy,        YES,
  1527.     "GEAR",        aENUM,        &opt.method,    mGEAR,
  1528.     "TRAPezoidal",    aENUM,        &opt.method,    mTRAPEZOID,
  1529.     "MAXORD",    aFINT,        &opt.maxord,
  1530.      "");
  1531.     if (didsomething)
  1532.         ;
  1533.     else if (argparse(cmd,cnt,REPEAT,
  1534.     "Seed",        aFINT,        &opt.seed,
  1535.     "WCZero",    aUDOUBLE,    &opt.wczero,
  1536.     "Damp",        aUDOUBLE,    &opt.damp,
  1537.     "Floor",    aUDOUBLE,    &opt.floor,
  1538.     "Tempamb",    aODOUBLE,    &opt.tempamb,    -ABS_ZERO,
  1539.     "Short",    aUDOUBLE,    &opt.shortckt,
  1540.     "TRansits",    aFINT,        &opt.transits,
  1541.     "INwidth",    aFINT,        &opt.inwidth,
  1542.     "OUTwidth",    aFINT,        &opt.outwidth,
  1543.     "XDivisions",    aUDOUBLE,    &opt.xdivisions,
  1544.     "YDivisions",    aUDOUBLE,    &opt.ydivisions,
  1545.      ""))
  1546.         ;
  1547.     else if (argparse(cmd,cnt,REPEAT,
  1548.     "NAG",        aENUM,        &opt.picky,    bNOERROR,
  1549.     "NONag",    aENUM,        &opt.picky,    bTRACE,
  1550.     "TRACe",    aENUM,        &opt.picky,    bTRACE,
  1551.     "NOTrace",    aENUM,        &opt.picky,    bLOG,
  1552.     "LOG",        aENUM,        &opt.picky,    bLOG,
  1553.     "NOLog",    aENUM,        &opt.picky,    bDEBUG,
  1554.     "DEBug",    aENUM,        &opt.picky,    bDEBUG,
  1555.     "NODebug",    aENUM,        &opt.picky,    bPICKY,
  1556.     "PICky",    aENUM,        &opt.picky,    bPICKY,
  1557.     "NOPicky",    aENUM,        &opt.picky,    bWARNING,
  1558.     "WARning",    aENUM,        &opt.picky,    bWARNING,
  1559.     "NOWarn",    aENUM,        &opt.picky,    bDANGER,
  1560.     "ERRor",    aENUM,        &opt.picky,    bERROR,
  1561.     "NOError",    aENUM,        &opt.picky,    bDISASTER,
  1562.     "DISaster",    aENUM,        &opt.picky,    bDISASTER,
  1563.     ""))
  1564.     ;
  1565.     else if (argparse(cmd,cnt,REPEAT,
  1566.     "ORder",    aENUM,        &dummy,        YES,
  1567.     "REVerse",    aENUM,        &opt.order,    oREVERSE,
  1568.     "FORward",    aENUM,        &opt.order,    oFORWARD,
  1569.     "AUTo",        aENUM,        &opt.order,    oAUTO,
  1570.     "MODe",        aENUM,        &dummy,        YES,
  1571.     "ANAlog",    aENUM,        &opt.mode,    mANALOG,
  1572.     "DIGital",    aENUM,        &opt.mode,    mDIGITAL,
  1573.     "MIXed",    aENUM,        &opt.mode,    mMIXED,
  1574.     "DUPcheck",    aENUM,        &opt.dupcheck,    YES,
  1575.     "NODUPcheck",    aENUM,        &opt.dupcheck,    NO,
  1576.     "BYPass",    aENUM,        &opt.bypass,    YES,
  1577.     "NOBYPass",    aENUM,        &opt.bypass,    NO,
  1578.     "VBYPass",    aENUM,        &opt.bypass,    bVOLT,
  1579.     "INCmode",    aENUM,        &opt.incmode,    YES,
  1580.     "NOIncmode",    aENUM,        &opt.incmode,    NO,
  1581.     "LIMIT",    aUDOUBLE,    &opt.limit,
  1582.     "MRT",        aUDOUBLE,    &opt.mrt,
  1583.     "FOOOO",    aFINT,        &opt.foooo,
  1584.      ""))
  1585.        dealloc(YES);
  1586.     else if (ii=*cnt, argparse(cmd,cnt,ONEPASS,
  1587.         "ITL",        a2DOUBLE,    &arg1,        &arg2,
  1588.     "")){
  1589.        if ((int)arg1 >= 1  &&  (int)arg1 <= 8){
  1590.       opt.itl[(int)arg1] = (int)arg2;
  1591.        }else{
  1592.           *cnt = ii;
  1593.       syntax(cmd,cnt,bWARNING);
  1594.       skiparg(cmd,cnt);
  1595.        }
  1596.     }else{
  1597.     syntax(cmd,cnt,bWARNING);
  1598.     skiparg(cmd,cnt);
  1599.     }
  1600.  }
  1601.  
  1602.  opt.lowlim = 1 - opt.reltol;
  1603.  opt.uplim  = 1 + opt.reltol;
  1604.  
  1605. #ifdef NOTIME
  1606.  opt.acct = NO;
  1607. #endif
  1608.  
  1609.  if (where){
  1610.     mprintf(where, ".options ");
  1611.     if (opt.acct)   mprintf(where," acct ");
  1612.     if (opt.list)   mprintf(where," list ");
  1613.     if (opt.nomod)  mprintf(where," nomod ");
  1614.     if (opt.page)   mprintf(where," page ");
  1615.     if (opt.node)   mprintf(where," node ");
  1616.     if (opt.opts)   mprintf(where," opts ");
  1617.     mprintf(where, " gmin=%s ",   ftos(opt.gmin,   "", 7, 0));
  1618.     mprintf(where, " reltol=%s ", ftos(opt.reltol, "", 7, 0));
  1619.     mprintf(where, " abstol=%s ", ftos(opt.abstol, "", 7, 0));
  1620.     mprintf(where, " vntol=%s ",  ftos(opt.vntol,  "", 7, 0));
  1621.     mprintf(where, " trtol=%s ",  ftos(opt.trtol,  "", 7, 0));
  1622.     mprintf(where, " chgtol=%s ", ftos(opt.chgtol, "", 7, 0));
  1623.     mprintf(where, " pivtol=%s ", ftos(opt.pivtol, "", 7, 0));
  1624.     mprintf(where, " pivrel=%s ", ftos(opt.pivrel, "", 7, 0));
  1625.     mprintf(where, " numdgt=%d ", opt.numdgt);
  1626.     mprintf(where, " tnom=%s ",   ftos(opt.tnom+ABS_ZERO,   "", 7, 0));
  1627.     mprintf(where, " cptime=%d ", opt.cptime);
  1628.     mprintf(where, " limtim=%d ", opt.limtim);
  1629.     mprintf(where, " limpts=%d ", opt.limpts);
  1630.     mprintf(where, " lvlcod=%d ", opt.lvlcod);
  1631.     mprintf(where, " lvltim=%d ", opt.lvltim);
  1632.     if (opt.method == mTRAPEZOID) mprintf(where, " method=trapezoid ");
  1633.     else if (opt.method == mGEAR) mprintf(where, " method=gear ");
  1634.     mprintf(where, " maxord=%d ", opt.maxord);
  1635.     for (ii=1;  ii<=8;  ii++)
  1636.        mprintf(where, " itl%d=%d ", ii, opt.itl[ii]);
  1637.     mprintf(where, " seed=%d ",   opt.seed);
  1638.     mprintf(where, " wczero=%s ", ftos(opt.wczero,  "", 7, 0));
  1639.     mprintf(where, " damp=%s ",   ftos(opt.damp,    "", 7, 0));
  1640.     mprintf(where, " floor=%s ",  ftos(opt.floor,   "", 7, 0));
  1641.     mprintf(where, " tempamb=%s ",ftos(opt.tempamb+ABS_ZERO, "", 7, 0));
  1642.     mprintf(where, " short=%s ",  ftos(opt.shortckt,"", 7, 0));
  1643.     mprintf(where, " in=%d ",     opt.inwidth);
  1644.     mprintf(where, " out=%d ",    opt.outwidth);
  1645.     mprintf(where, " xdivisions=%s ",  ftos(opt.xdivisions,   "", 7, 0));
  1646.     mprintf(where, " ydivisions=%s ",  ftos(opt.ydivisions,   "", 7, 0));
  1647.     if (opt.order == oREVERSE) mprintf(where, " order=reverse ");
  1648.     else if (opt.order == oFORWARD) mprintf(where, " order=forward ");
  1649.     else if (opt.order == oAUTO) mprintf(where, " order=auto ");
  1650.     if (opt.mode == mANALOG) mprintf(where, " mode=analog ");
  1651.     else if (opt.mode == mDIGITAL) mprintf(where, " mode=digital ");
  1652.     else if (opt.mode == mMIXED) mprintf(where, " mode=mixed ");
  1653.     mprintf(where, " transits=%d ",opt.transits);
  1654.     mprintf(where," %sdupcheck ", ((opt.dupcheck)?"":"no"));  
  1655.     if (opt.bypass == NO) mprintf(where, " nobypass ");
  1656.     else if (opt.bypass == YES) mprintf(where, " bypass ");
  1657.     else if (opt.bypass == bVOLT) mprintf(where, " vbypass ");
  1658.     mprintf(where," %sincmode ", ((opt.incmode)?"":"no"));    
  1659.     mprintf(where, " limit=%s ",  ftos(opt.limit,"", 7, 0));
  1660.     mprintf(where, " mrt=%s ",  ftos(opt.mrt,"", 7, 0));
  1661.     mputc('\n',where);
  1662.  }
  1663. }
  1664. /*--------------------------------------------------------------------------*/
  1665. /*--------------------------------------------------------------------------*/
  1666. SHAR_EOF
  1667. fi # end of overwriting check
  1668. if test -f 'src/outset.c'
  1669. then
  1670.     echo shar: will not over-write existing file "'src/outset.c'"
  1671. else
  1672. cat << \SHAR_EOF > 'src/outset.c'
  1673. /* outset  03/07/92
  1674.  * Copyright 1983-1992   Albert Davis
  1675.  * Sets up output direction and format for most commands
  1676.  * returns  NO     if it did nothing
  1677.  *        fORD if nothing with a file
  1678.  *        fOUT if it set up an output file
  1679.  *        fIN     if is set up an input file
  1680.  * updates pointers into the string
  1681.  * outreset starts it all over
  1682.  */
  1683. #include "ecah.h"
  1684. #include "error.h"
  1685. #include "formats.h"
  1686. #include "io.h"
  1687. #include "declare.h"
  1688. /*--------------------------------------------------------------------------*/
  1689.     void    initio(int,FILE*);
  1690.     void    decipher(char*);
  1691.     void    outreset(void);
  1692.     int    outset(const char*,int*,const char*,const char*);
  1693. static    FILE*    file_open(const char*,int*,const char*,const char*,FILE*);
  1694. /*--------------------------------------------------------------------------*/
  1695. extern struct ioctrl io;
  1696. static FILE *fn;        /* write file                    */
  1697. /*--------------------------------------------------------------------------*/
  1698. /* initio: initialize file encryption, etc
  1699.  */
  1700. void initio(Where,Whence)
  1701. int Where;
  1702. FILE *Whence;
  1703. {
  1704.  char *tag;
  1705.  tag = "''''";
  1706.  if (io.outcipher)            /* if writing an encrypted file,    */
  1707.     mprintf(Where,"%s\n",tag);        /* mark it as encrypted            */
  1708.  if (Whence){
  1709.     char buf[BUFLEN];
  1710.     if (!fgets(buf, BUFLEN, Whence))    /* if the first line deciphers to   */
  1711.        return;                /* the cipher tag, it is encrypted  */
  1712.     io.incipher = YES;            /* otherwise,                */
  1713.     decipher(buf);            /*     rewind and read normally   */
  1714.     if (strcmp(buf,tag) != 0){   /* mismatch */
  1715.        io.incipher = NO;
  1716.        (void)fseek(Whence,0L,SEEK_SET);
  1717.     }
  1718.  }
  1719. }
  1720. /*--------------------------------------------------------------------------*/
  1721. /* decipher: un-encrypt a line of text in place
  1722.  */
  1723. void decipher(buf)
  1724. char *buf;
  1725. {
  1726.  if (io.incipher){
  1727.     for ( ; isprint(buf[1]); buf++ ){
  1728.        int fixed;
  1729.        fixed = (int)buf[1] - (int)buf[0];
  1730.        while (!isascii(fixed) || !isprint(fixed))
  1731.        fixed += (0x7f-0x20);
  1732.        buf[0] = (char)fixed;
  1733.     }
  1734.     buf[0] = '\0';
  1735.  }
  1736. }
  1737. /*--------------------------------------------------------------------------*/
  1738. /* outreset: close files and set i/o flags to standard values
  1739.  */
  1740. void outreset()
  1741. {
  1742.  xclose(&fn);
  1743.  xclose(&io.whence);
  1744.  io.where = io.formaat = 0;
  1745.  io.incipher = io.outcipher = io.pack = NO;
  1746.  if (io.echoflag)
  1747.     io.where |= io.mstdout;
  1748.  if (io.printflag)
  1749.     io.where |= io.mprint;
  1750. }
  1751. /*--------------------------------------------------------------------------*/
  1752. /* outset: set up i/o for a command
  1753.  * return whether or not it did anything
  1754.  */
  1755. int outset(cmd,cnt,inext,outext)
  1756. const char *cmd;
  1757. int  *cnt;
  1758. const char *inext, *outext;
  1759. {
  1760.  int retcode = NO;
  1761.  
  1762.  for (;;){
  1763.     if (pmatch(cmd,cnt,"Printer")){
  1764.        io.where |= io.mprint;
  1765.     }else if (pmatch(cmd,cnt,"Noprint")){
  1766.        io.where &= ~io.mprint;
  1767.     }else if (pmatch(cmd,cnt,"Basic")){
  1768.        io.formaat = FMTEXP;
  1769.     }else if (pmatch(cmd,cnt,"Cipher")){
  1770.        io.outcipher = io.pack = YES;
  1771.     }else if (pmatch(cmd,cnt,"Pack")){
  1772.        io.pack = YES;
  1773.     }else if (pmatch(cmd,cnt,"Quiet")){
  1774.        io.where &= ~io.mstdout;
  1775.     }else if (pmatch(cmd,cnt,"Echo") || pmatch(cmd,cnt,"List")){
  1776.        io.where |= io.mstdout;
  1777.     }else if (outext && pmatch(cmd,cnt,"SAve")){
  1778.        fn = file_open(cmd,cnt,outext,"w",fn);
  1779.        io.where |= 1<<fileno(fn);
  1780.     }else if (outext && pmatch(cmd,cnt,">")){
  1781.        char *access;
  1782.        access = (pmatch(cmd,cnt,">")) ? "a" : "w";
  1783.        fn = file_open(cmd,cnt,outext,access,fn);
  1784.        io.where |= 1<<fileno(fn);
  1785.        io.formaat = FMTEXP;
  1786.     }else if (inext && pmatch(cmd,cnt,"<")){
  1787.        io.whence = file_open(cmd,cnt,inext,"r",io.whence);
  1788.     }else{
  1789.        break;
  1790.     }
  1791.     retcode = YES;
  1792.  }
  1793.  return retcode;
  1794. }
  1795. /*--------------------------------------------------------------------------*/
  1796. /* file_open: a different interface for xopen
  1797.  */
  1798. static FILE *file_open(cmd,cnt,ext,access,fileptr)
  1799. const char *cmd, *ext, *access;
  1800. int  *cnt;
  1801. FILE *fileptr;
  1802. {
  1803.  xclose(&fileptr);
  1804.  fileptr = xopen(cmd,cnt,ext,access);
  1805.  if (!fileptr)
  1806.     error(bERROR, "");
  1807.  return fileptr;
  1808. }
  1809. /*--------------------------------------------------------------------------*/
  1810. /*--------------------------------------------------------------------------*/
  1811. SHAR_EOF
  1812. fi # end of overwriting check
  1813. if test -f 'src/outtext.c'
  1814. then
  1815.     echo shar: will not over-write existing file "'src/outtext.c'"
  1816. else
  1817. cat << \SHAR_EOF > 'src/outtext.c'
  1818. /* outtext  10/08/91
  1819.  * Copyright 1983-1992   Albert Davis
  1820.  * output text to files, devices, or whatever
  1821.  * m???? = multiple output to a bunch of io devices.
  1822.  *        with character count (so tab will work)
  1823.  * Will start a new line first if the entire output will not fit.
  1824.  * so wrap will not break a word or number.
  1825.  * Where is a bit mask of places to send the output.
  1826.  * A possible portability problem exists with the handle numbers.
  1827.  * It assumes they start at 0, and count up, and that there are no more than
  1828.  * the number of bits in an integer (MAXHANDLE).
  1829.  * but I have yet to find a system that did not meet this form.
  1830.  */
  1831. #include "ecah.h"
  1832. #include "io.h"
  1833. #include "options.h"
  1834. #include "declare.h"
  1835. /*--------------------------------------------------------------------------*/
  1836.     void mtab(int,int);
  1837.     void mprintf();
  1838.     void mputs(const char*,int);
  1839.     void mputc(int,int);
  1840. /*--------------------------------------------------------------------------*/
  1841. extern const struct ioctrl io;
  1842. extern const struct options opt;
  1843.  
  1844. int cpos[MAXHANDLE+1];                    /* character counter    */
  1845. FILE *stream[MAXHANDLE+1];                /* reverse of fileno()  */
  1846. /*--------------------------------------------------------------------------*/
  1847. /* mtab: tab to column "count" on output devices "where"
  1848.  * by outputting spaces.
  1849.  * If already beyond, start new line, then tab to column.
  1850.  */
  1851. void mtab(count,where)
  1852. int count;
  1853. int where;
  1854. {
  1855.  int ii,mm;
  1856.  for (ii=0, mm=1;   ii<=MAXHANDLE;   ++ii, mm<<=1){
  1857.     if (where & mm){
  1858.        if (cpos[ii] > count)
  1859.       mputc('\n',mm);
  1860.        while (cpos[ii]<count)
  1861.       mputc(' ',mm);
  1862.     }
  1863.  }
  1864. }
  1865. /*--------------------------------------------------------------------------*/
  1866. /* mprintf: multiple printf
  1867.  * printf to "m" style files.
  1868.  */
  1869. /*VARARGS2*/
  1870. void mprintf(where,fmt,va_alist)
  1871. int where;
  1872. const char *fmt;
  1873. va_dcl /* ; */
  1874. {
  1875.  char buffer[BIGBUFLEN];
  1876.  va_list arg_ptr;
  1877.  
  1878.  va_start(arg_ptr);
  1879.  vsprintf(buffer,fmt,arg_ptr);
  1880.  va_end(arg_ptr);
  1881.  
  1882.  mputs(buffer,where);
  1883. }
  1884. /*--------------------------------------------------------------------------*/
  1885. #ifdef ANSI                /* ANSI C varargs (stdarg.h)        */
  1886. void mprintf(where,fmt)
  1887. int where;
  1888. char *fmt;
  1889. {
  1890.  char buffer[BIGBUFLEN];
  1891.  va_list arg_ptr;
  1892.  
  1893.  va_start(arg_ptr,fmt);
  1894.  vsprintf(buffer,fmt,arg_ptr);
  1895.  va_end(arg_ptr);
  1896.  
  1897.  mputs(buffer,where);
  1898. }
  1899. #endif
  1900. /*--------------------------------------------------------------------------*/
  1901. /* mputs: multiple puts.
  1902.  * puts to "m" style files.
  1903.  * also....
  1904.  * starts new line, prefixes it with + if it would exceed width
  1905.  * width is handled separately for each file to support different widths
  1906.  * (which are not currently handled by .options)
  1907.  * and it is possible that current contents of lines may be different
  1908.  */
  1909. void mputs(str,where)
  1910. const char *str;
  1911. int where;
  1912. {
  1913.  int ii;    /* file counter */
  1914.  int mm;    /* file counter mask */
  1915.  int sl;    /* length of output string */
  1916.  int newline;    /* true if any destination is at beginning of line */
  1917.  
  1918.  newline = NO;
  1919.  sl = strlen(str);
  1920.  for (ii=0, mm=1;   ii<=MAXHANDLE;   ++ii, mm<<=1){
  1921.     if (where & mm   &&   (sl+cpos[ii]) > opt.outwidth){
  1922.        mputc('\n',mm);
  1923.        mputc('+',mm);
  1924.     }
  1925.     if (cpos[ii]==0)
  1926.        newline = YES;
  1927.  }
  1928.  if (io.outcipher && newline)
  1929.     mputc('\t',where);
  1930.  while (*str)
  1931.     mputc(*str++,where);
  1932. }
  1933. /*--------------------------------------------------------------------------*/
  1934. /* mputc: multiple putc
  1935.  * multiple putc
  1936.  * also....
  1937.  * crunch spaces, if selected
  1938.  * encripts, if selected
  1939.  * keeps track of character count
  1940.  */
  1941. void mputc(chr,where)
  1942. int chr;
  1943. int where;
  1944. {
  1945.  int ii,mm,suppress,count;
  1946.  static int old = '\0';
  1947.  static unsigned int  cchr = 'w';    /* starting encryption seed        */
  1948.                     /* arbitrary printable character    */
  1949.  if (chr=='\t'){
  1950.     chr = ' ';
  1951.     count = NO;
  1952.  }else{
  1953.     count = YES;
  1954.  }
  1955.  
  1956.  suppress = (io.pack && old==' ' && chr==' ');
  1957.  old = chr;
  1958.  if (io.outcipher && !suppress && isprint(chr)){
  1959.     cchr += (unsigned int)chr;
  1960.     while (!isascii(cchr)  ||  !isprint(cchr))
  1961.     cchr -= (0x7f-0x20);
  1962.     chr = (char)cchr;
  1963.  }
  1964.  
  1965.  for (ii=0, mm=1;   ii<=MAXHANDLE;   ++ii, mm<<=1)
  1966.     if (where & mm){
  1967.        if (chr=='\b'){
  1968.       --cpos[ii];
  1969.       (void)fflush(stream[ii]);
  1970.        }else if (count){
  1971.       ++cpos[ii];
  1972.        }
  1973.        if (chr=='\n'){
  1974.       cpos[ii] = 0;
  1975.       (void)fflush(stream[ii]);
  1976. #ifdef CRLF_FIX
  1977.       (void)fputc('\r',stream[ii]);
  1978. #endif
  1979.        }else if (chr=='\r'){
  1980.       if (cpos[ii] == 0){
  1981.          suppress = YES;
  1982.       }else{
  1983.          cpos[ii] = 0;
  1984.          (void)fflush(stream[ii]);
  1985.       }
  1986.        }
  1987.        if (!suppress)
  1988.       (void)fputc(chr,stream[ii]);
  1989.     }
  1990.  if (chr=='\n')
  1991.     ccck();
  1992. }
  1993. /*--------------------------------------------------------------------------*/
  1994. /*--------------------------------------------------------------------------*/
  1995. SHAR_EOF
  1996. fi # end of overwriting check
  1997. #    End of shell archive
  1998. exit 0
  1999.