/* SLABCHK (SCM) -- SCM Label Name Check */ /* SLABCHK (SCM) -- SCM Labelnamen ueberpruefen */ /* // Copyright (c) 1997-2012 Oliver Bartels F+E, Muenchen // Author: Roman Ludwig // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101027) RELEASED FOR BAE V7.6. // rl (091021) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (060109) ENHANCEMENT: // Added single label message disable support. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (040803) BUGFIX: // Fixed zoom problem for sheets with shifted origin. // rl (030904) RELEASED FOR BAE V6.2. // rl (030704) ENHANCEMENT: // Added coordinate display to label/bustap entries. // Added zoom to label/bustap option. // rl (030703) BUGFIX: // Added bus name to orphant bus tap recognition. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (010625) RELEASED FOR BAE V5.0. // rl (000509) RELEASED FOR BAE V4.6. // rl (990929) RELEASED FOR BAE V4.4. // rl (990929) ENHANCEMENT: // Added rudimentary bus tap check. // rl (980910) RELEASED FOR BAE V4.2. // mb (980711) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (971111) ORIGINAL CODING. // // DESCRIPTION // // The slabchk User Language program performs a SCM label name // check across all schematic sheets of a project. Unique label // names are reported as possible errors. */ // Includes #include "pop.ulh" // User Language popup utilities #include "scm.ulh" // User Language SCM utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string REPDONE = M("Es wurden keine Fehler festgestellt.", "No error occurred."); string REPHEADER = M("SCHALTPLAN EINZELLABELREPORT", "SCHEMATIC SINGLE LABEL REPORT"); string REPFILE = M("Datei ...: '%s'","File ....: '%s'"); string REPLWARN = M("Blatt %s, Label %s (%.1f mm, %.1f mm)", "Sheet %s, Label %s (%.1f mm, %.1f mm)"); string REPLDISP = M("Label %s, + naechstes, - vorheriges. Liste mit ", "Label %s, + next, - previous. for list."); string REPBWARN = M("Blatt %s, Bustap %s (%.1f mm, %.1f mm)", "Sheet %s, Bus Tap %s (%.1f mm, %.1f mm)"); string REPBDISP = M("Bustap %s, + naechstes, - vorheriges. Liste mit ", "Bustap %s, + next, - previous. for list."); string UPRSELFILE = M("SCM-Jobdatei ? ","SCM Job File ? "); // INI file parameter name definitions #define PAR_ZOOMEXP "LABZOOMEXP_SCM"// Label zoom expansion value // Parameters static double ZOOMEXP = bae_inidblval(PAR_ZOOMEXP,0.01) /* Label zoom window expansion */; // Globals struct labdes { // Label descriptor int cnt /* Label count */; int nameflag /* Label name flag */; string sname /* First occurence sheet name */; double sx,sy /* First occurence coordinates */; string lname /* Label name */; } labl[] /* Label list */; int labn = 0 /* Label count */; struct bustapdes { // Bus tap descriptor int cnt /* Bus tap count */; string sname /* First occurence sheet name */; double sx,sy /* First occurence coordinates */; string bname /* Bus tap name */; } bustapl[] /* Bus tap list */; int bustapn = 0 /* Bus tap count */; index C_LEVEL conlevel /* Current connection level */; double conlx,conly /* Current con. segment lower bound. */; double conux,conuy /* Current con. segment upper bound. */; int levfound /* Level found flag */; int elemtyp /* Current top level element class */; string elemname /* Current top level element name */; string busname /* Bus name */; // Main program void main() { index C_FIGURE fig /* Figure list index */; index C_NREF nref /* Named reference index */; index C_BUSTAP bustap /* Bus tap index */; STRINGS headl /* Menu header string list */; int headn /* Menu header string count */; STRINGS entryl /* Menu entry string list */; int entryn /* Menu entry string count */; int lidxl[] /* Label index list */; int lidx /* Label index */; string fname /* Current DDB file name */; string ename /* Current element name */; string errstring /* Error string */; string errdisp /* Error display string */; char c /* Character input buffer */; double x, y /* Label position */; double wsnx, wsny /* Workspace origin */; int labidx /* Label index */; int bustapidx /* Bus tap index */; int nameflag /* Label name flag */; int jobclass /* Current job DDB class */; string jobfname /* Current job file name */; string jobename /* Current job element name */; int blocktop /* Top block flag */; int i /* Loop control variable */; // Abort if not in Schematic Editor if (!(uliptype() & ULIPSCM)) error_class(); // Check if call inside function check_fctactive(); // Save current element with verification on request verifysave(); // Store the current plan designators jobclass=bae_planddbclass(); jobfname=bae_planfname(); jobename=bae_planename(); // Ask for DDB file name if ((fname=askddbfile(UPRSELFILE,DDBCLSCM))=="") error_abort(); // Loop for all plans ename=""; while (scanddbenames(fname,DDBCLSCM,ename)==1) { // Load the plan if not already in memory if (fname!=bae_planfname() || ename!=bae_planename()) { if (fname==bae_planfname()) bae_setintpar(22,1); loadddbelem(fname,ename,DDBCLSCM); } wsnx=bae_planwsnx(); wsny=bae_planwsny(); blocktop=cap_blocktopflag(); // Loop for all labels forall (fig where fig.TYP==C_FIGNREF) { nref=fig.NREF; if (nref.MACRO.CLASS!=DDBCLSLAB) continue; if (nref.NAME[0]=='?' && blocktop) continue; if (fig.RULEOBJID<0 || cap_rulequery(RS_OCFIG,fig,RS_SCMSUBJ,RS_NAMELABEL, "?d",nameflag)<1) if (cap_rulequery(RS_OCPOOL,nref.MACRO, RS_SCMSUBJ,RS_NAMELABEL,"?d",nameflag)<1) nameflag=0; // Get the label list index labidx= gclabel(nref.NAME,ename,nref.X-wsnx,nref.Y-wsny); // Increment the label count labl[labidx].cnt++; labl[labidx].nameflag|=nameflag; } // Loop for all bus taps forall (bustap) { // Get connection data conlx=bustap.SEG.X1; conly=bustap.SEG.Y1; conux=bustap.SEG.X2; conuy=bustap.SEG.Y2; // Scan bus connection level levfound=0; busname=""; if (cap_scanall(0.0,0.0,0.0,1,NULL,conlev,NULL,NULL)) error_scan(); // Check if level found if (levfound) { // Scan bus taps/connections if (cap_scanall( 0.0,0.0,0.0,1,tapmac,NULL,NULL,NULL)) error_scan(); if (busname[0]=='?' && blocktop) continue; if (busname=="") sprintf(busname,"%s:@%d.",ename, conlevel.IDNUM); else busname=busname+"."; } // Get the label list index bustapidx=gcbustap(busname+bustap.NAME,ename, bustap.X-wsnx,bustap.Y-wsny); // Increment the bus tap count bustapl[bustapidx].cnt++; } } // Reload the original element if (jobclass!=DDBCLUNDEF && (jobclass!=bae_planddbclass() || jobfname!=bae_planfname() || jobename!=bae_planename())) { bae_setintpar(22,2); bae_loadelem(jobfname,jobename,jobclass); } // Print the report header sprintf(headl[0],REPHEADER); sprintf(headl[2],REPFILE,fname); headn=4; entryn=0; // Loop for all labels for (i=0;i=entryn) i=0; } // Check if previous error request else if (c=='-') { i--; if (i<0) i=entryn-1; } else { break; } } break; } } } else // Print the done message bae_prtdialog(REPDONE); } // List management routines int gclabel(string labname,string sheetname,double x,double y) /* // Get or create a new label // Return value : // label index // Parameters : // string labname : Label name // string sheetname : Sheet name // double x,y : Label coordinates */ { int slb = 0 /* Search lower boundary */; int sub = labn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Get the comparison result if ((compres=numstrcmp(labname,labl[sidx].lname))==0) // Label found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Update the label list for (sidx=labn;sidx>slb;sidx--) labl[sidx]=labl[sidx-1]; // Insert sheet labl[slb].lname=labname; labl[slb].sname=sheetname; labl[slb].sx=x; labl[slb].sy=y; labl[slb].cnt=0; labl[slb].nameflag=0; labn++; // Return sheet index return(slb); } int gcbustap(string bustapname,string sheetname,double x,double y) /* // Get or create a new bus tap // Return value : // Bus tap index // Parameters : // string bustapname : Bus tap name // string sheetname : Sheet name // double x,y : Bus tap coordinates */ { int slb = 0 /* Search lower boundary */; int sub = bustapn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Get the comparison result if ((compres=numstrcmp(bustapname,bustapl[sidx].bname))==0) // Bus tap found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Update the bus tap list for (sidx=bustapn;sidx>slb;sidx--) bustapl[sidx]=bustapl[sidx-1]; // Insert sheet bustapl[slb].bname=bustapname; bustapl[slb].sname=sheetname; bustapl[slb].sx=x; bustapl[slb].sy=y; bustapl[slb].cnt=0; bustapn++; // Return sheet index return(slb); } int conlev(index C_CONBASE conbase,int segidx, int contyp,double lx,double ly,double ux,double uy, int busconflag,int coninws,index C_LEVEL level) /* // Get level of connection segment // Return value : // zero if done or (-1) on file error // Parameters : // index C_CONBASE conbase : Connection base // int segidx : Connection segment index // int contyp : Connection type // double lx : Lower X coordinate // double ly : Lower Y coordinate // double ux : Upper X coordinate // double uy : Upper Y coordinate // int busconflag : Connection bus flag // int coninws : Connection in workspace flag // index C_LEVEL level : Connection level */ { // Check if bus connection segment found if (busconflag && lx==conlx && ly==conly && ux==conux && uy==conuy) { // Store bus level levfound=1; conlevel=level; } // Return without errors return(0); } int tapmac(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Bust tap macro function // Return value : // 0 if out of workspace, 1 if inside, 2 if unknown, or (-1) on error // Parameters : // index C_MACRO macro : Macro index // index C_POOL pool : Macro pool index // int macinws : Macro in workspace flag // string refname : Macro reference name // index C_LEVEL level : Macro level // index C_LEVEL buslevel : Macro bus level */ { // Check the macro class switch (macro.CLASS) { // Symbol case DDBCLSSYM : elemtyp=DDBCLSSYM; elemname=refname; break; // Label case DDBCLSLAB : elemtyp=DDBCLSLAB; elemname=refname; break; case DDBCLSMRK : // Check if bus label pin if (refname!="" && level==conlevel) if (elemtyp==DDBCLSLAB) { // Store the bus name if (busname=="") busname=elemname; else busname=busname+","+elemname; } return(0); } // Continue scan return(1); } // User Language program end