/* LCIFIN (GED) -- Layout CIF Data Input */ /* LCIFIN (GED) -- Layout-CIF-Datenuebernahme */ /* // Copyright (c) 2000-2012 Oliver Bartels F+E, Muenchen // Author: Roman Ludwig // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) 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 (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (010625) RELEASED FOR BAE V5.0. // rl (010503) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000509) RELEASED FOR BAE V4.6. // rl (000111) ORIGINAL CODING. // // DESCRIPTION // // The lcifin User Language program reads CIF data // from a selectable ASCII file and automatically performs // a flat placement of the therein defined structures on the current // layout. The created elements are group selected. */ // Includes #include "pop.ulh" // User Language popup utilities // Disable undo state request #pragma ULCALLERNOUNDO // INI file parameter name definitions #define PAR_CIFEXT "CIFIEXT_LAY" // CIF input file name extension #define PAR_CIFICRDFAC "CIFICRDFAC_LAY"// CIF coordinate input scale // Messages string REPPARSE = M("Lesen CIF-Daten...", "Reading CIF data..."); string REPDONE = M("CIF-Daten eingelesen.","CIF data imported."); string UPRCIFFILE = M("CIF-Eingabe-Datei ? ", "CIF Data Input File ? "); string ERRPOLY = M("Fehler bei der Polygonerzeugung!\n", "Error generating polygon!\n"); string ERRPATH = M("Fehler bei der Leiterbahnerzeugung!\n", "Error generating path!\n"); // Global definitions and declarations double plannx = bae_planwsnx() /* Plan origin X coordinate */; double planny = bae_planwsny() /* Plan origin Y coordinate */; double lenconv = bae_inidblval(PAR_CIFICRDFAC,1.0/100000000.0) /* Length conv. fact. (def. 10 um) */; // Scanner variables string curstr /* Current string */; int curcard /* Current cardinal value */; int curlay /* Current layer number */; double curx /* Current X coordinate */; double cury /* Current Y coordinate */; double curw /* Current width */; double curxl[] /* Current X coordinate list */; double curyl[] /* Current Y coordinate list */; int curcn = 0 /* Current coordinate count */; double curflt /* Current float value */; int cursidx = (-1) /* Current symbol index */; int curridx /* Current reference index */; double currangsin /* Current reference angle sine */; double currangcos /* Current reference angle cosine */; int currxmirr /* Current reference x mirroring */; int currymirr /* Current reference y mirroring */; double currx /* Current reference x coordinate */; double curry /* Current reference y coordinate */; double currotx /* Current rotation x component */; double curbw /* Current box width */; double curbh /* Current box height */; double curbx /* Current box x coordinate */; double curby /* Current box y coordinate */; struct polydes { // Polygon descriptor double width /* Polygon width */; int lay /* Polygon layer */; int pn /* Polygon point count */; double pxl[] /* Polygon point x coord. list */; double pyl[] /* Polygon point y coord. list */; }; struct symdes { // Symbol descriptor int polyn /* Symbol polygon count */; struct polydes polyl[] /* Symbol polygon list */; } syml[] /* Symbol list */; // Part list declarations string CIFEXT = bae_inistrval(PAR_CIFEXT,".cif") /* CIF input file name ext. */; // Main program void main() { string fname /* Input file name */; // Abort if invalid plan class if (bae_planddbclass()!=DDBCLLAY && bae_planddbclass()!=DDBCLLPRT) error_class(); // Select the placement data file if (bae_askfilename(fname,CIFEXT,UPRCIFFILE) || fname=="") error_abort(); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Parse the placement file bae_prtdialog(REPPARSE); parsefile(fname); // Print done message bae_prtdialog(REPDONE); } /*________________________________________________________________*/ // Layout placement input data BNF syntax description #bnf { // CIF data BNF input syntax definition ciffile : cifcommandlist EOF ; cifcommandlist : cifcommand cifcommandlist | cifcommand ; cifcommand : "(" identlist ")" ";" | "DS" cardnumber (p_defstart) optdir ";" definitionlist "DF" ";" (p_defend) | definitionlist "E" ; definitionlist : definitionlist definition | definition ; definition : "L" alnumstr (p_setlay) ";" | "W" cifnumber (p_polystart(1)) coordinatelist (p_polyend) ";" | "P" (p_polystart(0)) coordinatelist (p_polyend) ";" | "B" cifnumber (p_boxwidth) cifnumber (p_boxheight) coordinate (p_boxorg) optdir (p_boxend) ";" | "C" cardnumber (p_refstart) optlist (p_refend) ";" | NUMBER identlist ";" ; coordinate : cifnumber (p_storex) cifnumber (p_storey) ; optdir : cifnumber cifnumber | ; coordinatelist : coordinatelistelem coordinatelist | coordinatelistelem ; coordinatelistelem : coordinate (p_storecoord) ; optlist : optlist option | option | ; option : "R" cifnumber (p_rotx) cifnumber (p_roty) | "MX" (p_mirrx) | "MY" (p_mirry) | "T" coordinate (p_refcoord) ; cifnumber : "-" NUMBER (p_cifnumber(1)) | NUMBER (p_cifnumber(0)) ; cardnumber : NUMBER (p_cardinal) ; identlist : identlist ident | ident | ; ident : IDENT | NUMBER | UNKNOWN ; alnumstr : IDENT (p_name) | NUMBER (p_name) ; } // BNF syntax definition end /*________________________________________________________________*/ // Scanner/parser functions void parsefile(string fn) /* // Parse an input file // Parameters : // string fn : File name */ { // Parser error messages STRINGS ERRS = { "", M("(synparsefile) Keine BNF-Definition verfuegbar!", "(synparsefile) No BNF definition available!"), M("(synparsefile) Parser ist bereits aktiv!", "(synparsefile) Parser already active!"), M("(synparsefile) Fehler beim Oeffnen der Datei '%s'!", "(synparsefile) Error opening file '%s'!"), M("(synparsefile) Zu viele offene Dateien!", "(synparsefile) Too many open files!"), M("[%s/%d] Fataler Lese-/Schreibfehler!", "[%s/%d] Fatal read/write error!"), M("[%s/%d] Scan Item '%s' zu lang!", "[%s/%d] Scan item '%s' too long!"), M("[%s/%d] Syntaxfehler bei '%s' (unerwartetes Symbol)!", "[%s/%d] Syntax error at '%s' (unexpected symbol)!"), M("[%s/%d] Dateiende erreicht!", "[%s/%d] Unexpected end of file!"), M("[%s/%d] Stackueberlauf (BNF zu komplex)!", "[%s/%d] Stack overflow (BNF too complex)!"), M("[%s/%d] Stackunterlauf (BNF fehlerhaft)!", "[%s/%d] Stack underflow (BNF erroneous)!"), M("[%s/%d] Fehler von Parser Aktion/Funktion!", "[%s/%d] Error from parse action function!"), M("(synparsefile) Unbekannter Fehlercode %d!", "(synparsefile) Unknown error code %d!") }; int status /* Parser status */; string msg /* Error message */; // Parse the input file and evaluate the parser status synscaneoln(0); if ((status=synparsefile(fn))==0) // No error return; if (status>=arylength(ERRS)) sprintf(msg,ERRS[arylength(ERRS)-1],status); else sprintf(msg,ERRS[status], fn,synscanline(),synscanstring()); // Print the error message error(msg); } // Parser action routines int p_defstart() /* // Receive a definition start // Return value : // zero if done or (-1) on error */ { // Set the current symbol index cursidx=curcard; // Return without errors return(0); } int p_defend() /* // Receive a definition end // Return value : // zero if done or (-1) on error */ { // Reset the current symbol index cursidx=(-1); // Return without errors return(0); } int p_storex() /* // Receive a X coordinate // Return value : // zero if done or (-1) on error */ { // Store the current X coordinate curx=curflt*lenconv; // Return without errors return(0); } int p_storey() /* // Receive a Y coordinate // Return value : // zero if done or (-1) on error */ { // Store the current Y coordinate cury=curflt*lenconv; // Return without errors return(0); } int p_storecoord() /* // Receive a coordinate pair // Return value : // zero if done or (-1) on error */ { // Store the coordinate pair to the list curxl[curcn]=curx; curyl[curcn]=cury; curcn++; // Return without errors return(0); } int p_boxwidth() /* // Receive a box width // Return value : // zero if done or (-1) on error */ { // Store the box width curbw=0.5*curflt*lenconv; // Return without errors return(0); } int p_boxheight() /* // Receive a box height // Return value : // zero if done or (-1) on error */ { // Store the box height curbh=0.5*curflt*lenconv; // Return without errors return(0); } int p_boxorg() /* // Receive a box origin coordinate pair // Return value : // zero if done or (-1) on error */ { // Store the box origin curbx=curx; curby=cury; // Return without errors return(0); } int p_boxend() /* // Receive a box end // Return value : // zero if done or (-1) on error */ { index L_FIGURE fig /* Figure list index */; int polyn /* Symbol polygon count */; // Check if top level box if (cursidx<0) { // Place the box polygon bae_clearpoints(); bae_storepoint(curbx-curbw+plannx,curby-curbh+planny,0); bae_storepoint(curbx+curbw+plannx,curby-curbh+planny,0); bae_storepoint(curbx+curbw+plannx,curby+curbh+planny,0); bae_storepoint(curbx-curbw+plannx,curby+curbh+planny,0); if (ged_storepoly(curlay,L_POLYCOPPASS,"",0)) error(ERRPOLY); if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); } else { // Store the box polygon to current symbol polyn=syml[cursidx].polyn; syml[cursidx].polyl[polyn].pxl[0]=curbx-curbw; syml[cursidx].polyl[polyn].pyl[0]=curby-curbh; syml[cursidx].polyl[polyn].pxl[1]=curbx+curbw; syml[cursidx].polyl[polyn].pyl[1]=curby-curbh; syml[cursidx].polyl[polyn].pxl[2]=curbx+curbw; syml[cursidx].polyl[polyn].pyl[2]=curby+curbh; syml[cursidx].polyl[polyn].pxl[3]=curbx-curbw; syml[cursidx].polyl[polyn].pyl[3]=curby+curbh; syml[cursidx].polyl[polyn].pn=4; syml[cursidx].polyl[polyn].lay=curlay; syml[cursidx].polyl[polyn].width=0.0; syml[cursidx].polyn++; } // Return without errors return(0); } int p_polystart(int wide) /* // Receive a polygon start // Return value : // zero if done or (-1) on error // Parameters : // int wide : Wide polygon flag */ { // Clear the coordinate list curcn=0; // Check if wide polygon if (wide) // Get the polygon width curw=curflt*lenconv; else curw=0.0; // Return without errors return(0); } int p_polyend() /* // Receive a polygon end // Return value : // zero if done or (-1) on error */ { index L_FIGURE fig /* Figure list index */; int polyn /* Symbol polygon count */; int i /* Loop control variable */; // Check if top level box if (cursidx<0) { // Place the polygon bae_clearpoints(); for (i=0;i0.0) { if (ged_storepath(curlay,curw)) error(ERRPATH); } else { if (ged_storepoly(curlay,L_POLYCOPPASS,"",0)) error(ERRPOLY); } if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); } else { // Store the polygon to current symbol polyn=syml[cursidx].polyn; for (i=0;i0.0) { if (ged_storepath(syml[curridx].polyl[i].lay, syml[curridx].polyl[i].width)) error(ERRPATH); } else { if (ged_storepoly(syml[curridx].polyl[i].lay, L_POLYCOPPASS,"",0)) error(ERRPOLY); } if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); } else { // Copy the ref. symbol polygons to current symbol pidx=syml[cursidx].polyn; syml[cursidx].polyl[pidx]=syml[curridx].polyl[i]; pointn=syml[cursidx].polyl[pidx].pn; for (j=0;j