fix lazy list building in "xschem ..." commands (put separator after last item), as some parsers choke on this.

This commit is contained in:
stefan schippers 2023-04-08 22:27:59 +02:00
parent 5e3445a80e
commit 192e873f0c
2 changed files with 36 additions and 28 deletions

View File

@ -479,8 +479,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Include ~/xxx here between <ul> and </ul>
-->
<li><kbd> abort_operation</kbd></li><pre>
Resets UI state, unselect all and abort any pending operation </pre>
<li><kbd> add_symbol_pin</kbd></li><pre>
@ -720,15 +718,16 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Return a list of 3-items. Each 3-item is
an instance name followed by the symbol reference and symbol type.
Example: xschem instance_list --&gt;
{x1} {sky130_tests/bandgap.sym} {subcircuit}} {...} {...} {...} ... </pre>
{x1} {sky130_tests/bandgap.sym} {subcircuit}} {...} {...} {...} ... </pre>
<li><kbd> instance_net inst pin</kbd></li><pre>
Return the name of the net attached to pin 'pin' of instance 'inst'
Example: xschem instance_net x3 MINUS --&gt; REF </pre>
<li><kbd> instance_nodemap inst</kbd></li><pre>
<li><kbd> instance_nodemap inst [pin]</kbd></li><pre>
Return the instance name followed by a list of 'pin net' associations
example: xschem instance_nodemap x3
--&gt; x3 PLUS LED OUT LEVEL MINUS REF
instance x3 pin PLUS is attached to net LED, pin OUT to net LEVEL and so on... </pre>
instance x3 pin PLUS is attached to net LED, pin OUT to net LEVEL and so on...
If 'pin' is given restrict map to only that pin </pre>
<li><kbd> instance_pin_coord inst attr value</kbd></li><pre>
Return the name and coordinates of pin with
attribute 'attr' set to 'value' of instance 'inst'
@ -769,7 +768,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> load f [symbol|gui|noundoreset|nofullzoom]</kbd></li><pre>
Load a new file 'f'.
'gui': ask to save modified file or warn if opening an already
open file or opening a new(not existing) file.
open file or opening a new(not existing) file.
'noundoreset': do not reset the undo history
'symbol': do not load symbols (used if loading a symbol instead of a schematic)
'nofullzoom': do not do a fll zoom on new schematic.</pre>
@ -827,7 +826,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> new_schematic create|destroy|destroy_all|switch_win winpath file</kbd></li><pre>
Open/destroy a new tab or window
create: create new empty window or with 'file' loaded if 'file' given.
The winpath must be given (even {} is ok) but not used.
The winpath must be given (even {} is ok) but is not used.
destroy: destroy tab/window identified by winpath. Example:
xschem new_schematic destroy .x1.drw
destroy_all: close all tabs/additional windows
@ -1055,7 +1054,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
If 'callback' procedure name is given execute the procedure when simulation
is finished. all execute(..., id) data is available (id = execute(id) )
A callback prodedure is useful if simulation is launched in background mode
( set sim(spice,1,fg) 0 )</pre>
( set sim(spice,1,fg) 0 ) </pre>
<li><kbd> snap_wire </kbd></li><pre>
Start a GUI start snapped wire placement (click to start a
wire to closest pin/net endpoint) </pre>
@ -1096,8 +1095,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Toggle dark/light colorscheme </pre>
<li><kbd> translate n str</kbd></li><pre>
Translate string 'str' replacing @xxx tokens with values in instance 'n' attributes
Example: xschem translate vref {the voltage is @value}
the voltage is 1.8</pre>
Example: xschem translate vref {the voltage is @value}
the voltage is 1.8
</pre>
<li><kbd> trim_wires</kbd></li><pre>
Remove operlapping wires, join lines, trim wires at intersections </pre>
<li><kbd> undo</kbd></li><pre>
@ -1145,7 +1145,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
</ul>
<!-- TCL global variables -->
<h1>XSCHEM <a id="tclglobals">TCL GLOBAL</a> VARIABLES</h1><br>

View File

