📄 spicenum.c
字号:
stripsomespace(s, nostripping); modernizeex(s); /* required for stripbraces count */ scopy(u,""); If s[0]=='.' Then /* check Pspice parameter format */ scopy(t,s); stupcase(t); k=1; While t[k]>' ' Do cadd(u, t[k]); Inc(k) Done If spos(".PARAM",t) ==1 Then /* comment it out */ s[0]='*'; category='P'; ElsIf spos(".SUBCKT",t) ==1 Then /* split off any "params" tail */ a= spos("PARAMS:",t); If a>0 Then pscopy(s,s,1,a-1); EndIf category='S'; ElsIf spos(".CONTROL",t) ==1 Then category='C' ElsIf spos(".ENDC",t) ==1 Then category='E' ElsIf spos(".ENDS",t) ==1 Then category='U' Else category='.'; n= stripbraces(s); If n>0 Then category='B' EndIf /* priority category ! */ EndIf ElsIf s[0]==Intro Then /* private style preprocessor line */ s[0]='*'; category='P'; ElsIf upcase(s[0])=='X' Then /* strip actual parameters */ i=findsubname(dico, s); /* i= index following last identifier in s *//* pscopy(s,s,1,i); sjb - this is already done by findsubname() */ category='X' ElsIf s[0]=='+' Then /* continuation line */ category='+' ElsIf cpos(s[0],"*$#")<=0 Then /* not a comment line! */ n= stripbraces(s); If n>0 Then category='B' /* line that uses braces */ Else category=' ' EndIf; /* ordinary code line*/ Else category='*' EndIf return categoryEndFunc /************ core of numparam **************//* some day, all these nasty globals will go into the tdico structure and everything will get hidden behind some "handle" ...*/Intern int linecount= 0; /* global: number of lines received via nupa_copy */Intern int evalcount= 0; /* number of lines through nupa_eval() */ Intern int nblog=0; /* serial number of (debug) logfile */Intern Bool inexpansion= False; /* flag subckt expansion phase */Intern Bool incontrol= False; /* flag control code sections */Intern Bool dologfile= True; /* for debugging */Intern Bool firstsignal=True;Intern Pfile logfile= Null;Intern tdico * dico=Null;/* already part of dico : *//* Str(80, srcfile); source file *//* Darray(refptr, Pchar, Maxline) pointers to source code lines *//* Darray(category, char, Maxline) category of each line *//* Open ouput to a log file. takes no action if logging is disabled. Open the log if not already open.*/InternProc putlogfile(char c, int num, Pchar t)Begin Strbig(Llen, u); Str(20,fname); If dologfile Then If(logfile == Null) Then scopy(fname,"logfile."); Inc(nblog); nadd(fname,nblog); logfile=fopen(fname, "w"); EndIf If(logfile != Null) Then cadd(u,c); nadd(u,num); cadd(u,':'); cadd(u,' '); sadd(u,t); cadd(u,'\n'); fputs(u,logfile); EndIf EndIfEndProcInternProc nupa_init( Pchar srcfile)Begin short i; /* init the symbol table and so on, before the first nupa_copy. */ evalcount=0; linecount= 0; incontrol=False; placeholder= 0; dico= New(tdico); initdico(dico); For i=0; i<Maxline; Inc(i) Do dico->refptr[i]= Null; dico->category[i]='?'; Done Sini(dico->srcfile); If srcfile != Null Then scopy(dico->srcfile, srcfile) EndIfEndProcInternProc nupa_done(void)Begin short i; Str(80,rep); short dictsize, nerrors; If logfile != Null Then fclose(logfile); logfile=Null; EndIf nerrors= dico->errcount; dictsize= donedico(dico); For i=Maxline-1; i>=0; Dec(i) Do Dispose( dico->refptr[i]) Done Dispose(dico); dico= Null; If NotZ(nerrors) Then /* debug: ask if spice run really wanted */ scopy(rep," Copies="); nadd(rep,linecount); sadd(rep," Evals="); nadd(rep,evalcount); sadd(rep," Placeholders="); nadd(rep,placeholder); sadd(rep," Symbols="); nadd(rep,dictsize); sadd(rep," Errors="); nadd(rep,nerrors); cadd(rep,'\n'); ws(rep); ws("Numparam expansion errors: Run Spice anyway? y/n ? \n"); rs(rep); If upcase(rep[0]) != 'Y' Then exit(-1) EndIf EndIf linecount= 0; evalcount= 0; placeholder= 0; /* release symbol table data */EndProc /* SJB - Scan the line for subcircuits */Proc nupa_scan(Pchar s, int linenum)Begin If spos(".SUBCKT",s) ==1 Then defsubckt( dico, s, linenum, 'U' ); EndIfEndProcFunc Pchar nupa_copy(Pchar s, int linenum)/* returns a copy (not quite) of s in freshly allocated memory. linenum, for info only, is the source line number. origin pointer s is kept, memory is freed later in nupa_done. must abort all Spice if malloc() fails. Is called for the first time sequentially for all spice deck lines. Is then called again for all X invocation lines, top-down for subckts defined at the outer level, but bottom-up for local subcircuit expansion, but has no effect in that phase. we steal a copy of the source line pointer. - comment-out a .param or & line - substitute placeholders for all {..} --> 10-digit numeric values.*/Begin Strbig(Llen,u); Strbig(Llen,keywd); Pchar t; short i,ls; char c,d; ls= length(s); While (ls>0) And (s[ls-1]<=' ') Do Dec(ls) Done pscopy(u,s, 1,ls); /* strip trailing space, CrLf and so on */ dico->srcline= linenum; If (Not inexpansion) And (linenum >=0) And (linenum<Maxline) Then Inc(linecount); dico->refptr[linenum]= s; c= transform(dico, u, incontrol, keywd); If c=='C' Then incontrol=True ElsIf c=='E' Then incontrol=False EndIf If incontrol Then c='C' EndIf /* force it */ d= dico->category[linenum]; /* warning if already some strategic line! */ If (d=='P') Or (d=='S') Or (d=='X') Then fputs(" Numparam warning: overwriting P,S or X line.\n",stderr); EndIf If c=='S' Then defsubckt( dico, s, linenum, 'U' ) ElsIf steq(keywd,"MODEL") Then defsubckt( dico, s, linenum, 'O' ) EndIf; /* feed symbol table */ dico->category[linenum]= c; EndIf /* keep a local copy and mangle the string */ ls=length(u); t= NewArr( char, ls+1); /* == (Pchar)malloc(ls+1); */ If t==NULL Then fputs("Fatal: String malloc crash in nupa_copy()\n", stderr); exit(-1) Else For i=0;i<=ls; Inc(i) Do t[i]=u[i] Done If Not inexpansion Then putlogfile(dico->category[linenum],linenum,t) EndIf; EndIf return tEndFuncFunc int nupa_eval(Pchar s, int linenum)/* s points to a partially transformed line. compute variables if linenum points to a & or .param line. If the original is an X line, compute actual params. Else substitute any &(expr) with the current values. All the X lines are preserved (commented out) in the expanded circuit.*/Begin short idef; /* subckt definition line */ char c; Str(80,subname); dico->srcline= linenum; c= dico->category[linenum];#ifdef TRACE_NUMPARAMS printf("** SJB - in nupa_eval()\n"); printf("** SJB - processing line %3d: %s\n",linenum,s); printf("** SJB - category '%c'\n",c);#endif /* TRACE_NUMPARAMS */ If c=='P' Then /* evaluate parameters */ nupa_assignment( dico, dico->refptr[linenum] , 'N'); ElsIf c=='B' Then /* substitute braces line */ nupa_substitute( dico, dico->refptr[linenum], s, False); ElsIf c=='X' Then /* compute args of subcircuit, if required */ idef = findsubckt( dico, s, subname); If idef>0 Then nupa_subcktcall( dico, dico->refptr[idef], dico->refptr[linenum], False); Else putlogfile('?',linenum, " illegal subckt call."); EndIf ElsIf c=='U' Then /* release local symbols = parameters */ nupa_subcktexit( dico); EndIf putlogfile('e',linenum,s); Inc(evalcount);#ifdef TRACE_NUMPARAMS ws("** SJB - --> "); ws(s); wln(); ws("** SJB - leaving nupa_eval()"); wln(); wln();#endif /* TRACE_NUMPARAMS */ return 1EndFuncFunc int nupa_signal(int sig, Pchar info)/* warning: deckcopy may come inside a recursion ! substart no! *//* info is context-dependent string data */Begin putlogfile('!',sig, " Nupa Signal"); If sig == NUPADECKCOPY Then If firstsignal Then nupa_init(info); firstsignal=False; EndIf ElsIf sig == NUPASUBSTART Then inexpansion=True ElsIf sig == NUPASUBDONE Then inexpansion=False ElsIf sig == NUPAEVALDONE Then nupa_done(); firstsignal=True EndIf return 1EndFunc#ifdef USING_NUPATEST/* This is use only by the nupatest program */Func tdico * nupa_fetchinstance(void)Begin return dicoEndFunc#endif /* USING_NUPATEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -