/* LOGLEDIT (SCM) -- Loglib Editor Functions */ /* LOGLEDIT (SCM) -- Loglib-Editor-Funktionen */ /* // 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 (100113) ENHANCEMENT: // Adjusted line wrap to at least edit box width. // rl (091021) RELEASED FOR BAE V7.4. // rl (081205) ENHANCEMENT: // Added manual launch button. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (070601) ENHANCEMENT: // Added alternate part macro edit box. // Improved virtual symbol handling. // rl (070112) BUGFIX: // Fixed problem with graphic edit plan reload. // rl (060829) RELEASED FOR BAE V6.8. // rl (051031) ENHANCEMENT: // Added automatic xlat for single pin symbols. // rl (050906) RELEASED FOR BAE V6.6. // rl (050530) ENHANCEMENT: // Added table pin assignment. // rl (050527) ENHANCEMENT: // Added graphical pin assignment. // rl (050218) ENHANCEMENT: // Added automatic newattr commands insertion. // rl (041216) ENHANCEMENT: // Added automatic default statement for symbols with $plname. // rl (040811) RELEASED FOR BAE V6.4. // rl (040216) ENHANCEMENT: // Added layout part macro selection for new definitions. // Added layout part pin list comment for new definitions. // Added layout part macro load in HighEnd. // rl (030904) RELEASED FOR BAE V6.2. // rl (030226) ENHANCEMENT: // Added $rlext support for picked references. // Fixed problem with uppercase $rlname definition. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (020206) BUGFIX: // Fixed problem with empty $rlname definition. // rl (010928) ENHANCEMENT: // Added $rlname query for picked references. // rl (010625) RELEASED FOR BAE V5.0. // rl (010423) BUGFIX: // Fixed problem with library file name extension. // rl (010409) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000713) RELEASED FOR BAE V4.6. // rl (000504) ORIGINAL CODING. // // DESCRIPTION // // The logledit User Language program provides the ability to // edit and compile loglib data. // If the currently loaded element is a schematic symbol the // loglib definition for this symbol will be created/edited. // If the currently loaded element is a schematic plan the // user can select a symbol on the plan. // For other element classes the element must be specified/selected in // a selection list box. */ // Includes #include "pop.ulh" // User Language popup utilities #include "baeparam.ulh" // User Language BAE param. access #include "scm.ulh" // User Language SCM utilities #include "sql.ulh" // User Language SQL utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRABORT = M_UPRABORT(); string REPDONE = M("Es wurden keine Fehler festgestellt.", "Operation completed without errors."); string UPRPICKSYM = M("Symbol selektieren!","Select Symbol"); string UPRDEST = M("Zieldatei selektieren!", "Select destination file!"); string UPRDEFLIB = M("&Defaultbibliothek","&Default library"); string UPRJOB = M("&Jobdatei","&Job file"); string UPROTHER = M("&Andere Datei","&Other file"); string UPREDIT = M("!Neue Loglib-Definition", "!New Loglib Definition"); string UPRDEDIT = M("Loglib-Definition zu Symbol '%s'", "Loglib Definition of Symbol '%s'"); string UPRDEDITD = M("Loglib-Definition '%s' zu Symbol '%s'", "Loglib Definition '%s' of Symbol '%s'"); string UPRDFILE = M("!Zieldateiname ? ","!Destination File Name ? "); string UPRLFILE = M("Quelldateiname ? ","Source File Name ? "); string UPRMACLIST = M("Gehaeuse","Macro(s)"); string UPRDOCU = M("Doku","Help"); string UPRSAMPLE = M("Beispiele :","Examples :"); string UPRPINASS = M("Pinzuordnungen :","Pin Assignments :"); string UPRPINASSN = M("Pinzuordnungen '%s'","Pin Assignments '%s'"); string UPRPINASSS = M(":",":"); string UPRNEXTDIAL = M("&>","&>"); string UPRPREVDIAL = M("&<","&<"); string UPRIMPASS = M("&Import","&Import"); string UPRTABASS = M("&Tabelle","&Table"); string UPRGRLASS = M("Grafisch mit &Linien","Graphically with &Lines"); string UPRGRTASS = M("Grafisch mit &Texten","Graphically with &Texts"); string UPRASSFILE = M("Pinzuordnungsdatei ? ","Pin Assignment File ? "); string UPROFILE = M("Definition '%s' in anderer Datei suchen ?", "Search definition '%s' in other file ?"); string UPRNFILE = M("Definition '%s' nicht gefunden! In anderer Datei suchen ?", "Definition '%s' not found. Search in other file ?"); string UPRNPFILE = M("Layoutbauteil '%s' nicht gefunden! (Anderes) Bauteil suchen ?", "Layout part '%s' not found. Search (other) part ?"); string UPRECONT = M("Fehler bei der Kompilierung!", "Error compiling definition!"); string UPRWCONT = M("Warnung(en) bei der Kompilierung!", "Warning(s) compiling definition!"); string UPRPRTPROJ = M("Bauteilmakros in Projektdatei :", "Part Macros in Project File :"); string UPRPRTDB = M("Bauteilmakros in Bibliothek '%s' :", "Library Part Macros '%s' :"); string UPRPATTERN = M("Muster anwenden :","Apply Pattern :"); string UPRPATTERNA = M("Alle","All"); string UPRPATTDOC = M("z.B. *16 oder dil*","e.g. *16 or dil*"); string UPRLIST = M("Liste","List"); string UPRVIRTUAL = M("virtual","virtual"); string UPRNEWPRT = M("Layoutbauteilmakro in '%s' ?", "Layout Part Macro in '%s' ?"); string UPRDNEWPRT = M("Layoutbauteilmakro :","Layout Part Macro :"); string UPRDNEWPRTL = M("Layoutbauteilmakro(s) :","Layout Part Macro(s) :"); string UPRNEWPRTD = M("Layoutbauteilmakro zu Symbol '%s' Definition '%s'", "Layout Part Macro of Symbol '%s' Definition '%s'"); string UPRGATECNT = M("Anzahl Gatter ? ","Gate Count ? "); string UPRTXTLEFT = M("Zum Speichern hier links klicken", "Left click here to finish"); string UPRATXTLEFT = M("Zum Abbrechen hier links klicken", "Left click here to abort"); string UPRTXTRIGHT = M("Zum Speichern hier rechts klicken", "Right click here to finish"); string UPRATXTRIGHT = M("Zum Abbrechen hier rechts klicken", "Right click here to abort"); string UPRLPINCNT = M("Layoutbauteil '%s' hat zu wenig Pins fuer Zuordnung. Abbrechen?", "Layout part '%s' has not enough pins for assignment. Abort?"); string REPSPPARTF = M("part r : s0805 - Bauteil mit fester Bauformzuordnung", "part r : s0805 - Part with fixed part macro assignment"); string REPSPPARTD = M("part r : default s0805 - Bauteil mit $plname-aenderbarer Bauformzuordnung", "part r : default s0805 - Part with $plname changeable part macro assignment"); string REPSPPARTA = M("part r : s0805,s1206 - Bauteil mit Alternativbauformliste", "part r : s0805,s1206 - Part with alternate part macro list"); string REPSPPARTM = M("part op : mainpart so8 - mainpart-Definition", "part op : mainpart so8 - mainpart definition"); string REPSPPARTS = M("part op_supply : subpart op - subpart-Definition", "part op_supply : subpart op - subpart definition"); string REPSPPARTV = M("part header : virtual - virtual-Definition", "part header : virtual - virtual definition"); string REPSPPARTC = M("part d : class diode s0805 - Bauteil mit Klassenangabe", "part d : class diode s0805 - Part with class specification"); string REPSPPARTMC = M("part lm324 : class op mainpart so8 - mainpart mit Klassenangabe", "part lm324 : class op mainpart so8 - mainpart with class specification"); string REPSPPINS = M("pin(a,b,y); - Symbolpinauflistung", "pin(a,b,y); - Symbol pin list"); string REPSPBUSSES = M("bus(data); - Buspinauflistung", "bus(data); - Bus pin list"); string REPSPXLATG = M("xlat (a,b,y) to (1,2,3) or (4,5,6); - Symbolpinzuordnung gatterweise", "xlat (a,b,y) to (1,2,3) or (4,5,6); - Symbol pin assignment"); string REPSPXLATP = M("xlat ((a,1,4),(b,2,5),(y,3,6)); - Symbolpinzuordnung pinweise", "xlat ((a,1,4),(b,2,5),(y,3,6)); - Symbol pin assignment"); string REPSPXLATB = M("xlat (data.d0,data.d1,data.d2) to (7,8,9); - Buspinzuordnung", "xlat (data.d0,data.d1,data.d2) to (7,8,9); - Bus pin assignment"); string REPSPPARTATT = M("newattr \"$manufacturer\" = \"Bartels\"; - Bauteilattributzuweisung", "newattr \"$manufacturer\" = \"Bartels\"; - Part attribute assignment"); string REPSPPARTUATT = M("newattr \"$val\" = \"!unique!\"; - Nur Symbole mit gleichem Wert zusammenpacken", "newattr \"$val\" = \"!unique!\"; - Package only same value symbols to one part"); string REPSPPINATT = M("newattr \"$pintype\" = \"out\" to (3,6); - Attributzuweisung an "+"Layoutbauteilpins", "newattr \"$pintype\" = \"out\" to (3,6); - Layout part pin attribute assignment"); string REPSPPINTYP = M(" Pintypen: \"in\",\"out\",\"bidi\",\"anl\",\"sup\"", " Pin types: \"in\",\"out\",\"bidi\",\"anl\",\"sup\""); string REPSPNETASS = M("net \"gnd\" : (10); - Layoutbauteilpin Festnetzzuweisung", "net \"gnd\" : (10); - Layout part pin net assignment"); string REPSPNETAASS = M("net \"$gnd\" : (10); - Layoutbauteilpin Attributnetzzuweisung", "net \"$gnd\" : (10); - Layout part pin attribute net assignment"); string REPSPNETINT = M("net internal : (10,11); - Layoutbauteilpins verbinden", "net internal : (10,11); - Connect layout part pins"); string REPSPSWAPG = M("swap ((1,2,3),(4,5,6); - Gattertausch = swap (((1),(2),(3)),((4),(5),(6)))", "swap ((1,2,3),(4,5,6); - Gate swap = swap(((1),(2),(3)),((4),(5),(6)))"); string REPSPSWAPP = M("swap (((1,2))); - Pintausch", "swap (((1,2))); - Pin swap"); string REPSPSWAPGP = M("swap (((1,2),3),((4,5),6)); - Pin-/Gattertausch", "swap (((1,2),3),((4,5),6)); - Pin/gate swap/"); string REPSPSWAPPI = M("swap internal (((1,2))); - Auf Bauteil beschraenkter swap", "swap internal (((1,2))); - Part restricted swap"); string REPSPNETATTD = M("netattr mindist \"$val\" : (x); - Netzmindestabstand aus Attribut ableiten", "netattr mindist \"$val\" : (x); - Derive net min. distance from attribute"); string REPSPNETATTDF = M("netattr mindist \"0.5\" : (x); - Netzmindestabstand fest vorgeben", "netattr mindist \"0.5\" : (x); - Set net min. distance to given value"); string REPSPNETATTP = M("netattr priority \"$val\" : (x); - Netzprioritaet aus Attribut ableiten", "netattr priority \"$val\" : (x); - Derive net priority from attribute"); string REPSPNETATTPF = M("netattr priority \"5\" : (x); - Netzprioritaet fest vorgeben", "netattr priority \"5\" : (x); - Set net priority to given value"); string REPSPNETATTW = M("netattr routwidth \"$val\" : (x); - Netzroutingbreite aus Attribut ableiten", "netattr routwidth \"$val\" : (x); - Derive net route width from attribute"); string REPSPNETATTWF = M("netattr routwidth \"0.5\" : (x); - Netzroutingbreite fest vorgeben", "netattr routwidth \"0.5\" : (x); - Set net route width to given value"); string REPSPNETATTV = M("netattr powwidth \"$val\" : (x); - Netzversorgungsbreite aus Attribut ableiten", "netattr powwidth \"$val\" : (x); - Derive net power route width from attribute"); string REPSPNETATTVF = M("netattr powwidth \"0.5\" : (x); - Netzversorgungsbreite fest vorgeben", "netattr powwidth \"0.5\" : (x); - Set net power route width to given value"); string REPSPNETATTA = M("netattr \"$nettype\" \"$nettype\" : (x); - Beliebiges Netzattribut setzen", "netattr \"$nettype\" \"$nettype\" : (x); - Set net attribute"); string REPSPNETATTF = M("netattr \"$nettype\" \"a\" : (x); - Beliebiges Netzattribut fest vorgeben", "netattr \"$nettype\" \"a\" : (x); - Set net attribute to given value"); string REPSPBLOCK = M("call blockname; - Referenz auf hierarchische Schaltplanbloecke", "call blockname; - Reference to hierarchical SCM block"); string REPSPCOMM = M("comment = \"DSP 32 Bit\"; - Definitionskommentar", "comment = \"DSP 32 Bit\"; - Definition comment"); string ERRMACLOAD = M("Fehler beim Laden von Symbol '%s' aus '%s'!", "Error loading symbol '%s' in '%s'!"); string ERRDELLSCM = M("Altes Element '%s'/'%s' ist schreibgeschuetzt!", "Old element '%s'/'%s' is write-protected!"); string ERRPINNASS = M("Pin '%s'/'%s' hat keine Zuweisung!", "Pin '%s'/'%s' isn't assigned!"); string ERRTEMPELEM = M("Temporaerelement '%s'/'%s' konnte nicht angelegt werden!", "Couldn't create temporary element '%s'/'%s'!"); string ERRNODEF = M("Definition '%s' in Bibliothek '%s' nicht gefunden!", "Logical definition '%s' not found in library '%s'!"); string ERRNOPICK = M("Kein Pickelement gefunden!", "No pick element found!"); string FMTGATENAME = M("g%d","g%d"); // INI file parameter name definitions #define PAR_LINELEN "LLCOLS_SCM" // Logical library edit columns #define PAR_MAXEDIT "LLMAXLEN_SCM" // Max. logical library edit length #define PAR_LLJOB "LLJOBEDIT_SCM" // Logical library job edit only #define PAR_LLPINTS "LLPINTS_SCM" // Pin text size #define PAR_NEWATTRL "NEWATTRL_SCM" // newattr list #define PAR_ASSFEXT "PINASSFEXT_SCM"// Pin assignment file name extension #define PAR_PINDCNT "LLPINDCNT_SCM" // Pin edit dialog items count #define PAR_PINWIDTH "LLPINDW_SCM" // Pin edit dialog item width #define PAR_DISPPLNAME "DISPPLNAME_SCM"// $plname part display flag // User Language program names #define UL_HISTORY "history" // ULP: File History Call // Global variable definitions int LINELEN = bae_iniintval(PAR_LINELEN,40); // Logical library edit columns int MAXEDIT = bae_iniintval(PAR_MAXEDIT,60000); // Max. logical library edit length int JOBDEST = bae_iniintval(PAR_LLJOB,0); // Logical library job dest. flag double PINTSIZE = bae_inidblval(PAR_LLPINTS,0.002); // Pin text size string ASSEXT = bae_inistrval(PAR_ASSFEXT,".csv") /* Pin assignments file name ext. */; int PINDCNT = bae_iniintval(PAR_PINDCNT,12) /* Max. pin list length */; double PINDWIDTH = bae_inidblval(PAR_PINWIDTH,5.0) /* Pin edit field width */; double BUTXSTEP = bae_swconfig(3)==2 ? 2.0 : 0.0 /* Menu action button x spacing */; #define RS_LLEDIT "logledit" // Logical library edit flag pred. #define RS_LLCACOLOR "logledit_color"// Log. lib. contact area color pred. #define RS_LLPICKM "logledit_pickm"// Log. lib. pick mode pred. #define EBOXHEIGHT 16.0 // Edit box height #define HBOXHEIGHT 3.0 // Help box height #define SYMSPACE 0.010 // Symbol Placement spacing #define LOGLFNAME "logledit.ddb" // Logical library edit DDB file name string loglfname = scmlibdir()+LOGLFNAME; string HLPDOC = M("bm7_11_de.htm","bm7_11_en.htm")/* Help document name */; #define HLPDIR "baedoc" // Help documents directory name // SQL command definitions #define L_CREATE "create table lledit_data (plan string,library string);" #define L_DELETE "delete from lledit_data where plan=%s;" #define L_INSERT "insert into lledit_data values(%s,%s);" #define L_SELECT "select library from lledit_data where plan=%s;" string sqlcommand /* SQL command string */; struct nattrdes { // Attribute descriptor string attname /* Attribute name */; string attval /* Attribute default value */; } /* Attribute list */; struct nattrdes defnattrl[] = { // Default newattr list { "$comment" , "" }, { "$commentde" , "" }, { "$manufacturer" , "" }, { "$type" , "$LLNAME" } }; struct nattrdes nattrl[] /* newattr list */; int nattrn /* newattr count */; string logldef /* Definition string */; string defhead /* Definition head part */; string defbody /* Definition body */; string curstr /* Current scan string */; string curplname = "" /* Current part macro name */; int curplnflag = 0 /* Current part name attribute flag */; int gpflag = 0 /* gpname attribute flag */; int pinscan = 0 /* Pin command scan flag */; int pincnt = 0 /* Pin count */; struct pindes { // Pin placement descriptor double x, y /* Pin position */; double r /* Pin rotation angle */; string name /* Pin name */; int proc /* Pin processed flag */; } lpinl[],spinl[] /* Pin lists */; int lpinn = 0 /* Layout pin count */; int spinn = 0 /* Schematic pin count */; double symw, symh /* Symbol size */; double symxoff, symyoff /* Symbol origin offset */; double symlx, symly /* Symbol lower boundary */; struct xlatdes { // xlat descriptor string pl[] /* Part pin list */; string name /* Pin name */; } xlatl[] /* xlat pin list */; int xlatn = 0 /* xlat pin count */; int gaten = 0 /* Gate count */; STRINGS pinl /* Pin list */; int pinn = 0 /* Pin count */; STRINGS macl /* Current part macro list */; int macn = 0 /* Current part macro count */; int macidx = (-1) /* Makro field dialog box item idx. */; string jobfname = bae_planfname() /* Project file name */; int ddbclass = bae_planddbclass() /* Schematic plan DDB class */; string defloglname /* Default logical lib. file name */; // Main program void main() { index C_FIGURE fig /* Figure list index */; index C_NREF nref /* Named reference index */; string deflname /* Definition library file name */; string defename /* Definition element name */; string rlname /* Requested logical library name */; double x, y /* Pick position */; int pickmode /* Element pick mode */; int boxccnt /* Edit box character count */; int col /* Color buffer */; /* Get default logical library name */ defloglname=strgetvarfilename(scm_defloglname()); catext(defloglname,DDBEXT); // Get the newattr list for (nattrn=0;nattrn<1000;nattrn++) { if ((nattrl[nattrn].attname=bae_inistrval( bae_inifieldvarname(PAR_NEWATTRL,nattrn,0),""))=="") { // Check if list defined at all if (nattrn==0) { // Use default newattr list nattrl=defnattrl; nattrn=arylength(nattrl); } break; } nattrl[nattrn].attval=bae_inistrval( bae_inifieldvarname(PAR_NEWATTRL,nattrn,1),""); } // Calculate the edit box character count if (LINELEN<0) { LINELEN=-LINELEN; } else { boxccnt=floor((90.0-DIAL_LEFTMARG-DIAL_RIGHTEMARG- 2.0*bae_dialgettextlen(PA_FNTFIX," "))/ (bae_dialgettextlen(PA_FNTFIX," ")- bae_dialgettextlen(PA_FNTFIX," "))); if (boxccnt>LINELEN) LINELEN=boxccnt; } // Check if special logical library edit plan if (cap_rulequery(RS_OCPLAN,0,RS_SCMSUBJ,RS_LLEDIT,"?d",col)>0 && col>0 && (deflname=getdstlibname())!="" && con_getlogpart(deflname,bae_planename(),LINELEN,logldef)==0) { // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Restore contact area color if (cap_rulequery( RS_OCPLAN,0,RS_SCMSUBJ,RS_LLCACOLOR,"?d",col)>0) bae_setcolor(7,col); else bae_setcolor(7,0); if (cap_rulequery( RS_OCPLAN,0,RS_SCMSUBJ,RS_LLPICKM,"?d",pickmode)<1) scm_getintpar(5,pickmode); defename=bae_planename(); // Get the mouse position bae_wsmouse(x,y,0); bae_clriactqueue(); bae_storemouseiact(1,x,y,0,LMB); if (scm_pickelem(fig,C_FIGTEXT)!=0 || (fig.NAME!=UPRATXTLEFT && fig.NAME!=UPRATXTRIGHT)) { // Strip xlat command from definition stripxlat(); // Scan pin assignments forall (fig where fig.TYP==C_FIGNREF) { // Buffer symbol name for scan error messages curstr=fig.NAME; // Check if first gate if (gaten==0) { // Document schematic pins logldef+=" xlat("; if (cap_scanfelem(fig,0.0,0.0,0.0,1, macfunc,NULL,NULL,NULL)!=0) error_scan(); logldef=logldef+") to\n ("; } else { logldef=logldef+") or\n ("; } // Document layout part pins pincnt=0; if (cap_scanfelem(fig,0.0,0.0,0.0,1, pmacfunc,NULL,NULL,NULL)!=0) error_scan(); gaten++; } logldef+=");\n }"; // Compile new definition switch (con_compileloglib(deflname,NULL,logldef)) { case (-1) : bae_msgbox(2,UPRECONT,""); exit(0); case (-2) : bae_msgbox(1,UPRWCONT,""); default : screenredraw(); } } // Save logical library edit element call(MNU_SCMSAVELEM); scm_setintpar(5,pickmode); // Reload previous plan bae_clriactqueue(); bae_storetextiact(1,"c"); ulsystem(UL_HISTORY,0); // Edit definition logledit(deflname,defename,defename,fig,1); } // Check if symbol edit else if (ddbclass==DDBCLSSYM || ddbclass==DDBCLSLAB) { // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Edit/create definition for current symbol logledit(jobfname,bae_planename(),bae_planename(),fig,0); } else if (ddbclass==DDBCLSCM) { // Pick symbol bae_promptdialog(UPRPICKSYM); if (scm_pickelem(fig,C_FIGNREF)!=0) // No pick element found error(ERRNOPICK); // Get named reference index nref=fig.NREF; // Get the requested library part name if (nref.MACRO.TAGSYM) { // Use default logical library name for tag symbol rlname=nref.MACRO.NAME; } else { if (cap_getpartattrib(nref.NAME,"$rlname",rlname)!=0 || rlname[0]=='\0') // Get the requested library part name extension if (cap_getpartattrib(nref.NAME,"$rlext",rlname)!=0 || rlname[0]=='\0') { // Assume default logical library name rlname=nref.MACRO.NAME; } else { /* Check extended symbol macro name length */ if ((strlen(nref.MACRO.NAME)+ strlen(rlname)+1)<=MAXKEYLEN) /* Add requested extension */ rlname=nref.MACRO.NAME+"_"+rlname; else // Assume default logical library name rlname=nref.MACRO.NAME; } } // Convert name to lower case strlower(rlname); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Edit/create definition logledit(jobfname,rlname,nref.MACRO.NAME,fig,0); } else { // Select the source DDB file deflname=defloglname; if (bae_askddbfname(deflname,1,"")) // Abort error_abort(); // Select the element name if (bae_askddbename(defename,deflname,DDBCLLLIB,"")) // Abort error_abort(); // Edit/create definition logledit(deflname,defename,defename,fig,0); } } void logledit( string fname,string ename,string symname,index C_FIGURE fig,int autodest) /* // Edit/create loglib definition // Parameters : // string fname : File name // string ename : Element name // string symname : Symbol macro name // index C_FIGURE fig : Symbol figure list element // int autodest : Automatically set destination */ { index C_FIGURE nfig /* Named ref. figure list index */; string docdname /* Document directoy name */; string deflname /* Definition library file name */; string libname /* Library file name */; string xlatbuf /* xlat command buffer */; string msg /* Message string */; string helpstr /* Help display string */; int busflag /* Bus pin flag */; int newfile = 1 /* New source file flag */; int res /* Result buffer */; double cx, cy /* Current dialog coord. values */; double dialwidth /* Dialog box width */; double dialheight /* Dialog box height */; double baseheight /* Dialog box base height */; int edtidx /* Edit field dialog box item idx. */; int repflag = 1 /* Input repeat flag */; int i /* Loop control variable */; // Get default library name libname=defloglname; // Try to load definition from job file if (con_getlogpart(fname,ename,LINELEN,logldef)==0) { // Log. part definition found deflname=fname; newfile=0; } // Try to load definition from library file else if (con_getlogpart(libname,ename,LINELEN,logldef)==0) { // Log. part definition found deflname=libname; newfile=0; } else { // Check if other file requested sprintf(msg,UPROFILE,ename); while (bae_msgboxverify(msg,"")) { // Select the source DDB file if (bae_askddbfname(deflname,0,UPRLFILE)) break; // Try to load definition from source file if (con_getlogpart(deflname,ename, LINELEN,logldef)==0) { // Log. part definition found newfile=0; break; } sprintf(msg,UPRNFILE,ename); } // Check if template creation if (newfile) { if (ddbclass==DDBCLSLAB || (ddbclass==DDBCLSCM && fig.NREF.MACRO.CLASS==DDBCLSLAB)) { // Create label definition template sprintf(logldef, "part \"%s\" : virtual\n{\n pin(\"#\");\n}", ename); } else { // Get the layout part macro name getlaypartname(symname,ename,fig); sprintf(logldef,"part \"%s\" : ",ename); // Create symbol definition template if (macl[0]=="virtual") { logldef+="virtual"; } else { if (curplnflag) logldef+="default "; logldef+="\""+macl[0]+"\""; for (i=1;i=1 && busflag) continue; pincnt++; if (pincnt!=1) logldef=logldef+","; else logldef=logldef+" pin("; if (pincnt%10==0) logldef=logldef+"\n "; logldef=logldef+"\""+nfig.NAME+"\""; } if (pincnt!=0) logldef=logldef+");\n"; pincnt=0; forall (nfig where nfig.TYP==C_FIGNREF) { // Query the bus status if (cap_rulequery(RS_OCFIG,nfig, RS_SCMSUBJ,RS_AUTOBUS,"?d", busflag)<1 || !busflag) continue; pincnt++; if (pincnt!=1) logldef=logldef+","; else logldef=logldef+" bus("; if (pincnt%10==0) logldef=logldef+"\n "; logldef=logldef+"\""+nfig.NAME+"\""; } if (pincnt!=0) logldef=logldef+");\n"; forall (nfig where nfig.TYP==C_FIGTEXT && nfig.NAME=="$gp") gpflag=1; } if (lpinn>0) { if (lpinn0 && logldef[i]!='}') i--; if (i>=0 && logldef[i]=='}') { while (i>0 && (logldef[i-1]==' ' || logldef[i-1]=='\t')) i--; logldef[i]='\0'; } logldef+=pinassread()+" }"; break; // Graphical pin assignment case 2 : case 3 : // Table pin assignment case 4 : bae_dialgetdata(edtidx,0,0.0,logldef); verifysave(); curplname=""; gaten=pinn=xlatn=0; // Compile new definition switch (con_compileloglib( deflname,NULL,logldef)) { case (-1) : bae_msgbox(2,UPRECONT,""); continue; case (-2) : bae_msgbox(1,UPRWCONT,""); default : screenredraw(); } synparsestring(logldef); if (res==4) { // Strip xlat command from definition if ((xlatbuf=pinasstable( ename,symname,curplname))!="") { stripxlat(); logldef+=xlatbuf+" }"; } } else { pinassedit(deflname,ename,symname, curplname,res==3 ? 1 : 0); } break; // Edit macro list case 5 : // Compile new definition(s) switch (con_compileloglib( deflname,NULL,logldef)) { case (-1) : bae_msgbox(2,UPRECONT,""); continue; case (-2) : bae_msgbox(1,UPRWCONT,""); default : screenredraw(); } headedit(deflname,symname,ename); break; // Display manual case 6 : // Build the directory path name docdname=bae_progdir(); for (i=strlen(docdname)-2;i>=0;i--) if (docdname[i]==':' || docdname[i]=='/' || docdname[i]=='\\') { docdname[i+1]='\0'; break; } // Call the online help launcher launch("$extappl:.htm: \""+ docdname+HLPDIR+'\\'+HLPDOC+"\""); break; // Resize case (-2) : bae_dialgetdata(edtidx,0,0.0,logldef); break; default : error_abort(); } } while (repflag); } // Compile new definition switch (con_compileloglib(deflname,NULL,logldef)) { case (-1) : bae_msgbox(2,UPRECONT,""); repflag=1; continue; case (-2) : bae_msgbox(1,UPRWCONT,""); default : screenredraw(); } break; } while (1); bae_prtdialog(REPDONE); } int macfunc(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Pin list 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 if symbol pin if (macro.CLASS==DDBCLSMRK && refname!="") { pincnt++; if (pincnt!=1) logldef=logldef+","; else if (pinscan) logldef=logldef+" pin("; if (pincnt%10==0) logldef=logldef+"\n "; logldef=logldef+"\""+refname+"\""; spinl[spinn].name=refname; spinn++; } // Continue scan return(1); } int pmacfunc(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Pin destination list 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 */ { index C_FIGURE fig /* Figure list index */; index C_POLY poly /* Polygon index */; index C_POINT p /* Polygon point index */; string msg /* Message string */; double x, y /* Macro coordinates */; double sx, sy /* Line start coordinates */; double ex, ey /* Line end coordinates */; int pn = 0 /* Point count */; int oldpickmode /* Old element pick mode */; // Check if symbol pin if (macro.CLASS==DDBCLSMRK && refname!="") { // Check if line end at pin position cap_maccoords(x,y,0.0,0); scm_getintpar(5,oldpickmode); scm_setintpar(5,0); bae_clriactqueue(); bae_storemouseiact(1,x,y,0,LMB); if (scm_pickelem(fig,C_FIGPOLYC)==0) { // Scan polygon end points poly=fig.POLY; forall (p of poly) { if (pn==0) { sx=p.X; sy=p.Y; } else { ex=p.X; ey=p.Y; } pn++; } // Get the pick destination position if (dist(sx,sy,x,y)0 && newpart!="") { macl[0]=newpart; macn=1; // Get the layout part pin list getlaypartpins(newpart); return; } } } else if (ddbclass==DDBCLSCM) { curplname=""; cap_scanfelem(fig,0.0,0.0,0.0,1,NULL,NULL,NULL,pltextfunc); if (curplname!="") { macl[0]=curplname; macn=1; // Get the layout part pin list getlaypartpins(curplname); return; } } // Check if dialog box support if (bae_dialclr()) { // Select new part macro if (bae_askddbename(newpart,jobfname,DDBCLLPRT, msgstring(UPRNEWPRT,convstring(jobfname,1)))) error_abort(); macl[0]=newpart; macn=1; // Get the layout part pin list getlaypartpins(newpart); } else { // Edit new layout part macro list macn=0; if (editlaypartlist(symname,ename) || macn==0) return; // Get the layout part pin list getlaypartpins(macl[0]); } } void getlaypartpins(string partname) /* // Get layout part pin list // Parameter : // string partname : Part macro name */ { string msg /* Message string */; string pinname = "" /* Pin name name */; string fn /* File name buffer */; int pinidx = 0 /* Pin index */; double pinx, piny /* Pin position */; double pinr /* Pin rotation */; int i /* Loop control variable */; // Init. the pin list lpinn=0; // Check if virtual symbol if (partname=="virtual") return; // Get the library file name fn=jobfname; if (existddbelem(fn,DDBCLLPRT,partname)!=1) fn=defloglname; // Check if part exists if (existddbelem(fn,DDBCLLPRT,partname)!=1) { sprintf(msg,UPRNPFILE,partname); if (bae_msgboxverify(msg,"")) { if (bae_askddbfname(fn,1,"")) // Abort error_abort(); // Select the element name if (bae_askddbename(partname,fn,DDBCLLPRT,"")) // Abort error_abort(); } } // Scan the layout part pin list while ( ddbgetlaypartpin(fn,partname,pinidx,pinname,"",pinx,piny,pinr,0)==0) { for (i=lpinn;i>0;i--) if (numstrcmp(pinname,lpinl[i-1].name)<0) lpinl[i]=lpinl[i-1]; else break; lpinl[i].x=pinx; lpinl[i].y=piny; lpinl[i].r=pinr; lpinl[i].name=pinname; lpinl[i].proc=0; lpinn++; pinidx++; } if (bae_swconfig(0)==BAE_HighEnd && bae_iniintval(PAR_DISPPLNAME,0)) { // Build the load part macro request message sprintf(msg,"%d %s\"%s",MSGID_LLPRTMAC,fn,partname); // Send the load part macro request message bae_sendmsg(msg,0); } } void getsymbolpins(string symname) /* // Get symbol pin list // Parameter : // string symname : Symbol macro name */ { index C_POOL pool /* Symbol macro pool index */; double gridx, gridy /* Input grid */; double gd /* Grid distance value */; string msg /* Message string */; string fn /* File name buffer */; // Get the library file name fn=jobfname; if (existddbelem(fn,DDBCLSSYM,symname)!=1) { fn=scm_libfname(); catext(fn,DDBEXT); } // Copy the symbol macro to edit file ddbcopyelem(fn,loglfname,DDBCLSSYM,symname,1); // Load the symbol macro if (cap_macload(pool,fn,symname,DDBCLSSYM)!=0) { sprintf(msg,ERRMACLOAD,fn,symname); error(msg); } // Scan the symbol pins spinn=0; if (cap_scanpool(pool,0.0,0.0,0.0,1,pinposfunc,NULL,NULL,NULL)!=0) { // Release the macro element cap_macrelease(pool); error_scan(); } // Store the macro size symlx=pool.MACRO.MLX; symly=pool.MACRO.MLY; symxoff=pool.MACRO.MNX; symyoff=pool.MACRO.MNY; if (bae_getgridlock()) { bae_getinpgrid(gridx,gridy); // Shift lower boundary to ensure symbol origin grid snap gd=symxoff-symlx; symlx-= gridx!=0.0 ? (gridx*ceil(gd/gridx)-gd) : 0.0; gd=symyoff-symly; symly-= gridy!=0.0 ? (gridy*ceil(gd/gridy)-gd) : 0.0; } symw=mmceil(pool.MACRO.MUX-symlx); symh=mmceil(pool.MACRO.MUY-symly); // Release the macro element cap_macrelease(pool); } int pinposfunc(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // Pin position scan 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 if symbol macro itself if (refname=="") return(1); // Store the pin position cap_maccoords(spinl[spinn].x,spinl[spinn].y,spinl[spinn].r,0); spinl[spinn].name=refname; spinn++; return(0); } int gptextfunc(index C_TEXT textp,double tx,double ty,double tangle, int mirrflag,double tsize,string tstr,int textinws,int macclass,int varattr) /* // Get the text characteristics // Return value : // zero if done or (-1) on error // Parameters : // index C_TEXT textp : Text index // double tx : Text X coordinate // double ty : Text Y coordinate // double tangle : Text angle // int mirrflag : Text mirror flag // double tsize : Text size // string tstr : Text string // int textinws : Text in workspace flag // int macclass : Text macro class // int varattr : Text variant attribute flag */ { if (textp.STR=="$gp") gpflag=1; // Return without errors return(0); } int pltextfunc(index C_TEXT textp,double tx,double ty,double tangle, int mirrflag,double tsize,string tstr,int textinws,int macclass,int varattr) /* // Get the text characteristics // Return value : // zero if done or (-1) on error // Parameters : // index C_TEXT textp : Text index // double tx : Text X coordinate // double ty : Text Y coordinate // double tangle : Text angle // int mirrflag : Text mirror flag // double tsize : Text size // string tstr : Text string // int textinws : Text in workspace flag // int macclass : Text macro class // int varattr : Text variant attribute flag */ { if (textp.STR=="$plname") { curplnflag=1; // Query the current active default value if (cap_rulequery(RS_OCPOOL,textp,RS_SCMSUBJ,RS_INIVAL, "?s",curplname)>0 && curplname!="") return(-1); curplname=""; } // Return without errors return(0); } /*________________________________________________________________*/ // Logical library file syntax #bnf { // Loglib entry libdef : "part" ident ":" optclassspec partdef ; // Part functions syntax optclassspec : "class" ident | ; partdef : mainflag defflag plnames partblk | "subpart" ident partblk | "virtual" virtblk | "logical" virtblk ; mainflag : "mainpart" | ; defflag : "default" | ; plnames : plnames "," ident | ident (p_plname) ; partblk : "{" partcmds "}" | ";" ; partcmds : partcmds partcmd | partcmd ; partcmd : "bus" pinlist ";" | "net" netcmd ":" pinlist ";" | "pin" pinlist ";" | "swap" swapcmd swapblk ";" | "xlat" (p_xlat) pinlist (p_xlatpins) "to" xlats ";" | "xlat" (p_xlat) "(" xlatpinass ")" ";" | "netattr" "priority" DQSTR ":" pinlist ";" | "netattr" "mindist" DQSTR ":" pinlist ";" | "netattr" "powwidth" DQSTR ":" pinlist ";" | "netattr" "routwidth" DQSTR ":" pinlist ";" | "netattr" idstr DQSTR ":" pinlist ";" | "newattr" DQSTR "=" DQSTR topinlist ";" | "comment" "=" DQSTR ";" ; virtblk : "{" virtcmds "}" | ";" ; virtcmds : virtcmds virtcmd | virtcmd ; virtcmd : "bus" pinlist ";" | "net" netcmd ":" pinlist ";" | "pin" pinlist ";" | "netattr" "priority" DQSTR ":" pinlist ";" | "netattr" "mindist" DQSTR ":" pinlist ";" | "netattr" "powwidth" DQSTR ":" pinlist ";" | "netattr" "routwidth" DQSTR ":" pinlist ";" | "netattr" idstr DQSTR ":" pinlist ";" | "newattr" DQSTR "=" DQSTR topinlist ";" | "call" ident ";" | "architecture" "{" synthprog "}" | "comment" "=" DQSTR ";" ; topinlist : "to" pinlist | ; netcmd : ident | "internal" ; swapcmd : "internal" | ; swapblk : "(" groups ")" | "(" gates ")" ; groups : groups "," "[" gates "]" | "[" gates "]" ; gates : gates "," gate | gate ; gate : "(" gateblk ")" | pin ; gateblk : gateblk "," gatepin | gatepin ; gatepin : pinlist | pin ; xlats : xlats "or" pinlist (p_xlatppins) | pinlist (p_xlatppins) ; xlatpinass : xlatpinass "," xlpindef | xlpindef ; xlpindef : "(" pin "," xlpins ")" ; xlpins : xlpins "," pin | pin ; synthprog : synthprog sprogcmd | sprogcmd ; sprogcmd : "part" ident "(" preqpinlist ")" ";" ; preqpinlist : preqpinlist "," preqpinass | preqpinass ; preqpinass : pin ":" preqdest ; preqdest : pin | "net" ident | "net" "&" ident | "&" ident ; pinlist : "(" (p_clrid) pins ")" ; pins : pins "," pin | pin ; pin : identpt (p_addpin) | identpt (p_addpin) "-" identpt (p_addpin) optstep ; optstep : ":" NUMBER | ; // Identifier expression ident : IDENT (p_ident) | NUMBER (p_ident) | SQSTR (p_ident) | DQSTR (p_ident) ; identpt : identpt idpiece | '/' (p_idpiece) idpiece | idpiece ; idpiece : IDENT (p_idpiece) | NUMBER (p_idpiece) | SQSTR (p_idpiece) | DQSTR (p_idpiece) | '.' (p_idpiece) ; idstr : IDENT | DQSTR ; } // BNF end /*________________________________________________________________*/ // Parser action routines int p_plname() /* // Receive a physical library name // Return value : // zero if done, or nonzero on error */ { // Store the physical library name curplname=curstr; return(0); } int p_xlat() /* // Receive a xlat command start // Return value : // zero if done, or nonzero on error */ { pinn=0; // Return without errors return(0); } int p_xlatpins() /* // Receive a xlat pin list // Return value : // zero if done, or nonzero on error */ { int i /* Loop control variable */; for (i=0;ipux) pux=lpinl[i].x; if (lpinl[i].ypuy) puy=lpinl[i].y; d=dist(lpinl[i].x,lpinl[i].y,lpinl[i-1].x,lpinl[i-1].y); if (i==1 || (dmaxtlen) maxtlen=strlen(lpinl[i].name); } bae_getintpar(3,msmmode); scm_storetext((msmmode&2) ? UPRTXTRIGHT : UPRTXTLEFT, 0.5*(gaten*symw-SYMSPACE),symh+3.0*PINTSIZE, 0.0,PINTSIZE,0,TEXTHCENT|TEXTFRM1); if (cap_lastfigelem(lastfig)==0) rsc_assfigstrpred(lastfig,predname,"logledit","",""); scm_storetext((msmmode&2) ? UPRATXTRIGHT : UPRATXTLEFT, 0.5*(gaten*symw-SYMSPACE),symh+PINTSIZE, 0.0,PINTSIZE,0,TEXTHCENT|TEXTFRM1); if (cap_lastfigelem(lastfig)==0) rsc_assfigstrpred(lastfig,predname,"logledit","",""); pscale=0.75*PINTSIZE*maxtlen/(lpinn<=1 ? 1.0 : mindist); pxoff=pscale*(-plx-0.5*(pux-plx))+0.5*(gaten*symw-SYMSPACE); pyoff=-pscale*puy-SYMSPACE; for (i=0;i=spinn) continue; for (j=0;j0 && strl[strn-1]=="") strn--; netflag= isupper(strl[0][0]) ? 1 : 0 ; ls=(netflag || isdigit(strl[1][0])) ? 1 : 2 ; } else { eofflag=1; } // Flush pending gate pins if ((eofflag || strn<2 || (strn-ls)!=pln) && pn>0) { buf+=" xlat"; for (i=0;imaxlen) maxlen=curlen; // Get the layout part pin list getlaypartpins(plname); for (i=0;i0 ? 0 : PA_GRAYED),0,1,0,0.0, 0.0,0.0,"",0,DIAL_LEFTMARG+15.0,cy-1.6,0.0,UPRPREVDIAL); bae_dialaddcontrol(PA_ACT|((mlsidx+PINDCNT)1 ? 1 : 0/* Macro list flag */; STRINGS omacl /* Old part macro list */; int omacn = 0 /* Old part macro count */; int i /* Loop control variable */; // Buffer old macro list omacl=macl; omacn=macn; // Build the part name list string if (macn>0) { newpart=macl[0]; for (i=1;i=0) { // Get current macro list string bae_dialgetdata(macidx,0,0.0,newpart); if (newpart=="virtual") macn=0; else // Extract macro name list buildmaclist(newpart); // Search selected macro item for (i=0;i=macn) { // Add macro to list macl[macn]=itemstr; macn++; } else { // Delete macro from list for (;i<(macn-1);i++) macl[i]=macl[i+1]; macn--; } // Build the part name list string newpart= macn==0 ? "" : macl[0]; for (i=1;ipos1 ? strtrim(strextract(s,pos1-1,pos2-2)) : ""; // Update the scan start position pos1=pos2+1; } // Extract last substring if last char not delimiter if (pos1=0 && isspace(s[i])) ; // Extract and return substring return(i<0 ? "" : strextract(s,0,i)); } string strtrim(string s) /* // Trim string (skip leading and trailing white spaces) // Return value : // string without leading and trailing white spaces // Parameters : // string s : Input string */ { // Extract and return substring return(strrtrim(strltrim(s))); } double mmceil(double val) /* // Round meter input value up to next mm // Return value : // rounded value in meters // Parameters : // double val : Input value */ { // Calculate result and return it return(ceil(val*1000.0)/1000.0); } string scmlibdir() /* // Get SCM library directory path // Return value: SCM library directory path name */ { string s /* String buffer */; // Get the default SCM library name if ((s=strgetvarfilename(scm_deflibname()))=="") // Return current directory name return(""); // Extract and return directory path name return(strextract(s,0,strscanprior(s,"\\/",strlen(s)-1,1))); } void stripxlat() /* // Strip xlat command from logical definition */ { string loglbuf /* Definition buffer */; int sqtoggle = 0 /* Single quotation toggle */; int dqtoggle = 0 /* Double quotation toggle */; int dst /* String destination index */; char c /* Character buffer */; int i /* Loop control variable */; // Remove part close brace i=strlen(logldef)-1; while (i>0 && logldef[i]!='}') i--; if (i>=0 && logldef[i]=='}') { while (i>0 && (logldef[i-1]==' ' || logldef[i-1]=='\t')) i--; logldef[i]='\0'; } // Remove xlat commands loglbuf=logldef; for (i=dst=0;(c=loglbuf[i])!='\0';i++) { if (c=='\'' && !dqtoggle) sqtoggle=!sqtoggle; else if (c=='"' && !sqtoggle) dqtoggle=!dqtoggle; // Check if xlat start if (c=='x' && !sqtoggle && !dqtoggle && strextract(loglbuf,i,i+3)=="xlat") { // Skip xlat command while ((c=loglbuf[i])!='\0' && c!=';') i++; if (c==';' && (loglbuf[i+1]==13 || loglbuf[i+1]==10)) { while (dst>0 && logldef[dst-1]==' ') dst--; i++; } } else { logldef[dst]=c; dst++; } } // Terminate definition logldef[dst]='\0'; } void splitdef(string defstr) /* // Split logical definition // Parameter : // string defstr : Definition string */ { char c /* Character buffer */; int bodystart = strlen(defstr)-1 /* Definition body start */; int headstart /* Header string start */; int headend /* Header string end */; int macstart /* Macro string start */; int macend /* Macro string end */; int i /* Loop control variable */; // Search part body open brace for (i=0;(c=defstr[i])!='\0';i++) if (c=='{') { bodystart=i; break; } // Skip blanks i=bodystart-1; while (i>0 && ((c=defstr[i])==' ' || c=='\t' || c==13 || c==10)) i--; // Scan part macro string macstart=macend=i; while (i>0) { if ((c=defstr[i])==' ' && (i==0 || ((c=defstr[i-1])!=' ' && c!='\t' && c!=13 && c!=10 && c!=','))) { macstart=i+1; break; } i--; } buildmaclist(strextract(defstr,macstart,macend)); headend=i; headstart=5; while ((c=defstr[headstart])!='\0') { if (c==' ') break; headstart++; } // Get the definition split parts defbody=strextract(defstr,bodystart,strlen(defstr)-1); defhead=strextract(defstr,headstart,headend); } void buildmaclist(string macstr) /* // Get macro list from macro list string // Parameter : // string macstr : Macro list string */ { char c /* Character buffer */; int macstart /* Macro string start */; int macend /* Macro string end */; int i /* Loop control variable */; // Scan part macros macn=0; i=0; while ((c=macstr[i])!='\0') { // Skip blanks/seperators while ((c=macstr[i])==' ' || c==',' || c=='\t' || c==13 || c==10) i++; if (c=='"') i++; macstart=i; while ((c=macstr[i])!='\0' && c!=' ' && c!=',' && c!='\t' && c!=13 && c!=10) i++; macend=i-1; if (macend>0 && macstr[macend]=='"') macend--; macl[macn]=strextract(macstr,macstart,macend); macn++; } } string getdstlibname() /* // Get destination library // Return value: Destination library file name */ { // Query the destination library name curstr=""; sprintf(sqlcommand,L_SELECT,sql_quotestr(bae_planename())); sqlcmd(bae_planfname(),sqlcommand,datafunc); return(curstr); } int datafunc(string dstr,int dint,double ddbl, int dval,int dtype,string dtable,string dfield,int didx) /* // Data query callback function // Return value : // zero if done or (-1) on data error // Parameters : // string dstr : String/Date data // int dint : Integer/Boolean data // double ddbl : Float data // int dval : Data valid flag // int dtype : Data type // string dtable : Data table name // string dfield : Data field name // int didx : Data output field index */ { curstr=dstr; // Return without errors return(0); } // User Language program end