@ -1551,16 +1551,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, (char *)str_ptr, TCL_VOLATILE);
}
/* instance_nodemap inst
/* instance_nodemap inst [pin]
* Return the instance name followed by a list of 'pin net' associations
* example: xschem instance_nodemap x3
* --> x3 PLUS LED OUT LEVEL MINUS REF
* instance x3 pin PLUS is attached to net LED, pin OUT to net LEVEL and so on... */
* instance x3 pin PLUS is attached to net LED, pin OUT to net LEVEL and so on...
* If 'pin' is given restrict map to only that pin */
else if(!strcmp(argv[1], "instance_nodemap"))
{
/* xschem instance_nodemap [instance_name] */
int p, no_of_pins;
int inst = -1;
int inst = -1, first=1;
prepare_netlist_structs(0);
if(argc > 2) {
inst = get_instance(argv[2]);
@ -1572,8 +1573,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
pin = get_tok_value((xctx->inst[inst].ptr+ xctx->sym)->rect[PINLAYER][p].prop_ptr, "name",0);
if(!pin[0]) pin = "--ERROR--";
if(argc > 3 && strcmp(argv[3], pin)) continue;
if(first == 0) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, pin, " ",
xctx->inst[inst].node && xctx->inst[inst].node[p] ? xctx->inst[inst].node[p] : "{}", " ", NULL);
xctx->inst[inst].node && xctx->inst[inst].node[p] ? xctx->inst[inst].node[p] : "{}", NULL);
first = 0;
}
}
}
@ -1646,8 +1649,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
/* instance_pins inst
Return list of pins of instance 'inst'
'inst can be an instance name or a number */
* Return list of pins of instance 'inst'
* 'inst can be an instance name or a number */
else if(!strcmp(argv[1], "instance_pins"))
{
char *pins = NULL;
@ -2254,7 +2257,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
*/
else if(!strcmp(argv[1], "pinlist"))
{
int i, p, no_of_pins;
int i, p, no_of_pins, first = 1;
if(argc > 2) {
if((i = get_instance(argv[2])) < 0 ) {
Tcl_SetResult(interp, "xschem pinlist: instance not found", TCL_STATIC);
@ -2262,14 +2265,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
no_of_pins= (xctx->inst[i].ptr+ xctx->sym)->rects[PINLAYER];
for(p=0;p<no_of_pins;p++) {
if(first == 0) Tcl_AppendResult(interp, " ", NULL);
if(argc > 3 && argv[3][0]) {
Tcl_AppendResult(interp, "{",
get_tok_value((xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER][p].prop_ptr, argv[3], 0),
"} ", NULL);
"}", NULL);
} else {
Tcl_AppendResult(interp, "{ {", my_itoa(p), "} {",
(xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER][p].prop_ptr, "} } ", NULL);
(xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER][p].prop_ptr, "} }", NULL);
}
first = 0;
}
}
}
@ -2883,7 +2888,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
*/
else if(!strcmp(argv[1], "sch_pinlist"))
{
int i;
int i, first = 1;
char *dir = NULL;
const char *lab;
for(i = 0; i < xctx->instances; ++i) {
@ -2893,7 +2898,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else dir = NULL;
if(dir) {
lab = get_tok_value(xctx->inst[i].prop_ptr, "lab", 0);
Tcl_AppendResult(interp, "{", lab, "} {", dir, "} ", NULL);
if(first == 0) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, "{", lab, "} {", dir, "}", NULL);
first = 0;
}
}
@ -3010,12 +3017,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* Return a list of selected instance names */
else if(!strcmp(argv[1], "selected_set"))
{
int n, i;
int n, i, first = 1;
rebuild_selected_array();
for(n=0; n < xctx->lastsel; ++n) {
if(xctx->sel_array[n].type == ELEMENT) {
i = xctx->sel_array[n].n;
Tcl_AppendResult(interp, "{", xctx->inst[i].instname, "} ", NULL);
if(first == 0) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, "{", xctx->inst[i].instname, "}", NULL);
first = 0;
}
}
}
@ -3024,12 +3033,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* Return list of selected nets */
else if(!strcmp(argv[1], "selected_wire"))
{
int n, i;
int n, i, first = 1;
rebuild_selected_array();
for(n=0; n < xctx->lastsel; ++n) {
if(xctx->sel_array[n].type == WIRE) {
i = xctx->sel_array[n].n;
Tcl_AppendResult(interp, get_tok_value(xctx->wire[i].prop_ptr, "lab",0), " ", NULL);
if(first == 0) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, "{", get_tok_value(xctx->wire[i].prop_ptr, "lab",0), "}", NULL);
first = 0;
}
}
}
@ -3475,12 +3486,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
{
int i;
char n[100];
Tcl_SetResult(interp, "\n", TCL_STATIC);
for(i=0; i<xctx->symbols; ++i) {
my_snprintf(n , S(n), "%d", i);
Tcl_AppendResult(interp, " {", n, " ", "{", xctx->sym[i].name, "}", "}\n", NULL);
}
Tcl_AppendResult(interp, "\n", NULL);
}
else { cmd_found = 0;}
break;