/* SCMCRREF (CAP) -- SCM Sheet/Project Part/Label Cross Reference */ /* SCMCRREF (CAP) -- SCM-Blatt/-Projekt Bauteil-/Labelliste erstellen */ /* // Copyright (c) 1993-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (110909) ENHANCEMENT: // Added seperate open tag pin type section to output. // rl (110511) ENHANCEMENT: // Added $ulname attribute to output. // rl (101019) RELEASED FOR BAE V7.6. // rl (091021) RELEASED FOR BAE V7.4. // rl (090917) ENHANCEMENT: // Added open contact area pins to output. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (060322) ENHANCEMENT: // Added missing logical definitions to output. // rl (050906) RELEASED FOR BAE V6.6. // rl (050419) ENHANCEMENT: // Added attribute value list to output. // rl (040811) RELEASED FOR BAE V6.4. // rl (031126) ENHANCEMENT: // Added value column in symbol list. // rl (030904) RELEASED FOR BAE V6.2. // rl (030827) ENHANCEMENT: // Added bus tap list to cross reference. // 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 (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // mb (960919) RELEASED FOR BAE V3.4. // mb (960119) ENHANCEMENT: // Introduced option for selecting the cross reference element // type to be either current sheet, current project, or other // (selectable) project. Re-loading original plan element after // cross reference generation. Output format considerably // changed. // mb (951013) IMPROVEMENT: // Popup menu with (Output) option for cross reference // display used instead of file output. // mb (951013) ENHANCEMENT: // Cross reference sorted by sheet/part/label names. // Additional statistics (sheet/block/part/label) counts // provided. // mb (95) RELEASED FOR BAE V3.2. // mb (94) RELEASED FOR BAE V3.0. // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The scmcrref User Language program produces a part and label // cross reference listing for a selectable SCM sheet/project. // The cross reference listing is displayed in a popup menu with // file output option. */ // Includes #include "mnu.ulh" // User Language menu utilities #include "scm.ulh" // User Language SCM utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRABORT = M_UPRABORT(); string UPRSELPLN = M("SCM-Blatt/-Projekt fuer Cross Reference waehlen!", "Select SCM Sheet/Project for Cross Reference!"); string UPRCURSHT = M("Aktuelles &Blatt","Current &Sheet"); string UPRCURPLN = M("Aktuelles &Projekt","Current &Project"); string UPROTHPLN = M("A&nderes Projekt","&Other Project"); string UPRSELDDB = M("SCM-Jobdatei ? ","SCM Job File ? "); string UPRSORTMOD = M("Sortiermodus selektieren!","Select Sort Mode!"); string UPRSORTSYM = M("Sortieren &Symbole","Sort by &Symbols"); string UPRSORTPLN = M("Sortieren &Blaetter","Sort by S&heets"); string REPOWNTAG = M(" verweist auf eigenes Tagsymbol!", " references own tag symbol!"); string REPPTINVTAG = M("Unbekannter Tagtyp","Unknown Tag Type"); string REPPTSYMTAG = M("Symbol Tag","Symbol Tag"); string REPPTPINTAG = M("Pin Tag","Pin Tag"); string REPPTNETTAG = M("Netz Tag","Net Tag"); string REPPTNPNTAG = M("Netzpin Tag","Net Pin Tag"); string REPPTNARTAG = M("Netzbereich Tag","Net Area Tag"); string REPPTPARTAG = M("Bauteilbereich Tag","Part Area Tag"); string FMTCRRHD = M("SCM-Bauteil/Label-Cross-Referenz", "SCM Part/Label Cross Reference"); string FMTJOBNAM = M(" Projektdatei ......................: '%s'", " Project File .............: '%s'"); string FMTEVALMODE = M(" Auswertung ........................: %s", " Evaluated ................: %s"); string FMTSORTMODE = M(" Sortiert nach .....................: %s", " Sorted by ................: %s"); string FMTSHTCNT = M(" Anzahl Schaltplanblaetter .........: %d", " Top Level Sheet Count ....: %d"); string FMTBLKCNT = M(" Anzahl Hierachiebloecke ...........: %d", " Hierarchy Block Count ....: %d"); string FMTPRTCNT = M(" Gesamtanzahl Bauteile .............: %d", " Total Part Count .........: %d"); string FMTLABCNT = M(" Gesamtanzahl Labels ...............: %d", " Total Label Count ........: %d"); string FMTTAPCNT = M(" Gesamtanzahl Bustaps ..............: %d", " Total Bus Tap Count ......: %d"); string FMTOPINCNT = M(" Gesamtanzahl offene Kontaktbereiche: %d", " Total Open Contact Areas .: %d"); string FMTOTAGCNT = M(" Gesamtanzahl offene Tagsymbolpins..: %d", " Total Open Tag Sybmol Pins: %d"); string FMTANTCNT = M(" Gesamtanzahl Antennenhighlights ...: %d", " Total Antenna Highlights .: %d"); string FMTSHEETHD = M(" BLATTLISTE :"," SHEET LIST :"); string FMTPARTHD = M(" BAUTEILLISTE :"," PART LIST :"); string FMTLABHD = M(" LABELLISTE :"," LABEL LIST :"); string FMTTAPHD = M(" BUSTAPLISTE :"," BUS TAP LIST :"); string FMTOPINHD = M(" OFFENE KONTAKTBEREICHE LISTE :", " OPEN CONTACT AREA LIST :"); string FMTOTAGHD = M(" OFFENE TAGSYSMBOLPINS LISTE :", " OPEN TAG SYMBOL PIN LIST :"); string FMTANTHD = M(" SEGMENTE MIT ANTENNENHIGHLIGHT LISTE :", " SEGMENTS WITH ANTENNA HIGHLIGHT LIST :"); string FMTATTRHD = M(" ATTRIBUTLISTE :"," ATTRIBUTE LIST :"); string FMTATTRVAR = M("%s Var. %d","%s Var. %d"); string FMTMLOGHD = M(" FEHLENDE LOGISCHE DEFINITIONEN :", " MISSING LOGICAL DEFINITIONS :"); string ITMEVALPLN = M("Alle Blaetter","All Sheets"); string ITMEVALSHT = M("Nur aktuelles Blatt","Current Sheet Only"); string ITMSORTSYM = M("Bauteile/Labels","Parts/Labels"); string ITMSORTPLN = M("Blaetter","Sheets"); string ITMSHEET = M("Blatt","Sheet"); string ITMBLOCK = M("Block","Block"); string ITMASSP = M("Bauteilname","Part Name"); string ITMPART = M("Bauteil","Part"); string ITMSMAC = M("Symbol","Symbol"); string ITMSYMLAB = M("Symbol/Label","Symbol/Label"); string ITMSPIN = M("Pin","Pin"); string ITMATTR = M("Attribut","Attribute"); string ITMVAL = M("Wert","Value"); string ITMLNET = M("Netzname","Net Name"); string ITMLMAC = M("Label","Label"); string ITMTBUS = M("Busname","Bus Name"); string ITMTTAP = M("Bustapname","Bus Tap Name"); string ITMPCNT = M("Bauteilanzahl","Part Count"); string ITMLCNT = M("Labelanzahl","Label Count"); string ITMOPCNT = M("Anzahl offene Kontaktbereiche", "Open Contact Area Count"); string ITMOTCNT = M("Anzahl offene Tag Pins", "Open Tag Pin Count"); string ITMANCNT = M("Antennenanzahl","Antenna Count"); string ITMTCNT = M("Bustapanzahl","Bus Tap Count"); string ITMCNT = M("Anzahl","Count"); string ITMCOORD = M("Koordinaten","Coordinates"); string ITMTAGDST = M("Tagziel","Tag Destination"); #define FMTSENTRY " %-*s %-*s %*s %*s %*s %*s %*s %*s" #define FMTSHEADUL " %.*s %.*s %.*s %.*s %.*s %.*s %.*s %.*s" #define FMTHEADUL " %.*s %.*s %.*s %.*s %.*s" #define FMTPHEADUL " %.*s %.*s %.*s %.*s %.*s %.*s" #define FMTOHEADUL " %.*s %.*s %.*s %.*s" #define FMTTHEADUL " %.*s %.*s %.*s %.*s %.*s" #define FMTVHEADUL " %.*s %.*s %.*s" #define FMTPENTRY " %-*s %-*s %-*s %-*s %-*s %-*s" #define FMTLENTRY " %-*s %-*s %-*s %-*s %*d" #define FMTTENTRY " %-*s %-*s %-*s %-*s %*d" #define FMTXENTRY " %-*s %-*s %-*s" #define FMTOENTRY " %-*s %-*s %-*s %-*s" #define FMTTENTRY " %-*s %-*s %-*s %-*s %-*s" #define FMTVENTRY " %-*s %-*s %*d" #define FMTMENTRY " %s" #define FMTCOORD "%5.1fmm, %5.1fmm" #define ITMULINE "----------------------------------------" #define ITMDELIM "________________________________________________________" // INI file parameter name definitions #define PAR_ATRVAL1 "ATRVAL1_SCM" // First value attribute name #define PAR_ATRVAL2 "ATRVAL2_SCM" // Second value attribute name #define PAR_ATRVAL3 "ATRVAL3_SCM" // Third value attribute name // Maximum name lengths int SHEETML = strlen(ITMSHEET); int BLOCKML = strlen(ITMBLOCK); int ATTRML = strlen(ITMATTR); int VALML = strlen(ITMVAL); int SYMLABML = strlen(ITMSYMLAB); int CNTML = strlen(ITMCNT); int ANCNTML = strlen(ITMANCNT); int ASSPML = strlen(ITMASSP); int LNETML = strlen(ITMLNET); int TBUSML = strlen(ITMTBUS); int SPINML = strlen(ITMSPIN); int PARTML = strlen(ITMPART); int LMACML = strlen(ITMLMAC); int SMACML = strlen(ITMSMAC); int TTAPML = strlen(ITMTTAP); int LCNTML = strlen(ITMLCNT); int TCNTML = strlen(ITMTCNT); int PCNTML = strlen(ITMPCNT); int OPCNTML = strlen(ITMOPCNT); int OTCNTML = strlen(ITMOTCNT); int COORDML = strlen(ITMCOORD); int TAGDSTML = strlen(ITMTAGDST); // Globals int SORTBYPLAN = 1 /* Sort mode (sort by plan) */; static string ATRVAL1 = bae_inistrval(PAR_ATRVAL1,"$val") /* First value attribute name */; static string ATRVAL2 = bae_inistrval(PAR_ATRVAL2,"$wert") /* Second value attribute name */; static string ATRVAL3 = bae_inistrval(PAR_ATRVAL3,"$value") /* Third value attribute name */; struct partdes { // Part descriptor int sheetidx /* Sheet index */; string asspname /* Assigned part name */; string partname /* Part name */; string smacname /* Part symbol macro name */; string val /* Part value */; } pl[] /* Part list */; int pn = 0 /* Part count */; struct opindes { // Open pin descriptor int sheetidx /* Sheet index */; string symname /* Symbol name */; string pinname /* Symbol pin name */; string coord /* Symbol pin coordinates */; } opl[] /* Open pin list */; int opn = 0 /* Open pin count */; struct otagdes { // Open tag pin descriptor int sheetidx /* Sheet index */; string symname /* Symbol name */; string pinname /* Symbol pin name */; string coord /* Symbol pin coordinates */; string tagtyp /* Symbol pin tag type */; } otl[] /* Open tag pin list */; int otn = 0 /* Open tag pin count */; struct antdes { // Antenna descriptor int sheetidx /* Sheet index */; string netname /* Antenna net name */; string coord /* Antenna coordinates */; } anl[] /* Antenna list */; int ann = 0 /* Antenna count */; struct labdes { // Label descriptor int sheetidx /* Sheet index */; string lnetname /* Label net name */; string lmacname /* Label symbol macro name */; int lcnt /* Label count */; } ll[] /* Label list */; int ln = 0 /* Label count */; struct tapdes { // Label descriptor int sheetidx /* Sheet index */; string tbusname /* Bus tap bus name */; string ttapname /* Bus tap tap name */; int tcnt /* Bus tap count */; } tl[] /* Bus tap list */; int tn = 0 /* Bus tap count */; struct attrdes { // Attribute descriptor string name /* Attribute name */; string vall[] /* Attribute value list */; int valc[] /* Attribute value count list */; int valn /* Attribute value count */; } al[] /* Attribute list */; int an = 0 /* Attribute count */; STRINGS ldefl /* Missing logical definition list */; int ldefn = 0 /* Missing logical definition count */; struct sheetdes { // Sheet descriptor string sheetname /* Sheet name */; string blockname /* Sheet hierachical block name */; int pn /* Sheet part count */; int opn /* Sheet open pin count */; int otn /* Sheet open tag pin count */; int ann /* Sheet antenna count */; int ln /* Sheet label count */; int tn /* Sheet bus tap count */; } sheetl[] /* Sheet list */; int sheetn = 0 /* Sheet count */; int sheetidx /* Current sheet index */; int blockn = 0 /* Block count */; int totlabn = 0 /* Total label count */; int tottapn = 0 /* Total bus tap count */; int totopinn = 0 /* Total open pin count */; int tototagn = 0 /* Total open tag pin count */; int totantn = 0 /* Total antenna count */; STRINGS el /* Popup entry list */; int en /* Popup entry count */; index C_LEVEL conlevel /* Current connection level */; index C_FIGURE curfig /* Current figure list index */; double curx, cury /* Current pin coordinates */; double wsnx, wsny /* Workspace origin */; string filename = "" /* SCM plan file name */; string elemname /* Current top level element name */; string logfname = strgetvarfilename(scm_defloglname()) /* Logical library file name */; string busname /* Bus name */; string pinname /* Pin name */; // Main program void main() { int curclass /* Current class */; string curfn,curen /* Current file/element name */; string planname="" /* Current list name */; string evalmode /* Evaluation mode designator */; int i, j /* Loop control variables */; // Check if call inside function check_fctactive(); catext(logfname,DDBEXT); // Save current file/element name curfn=bae_planfname(); curen=bae_planename(); // Check if SCM plan loaded if ((curclass=bae_planddbclass())==DDBCLSCM) { // Check SCM plan type for cross reference bae_promptdialog(UPRSELPLN); switch (bae_askmenu(4, UPRCURSHT,UPRCURPLN,UPROTHPLN,UPRABORT)) { // Currently loaded sheet only case 0 : // Set plan file name to current filename=bae_planfname(); // Set plan element name to current planname=bae_planename(); break; // Current plan case 1 : // Set plan file name to current filename=bae_planfname(); break; // Selectable plan/project case 2 : // Postpone SCM plan file selection ! break; // Abort on default default : error_abort(); } } // Test if plan element name is already specified if (planname!="") { // Assume current SCM sheet cross reference request newsheet(); // Set the evaluation mode evalmode=ITMEVALSHT; } else { // Assume SCM plan cross reference request // Select SCM plan file if not yet specified if (filename=="" && (filename=askddbfile(UPRSELDDB,DDBCLSCM))=="") // Abort error_abort(); // Select the sort mode bae_promptdialog(UPRSORTMOD); if ((SORTBYPLAN=bae_askmenu(3, UPRSORTSYM,UPRSORTPLN,UPRABORT))<0 || SORTBYPLAN>1) error_abort(); // Save current element with verification on request verifysave(); // Get the SCM plan sheet list while (scanddbenames(filename,DDBCLSCM,planname)==1) { // Load the SCM sheet if (bae_planfname()==filename) bae_setintpar(22,1); loadddbelem(filename,planname,DDBCLSCM); // Generate new sheet entry newsheet(); } // Re-load the original element on request if (curclass!=DDBCLUNDEF && (curclass!=bae_planddbclass() || curfn!=bae_planfname() || curen!=bae_planename())) { bae_setintpar(22,2); bae_loadelem(curfn,curen,curclass); } // Set the evaluation mode evalmode=ITMEVALPLN; } // Build the cross reference header en=15; el[0]=FMTCRRHD; el[14]=el[1]=""; sprintf(el[2],FMTJOBNAM,filename); sprintf(el[3],FMTEVALMODE,evalmode); sprintf(el[4],FMTSORTMODE,SORTBYPLAN ? ITMSORTPLN : ITMSORTSYM); sprintf(el[5],FMTSHTCNT,sheetn); sprintf(el[6],FMTBLKCNT,blockn); sprintf(el[7],FMTPRTCNT,pn); sprintf(el[8],FMTLABCNT,totlabn); sprintf(el[9],FMTTAPCNT,tottapn); sprintf(el[10],FMTOPINCNT,totopinn); sprintf(el[11],FMTOTAGCNT,tototagn); sprintf(el[12],FMTANTCNT,totantn); el[13]=ITMDELIM; // Issue the sheet list header el[en++]=FMTSHEETHD; sprintf(el[en],FMTSENTRY,SHEETML,ITMSHEET,BLOCKML,ITMBLOCK, PCNTML,ITMPCNT,LCNTML,ITMLCNT,TCNTML,ITMTCNT,OPCNTML,ITMOPCNT, OTCNTML,ITMOTCNT,ANCNTML,ITMANCNT); en++; sprintf(el[en],FMTSHEADUL,SHEETML,ITMULINE,BLOCKML,ITMULINE,PCNTML, ITMULINE,LCNTML,ITMULINE,TCNTML,ITMULINE,OPCNTML,ITMULINE,OTCNTML, ITMULINE,ANCNTML,ITMULINE); en++; // Loop thru all sheets for (i=0;i>1; // Get the comparison result if ((compres=numstrcmp(blockname,sheetl[sidx].blockname))==0 && (compres=numstrcmp(sheetname,sheetl[sidx].sheetname))==0) // Sheet found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Update the part list sheet index references for (sidx=0;sidx=slb) pl[sidx].sheetidx++; // Update the label list sheet index references for (sidx=0;sidx=slb) ll[sidx].sheetidx++; // Update the bus tap list sheet index references for (sidx=0;sidx=slb) tl[sidx].sheetidx++; // Update the open pin list sheet index references for (sidx=0;sidx=slb) opl[sidx].sheetidx++; // Update the sheet list for (sidx=sheetn;sidx>slb;sidx--) sheetl[sidx]=sheetl[sidx-1]; // Insert sheet sheetl[slb].ln=sheetl[slb].pn=sheetl[slb].tn=sheetl[slb].opn=0; sheetl[slb].blockname=blockname; sheetl[slb].sheetname=sheetname; sheetn++; // Update the maximum sheet and block name lengths SHEETML=maxint(SHEETML,strlen(sheetname)); BLOCKML=maxint(BLOCKML,strlen(blockname)); // Return sheet index return(slb); } void newpart( int sheetidx,string asspname,string partname,string smacname,string val) /* // Store new part to sorted part list // Parameters : // int sheetidx : SCM sheet index // string asspname : Assigned part name // string partname : Part name // string smacname : Symbol macro name // string val : Symbol value */ { int slb = 0 /* Search lower boundary */; int sub = pn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int sheetcmp /* Sheet compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Get the compare result sheetcmp=sheetidx-pl[sidx].sheetidx; if ((compres=(SORTBYPLAN ? sheetcmp : 0))==0 && (compres=numstrcmp(asspname,pl[sidx].asspname))==0 && (compres=numstrcmp(partname,pl[sidx].partname))==0 && (compres=numstrcmp(smacname,pl[sidx].smacname))==0 && (compres=numstrcmp(val,pl[sidx].val))==0 && (compres=(SORTBYPLAN ? 0 : sheetcmp))==0) { // May not happen (internal error) // Anyway tolerate multiple part definition slb=sidx; break; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Insert part entry for (sidx=pn;sidx>slb;sidx--) pl[sidx]=pl[sidx-1]; // Insert part pl[slb].val=val; pl[slb].smacname=smacname; pl[slb].partname=partname; pl[slb].asspname=asspname; pl[slb].sheetidx=sheetidx; sheetl[sheetidx].pn++; pn++; // Update the maximum name lengths ASSPML=maxint(ASSPML,strlen(asspname)); PARTML=maxint(PARTML,strlen(partname)); SMACML=maxint(SMACML,strlen(smacname)); VALML=maxint(VALML,strlen(val)); } void newlabel(int sheetidx,string lnetname,string lmacname) /* // Store new label to sorted label list // Parameters : // int sheetidx : SCM sheet index // string lnetname : Label net name // string lmacname : Label macro name */ { int slb = 0 /* Search lower boundary */; int sub = ln-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int sheetcmp /* Sheet compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; sheetcmp=sheetidx-ll[sidx].sheetidx; if ((compres=(SORTBYPLAN ? sheetcmp : 0))==0 && (compres=numstrcmp(lnetname,ll[sidx].lnetname))==0 && (compres=numstrcmp(lmacname,ll[sidx].lmacname))==0 && (compres=(SORTBYPLAN ? 0 : sheetcmp))==0) { // Store label to sheet list ll[sidx].lcnt++; sheetl[sheetidx].ln++; totlabn++; // Done return; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Insert new label entry for (sidx=ln;sidx>slb;sidx--) ll[sidx]=ll[sidx-1]; // Insert label ll[slb].lcnt=1; ll[slb].lmacname=lmacname; ll[slb].lnetname=lnetname; ll[slb].sheetidx=sheetidx; sheetl[sheetidx].ln++; ln++; totlabn++; // Update the maximum name lengths LNETML=maxint(LNETML,strlen(lnetname)); LMACML=maxint(LMACML,strlen(lmacname)); } void newopin(int sheetidx,string symname,string pinname,string coord) /* // Store open pin to sorted open pin list // Parameters : // int sheetidx : SCM sheet index // string symname : Symbol name // string pinname : Symbol pin name // string coord : Coordinate string */ { int slb = 0 /* Search lower boundary */; int sub = opn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int sheetcmp /* Sheet compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; sheetcmp=sheetidx-opl[sidx].sheetidx; if ((compres=(SORTBYPLAN ? sheetcmp : 0))==0 && (compres=numstrcmp(symname,opl[sidx].symname))==0 && (compres=numstrcmp(pinname,opl[sidx].pinname))==0 && (compres=(SORTBYPLAN ? 0 : sheetcmp))==0) { slb=sidx; break; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Insert new open pin entry for (sidx=opn;sidx>slb;sidx--) opl[sidx]=opl[sidx-1]; // Insert label opl[slb].symname=symname; opl[slb].pinname=pinname; opl[slb].coord=coord; opl[slb].sheetidx=sheetidx; sheetl[sheetidx].opn++; opn++; totopinn++; // Update the maximum name lengths SYMLABML=maxint(SYMLABML,strlen(symname)); SPINML=maxint(SPINML,strlen(pinname)); COORDML=maxint(COORDML,strlen(coord)); } void newotag( int sheetidx,string symname,string pinname,string coord,string tagtyp) /* // Store open pin to sorted open pin list // Parameters : // int sheetidx : SCM sheet index // string symname : Symbol name // string pinname : Symbol pin name // string coord : Coordinate string // string tagtyp : Tag type string */ { int slb = 0 /* Search lower boundary */; int sub = otn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int sheetcmp /* Sheet compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; sheetcmp=sheetidx-otl[sidx].sheetidx; if ((compres=(SORTBYPLAN ? sheetcmp : 0))==0 && (compres=numstrcmp(symname,otl[sidx].symname))==0 && (compres=numstrcmp(pinname,otl[sidx].pinname))==0 && (compres=(SORTBYPLAN ? 0 : sheetcmp))==0) { slb=sidx; break; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Insert new open tag pin entry for (sidx=otn;sidx>slb;sidx--) otl[sidx]=otl[sidx-1]; // Insert label otl[slb].symname=symname; otl[slb].pinname=pinname; otl[slb].coord=coord; otl[slb].tagtyp=tagtyp; otl[slb].sheetidx=sheetidx; sheetl[sheetidx].otn++; otn++; tototagn++; // Update the maximum name lengths SYMLABML=maxint(SYMLABML,strlen(symname)); SPINML=maxint(SPINML,strlen(pinname)); COORDML=maxint(COORDML,strlen(coord)); TAGDSTML=maxint(TAGDSTML,strlen(tagtyp)); } void newantenna(int sheetidx,string netname,string coord) /* // Store antenna to sorted antenna list // Parameters : // int sheetidx : SCM sheet index // string netname : Net name // string coord : Coordinate string */ { int slb = 0 /* Search lower boundary */; int sub = ann-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int sheetcmp /* Sheet compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; sheetcmp=sheetidx-anl[sidx].sheetidx; if ((compres=(SORTBYPLAN ? sheetcmp : 0))==0 && (compres=numstrcmp(netname,anl[sidx].netname))==0 && (compres=(SORTBYPLAN ? 0 : sheetcmp))==0 && (compres=numstrcmp(coord,anl[sidx].coord))==0) { slb=sidx; break; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Insert new antenna entry for (sidx=ann;sidx>slb;sidx--) anl[sidx]=anl[sidx-1]; // Insert antenna anl[slb].sheetidx=sheetidx; anl[slb].netname=netname; anl[slb].coord=coord; sheetl[sheetidx].ann++; ann++; totantn++; // Update the maximum name lengths LNETML=maxint(LNETML,strlen(netname)); COORDML=maxint(COORDML,strlen(coord)); } void newbustap(int sheetidx,string tbusname,string ttapname) /* // Store new bustap to sorted bustap list // Parameters : // int sheetidx : SCM sheet index // string tbusname : Bus tap bus name // string ttapname : Bus tap tap name */ { int slb = 0 /* Search lower boundary */; int sub = tn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int sheetcmp /* Sheet compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; sheetcmp=sheetidx-tl[sidx].sheetidx; if ((compres=(SORTBYPLAN ? sheetcmp : 0))==0 && (compres=numstrcmp(tbusname,tl[sidx].tbusname))==0 && (compres=numstrcmp(ttapname,tl[sidx].ttapname))==0 && (compres=(SORTBYPLAN ? 0 : sheetcmp))==0) { // Store bus tap to sheet list tl[sidx].tcnt++; sheetl[sheetidx].tn++; tottapn++; // Done return; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Insert new bus tap entry for (sidx=tn;sidx>slb;sidx--) tl[sidx]=tl[sidx-1]; // Insert bus tap tl[slb].tcnt=1; tl[slb].tbusname=tbusname; tl[slb].ttapname=ttapname; tl[slb].sheetidx=sheetidx; sheetl[sheetidx].tn++; tn++; tottapn++; // Update the maximum name lengths TBUSML=maxint(TBUSML,strlen(tbusname)); TTAPML=maxint(TTAPML,strlen(ttapname)); } /*________________________________________________________________*/ // Bus scan functions int tapmac(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Bus 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 : return(0); // Label case DDBCLSLAB : // Check if requested level if (buslevel==conlevel) newbustap(sheetidx,busname,refname); return(0); } // Continue scan return(1); } int busmac(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Bus 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 : return(0); // Label case DDBCLSLAB : elemname=refname; break; case DDBCLSMRK : // Check if bus label pin if (refname!="" && level==conlevel) { // Store the bus name if (busname=="") busname=elemname; else busname=busname+","+elemname; } return(0); } // Continue scan return(1); } int contmac(index C_MACRO macro,index C_POOL pool, int macinws,string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Open pin 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 */ { // Abort scan for connected tag pins if (macro.CLASS==DDBCLSMRK && cap_mactaglink(0,0.0,0.0,0.0,0.0)==1) return(0); if (macro.CLASS==DDBCLSMRK) { pinname=refname; cap_maccoords(curx,cury,0.0,0); } // Continue scan return(1); } int contpoly(index C_POLY poly,int polyinws, index C_LEVEL level,int macclass,int bustapidx) /* // Contact area polygon scan function // Return value : // zero if done or (-1) on error // Parameters : // index C_POLY poly : Polygon index // int polyinws : Polygon in workspace flag // index C_LEVEL level : Polygon level // int macclass : Polygon macro class // int bustapidx : Polygon bus tap index */ { index C_MACRO macro /* Macro index */; string coord /* Coordinate string */; string tagtypstr /* Tag type string */; string tagpname /* Tag pin name */; int tagtyp /* Tag type */; int pinidx /* Tag pin index */; if (poly.TYP==C_POLYCONAREA && level.SEGFLAG==0) { macro=curfig.NREF.MACRO; sprintf(coord,FMTCOORD, cvtlength(curx-wsnx,0,2),cvtlength(cury-wsny,0,2)); if (macro.CLASS==DDBCLSSYM && macro.TAGSYM!=0) { tagtypstr=REPPTINVTAG; for (pinidx=0;cap_gettagdata(curfig, pinidx,tagtyp,tagpname,"","")==0;pinidx++) tagtypstr=tagtypename(tagtyp); newotag(sheetidx,curfig.NAME,pinname,coord,tagtypstr); } else { newopin(sheetidx,curfig.NAME, macro.CLASS==DDBCLSLAB ? "" : pinname,coord); } } // Return without errors return(0); } int antennacon(index C_CONBASE conbase,int segidx, int contyp,double lx,double ly,double ux,double uy, int busconflag,int coninws,index C_LEVEL level) /* // Antenna segment scan function // Return value : // zero if done or (-1) on error // index C_CONBASE conbase : Connection base // int segidx : Connection segment index // int contyp : Connection type // double lx : Left coordinate // double ly : Lower coordinate // double ux : Right coordinate // double uy : Upper coordinate // int busconflag : Connection bus flag // int coninws : Connection in workspace flag // index C_LEVEL level : Connection level */ { index C_CONSEG conseg /* Connection segment index */; index C_CNET cnet /* Connection net index */; string netname = "" /* Net name */; string coord /* Coordinate string */; int scanidx = 0 /* Scan index */; // Check if connection crosspoint or bus if (contyp==1 || busconflag) // Return without errors return(0); if (level.ERRFLAG) { // Search connection segment forall (conseg of conbase) { if (scanidx==segidx) { if ((conseg.ATTRIB&0xFF0000)==0 || (conseg.ATTRIB&0xFF00)==0) { forall (cnet of level) if (netname=="") netname=cnet.NAME; else netname+=","+cnet.NAME; sprintf(coord,FMTCOORD, cvtlength(0.5*(lx+ux)-wsnx,0,2), cvtlength(0.5*(ly+uy)-wsny,0,2)); newantenna(sheetidx,netname,coord); } } else if (scanidx>segidx) break; scanidx++; } } // Return without errors return(0); } void insattr(string name,string val) /* // Create an attribute list entry // Parameters : // string name : Attribute name // string val : Attribute value */ { int slb = 0 /* Search lower boundary */; int sub = an-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; int len /* String length */; int varnum /* Variant number */; int i, j /* Loop control variables */; // Check if internal attribute if (scm_chkattrname(name) && name!="$ulname") return; // Get attribute base name if (strmatch(name,"*\003*\003")) { len=strlen(name); varnum=atoi(strextract(name,len-3,len-1)); name[len-4]='\0'; sprintf(name,FMTATTRVAR,name,varnum); } // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Get the comparison result if ((compres=strcmp(name,al[sidx].name))==0) { // Attribute name found for (i=al[sidx].valn;i>0;i--) if ((compres= strcmp(val,al[sidx].vall[i-1]))==0) { al[sidx].valc[i-1]++; return; } else if (compres>0) { break; } // Insert new value for (j=al[sidx].valn;j>i;j--) { al[sidx].vall[j]=al[sidx].vall[j-1]; al[sidx].valc[j]=al[sidx].valc[j-1]; } al[sidx].vall[i]=val; al[sidx].valc[i]=1; al[sidx].valn++; // Update the maximum attribute name and value lengths ATTRML=maxint(ATTRML,strlen(name)); VALML=maxint(VALML,strlen(val)); return; } // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Update the attribute list for (sidx=an;sidx>slb;sidx--) al[sidx]=al[sidx-1]; // Insert name al[slb].name=name; al[slb].vall[0]=val; al[slb].valc[0]=1; al[slb].valn=1; an++; // Update the maximum attribute name and value lengths ATTRML=maxint(ATTRML,strlen(name)); VALML=maxint(VALML,strlen(val)); } void inslogdef(string name) /* // Create an logical definition list entry // Parameters : // string name : Logical definition name */ { int slb = 0 /* Search lower boundary */; int sub = ldefn-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=strcmp(name,ldefl[sidx]))==0) // Logical definition name found return; // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Update the logical definition list for (sidx=ldefn;sidx>slb;sidx--) ldefl[sidx]=ldefl[sidx-1]; // Insert name ldefl[slb]=name; ldefn++; } string tagtypename(int tagtyp) /* // Get tag type string // Return value : // Tag type string // Parameters : // int tagtyp : Tag type code */ { switch (tagtyp) { case SYPSYMTAG : return(REPPTSYMTAG); case SYPPINTAG : return(REPPTPINTAG); case SYPNETTAG : return(REPPTNETTAG); case SYPNPNTAG : return(REPPTNPNTAG); case SYPNARTAG : return(REPPTNARTAG); case SYPPARTAG : return(REPPTPARTAG); default : ; } return(REPPTINVTAG); } // User Language program end