#include <stdio.h>
#include <ctype.h>
#define maxsigs 200
/* define current signal of interest to be SG */
#define SG sigs[i]
#define foris for(i=0;i!=sindex;i++) 
#define fpf fprintf
#define deftimestep 1000.0

/* set up parser vars */
char cmt_start_ch      = '{',
     cmt_end_ch        = '}',
     line_cmt_ch       = '#',
     x_id_start_chs[]  = {'$','_','\0'},
     x_id_chs[]        = {'$','_','\0'},
     x_space_chs[]     = {':','@','-','=','\0'},
     op_chs[]          = {'+','*','/','\0'};
char *keys[] = {"output","I","O","Z","input","digitalpin","bidir","type"};
#include "procs6.h"

typedef enum {ntype,cnt,norm} stype;

int   sindex=0,vecnum=1;
struct sig  { char name[N_L],st,v,ov,dir,odir,cnt_name[N_L],out_at;
                                        } sigs[maxsigs];
struct sidx { int idx; stype st;} tlfx[1000+maxsigs];
/* if j is the tlf num sigs[sidx[j]].name is the sig name */
float time,timestep=deftimestep;
FILE *fo,*fs;


main(argc,argv)
int argc; char *argv[];
{int i,j;
 if (argc<2) error("USAGE: tlfvec <designname>  [-id]\n");
 if (arg_num(argc,argv,"-id")) {printf("Version JAN/29/89\n"); exit(0);}
 fin= efopen(cf(argv[1],".bnd"),"r");
 init();
 if (arg_num(argc,argv,"-stdout")) fo=stdout;
   else fo= fopen(cf(argv[1],".vec"),"w");
 if (arg_num(argc,argv,"-ts")&&arg_num(argc,argv,"-ts")<=argc)
  sscanf(argv[arg_num(argc,argv,"-ts")+1],"%f",&timestep);


/*-- Parse the bnd file and write the vec header -------------------*/

fpf(fo,"DEFPINS\n");

g_s();
while (!feof(fin))
{
 if (SNE(s,"pin") && SNE(s,"digitalpin"))
   error("keyword expected = pin or digitalpin");
 g_s();
 if (t!=integer) error("pin number expected");
 i=atoi(s);
 if (i>maxsigs || i<=0) error("invalid pin range");
 fpf(fo," PIN %d",i);
 g_s();
 if (SEQ(s,"Gnd")) fpf(fo," VSS;\n");
 else if(SEQ(s,"Vdd")) fpf(fo," VDD;\n");
 else
 { /* its not a power sig */
  if (t!=ident) error("Signal name expected");
  SCY(sigs[sindex].name,s);
  expect_sym("type");
  g_s(); g_s();
  if (s[0] != 'i' && s[0] != 'o' && s[0] != 'b')
   error("INPUT, OUTPUT, or BIDIR expected");
  sigs[sindex].st = uc(s[0]);
  fpf(fo," %s %c;\n",sigs[sindex].name,uc(s[0]));
  if(s[0]=='b') { g_s(); if(s[0]!='o') error("expected output");
                  g_s(); if(t!=ident) error("expected cnt signal");
                  SCY(sigs[sindex].cnt_name,s);
                  g_s(); if(t!=integer) error("expected bidir value");
                  sigs[sindex].out_at=s[0];
                }
  sindex++;
 }
 g_s();
} /* while */

fpf(fo,"END;\n\n");
fclose(fin);
/* finished parsing the .bnd file */
pr_header();

/*------- Parse the tlf header      ---------------------------------*/

fin=efopen(cf(argv[1],".tlf"),"r");
init();
g_s();
while (!feof(fin)&&SEQ(s,"S"))  /* get the header */
{ j=get_int();
  get_ident();
  i=sig_index(s); tlfx[j].idx=i;
  if(SEQ(s,SG.name)) tlfx[j].st=norm;
        else tlfx[j].st=cnt;
  g_s();
}

/*------- Init the pins            ----------------------------------*/

/* init values */
foris { SG.v='X'; SG.ov='-'; SG.dir='O'; SG.odir='-'; }

/*
 foris
   printf("%s %s %c %c %c \n",
          SG.name,SG.cnt_name,SG.st,SG.v,SG.dir);
*/
/*-------- Read and deal with vectors ------------------------------*/


while (!feof(fin))  /* deal with vector */
{
 g_s(); if(t!=real) error("time expected");
 sscanf(s,"%f",&time);
 if(time >= vecnum*timestep) {vecout(); vecnum++;}
 get_int();

 while(!feof(fin)&&t!=keyword)
 {if(t!=integer) error("Expected int");
  j=atoi(s);
  i=tlfx[j].idx; /* look up the sindex & make the SG abbr work */
  g_s();
  if(tlfx[j].st==norm) SG.v=s[0];
   else { /* its tri or bidir */
          if(SG.out_at==s[0]||s[0]=='X') SG.dir='O'; else SG.dir='I';}
  g_s();
 }

} /* END of vector while */

vecout(); /* output the last vector */
fprintf(stdout,"-I-  %d vectors \n",vecnum  );

} /* main */

/*------------------------------------------------------------------*/

vecout()    /* output the vector stored in sigs[] */
{ int i;
  foris
  { switch (SG.st)
    { case 'I': fpf(fo,"%c",iv(SG.v)); break;
      case 'O': fpf(fo,"%c",SG.v); break;
      case 'B': if(SG.dir=='I') fpf(fo,"%c",iv(SG.v));
                 else fpf(fo,"%c",SG.v);
                break;
    }
  }
  fpf(fo," {%d}\n",vecnum);
  /* copy old vals */
  foris { SG.ov = SG.v; SG.odir = SG.dir;}
}

/*------------------------------------------------------------------*/

pr_header()            /* print a commented signal name header */
{ int i=0,j=0,l=0;
  fpf(fo,"{\n");
  foris if(strlen(SG.name)>l) l=strlen(SG.name);
  l--;
  for(;j<=l;j++)
   { foris if(strlen(SG.name)>j)
       fpf(fo,"%c",SG.name[j]); else fpf(fo,"%c",' ');
     fpf(fo,"\n");
   }
  fpf(fo,"}\n");
}


iv(c)
char c;
{ if(c=='0') return('L'); if(c=='1') return('H'); return(c); }


/*------------------------------------------------------------------*/

sig_index(sg)   /* return the sigs[] index with name sg */
char *sg;
{ int i=0;
  while (i<sindex && SNE(SG.name,sg)&&SNE(SG.cnt_name,sg)) i++;
  if (i == sindex) {fpf(stderr,"tlf signal %s not found in bnd",sg);
                    error("Unknown signal in tlf"); }
  return(i);
}