Merge branch 'StefanSchippers:master' into master
This commit is contained in:
commit
48b561b72c
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product Id="*" Name="Xschem" Language="1033" Version="3.4.6" Manufacturer="Xschem" UpgradeCode="0deb9c17-cbbd-491c-be3e-24446b27ccd5">
|
||||
<Product Id="*" Name="Xschem" Language="1033" Version="3.4.6.1" Manufacturer="Xschem" UpgradeCode="0deb9c17-cbbd-491c-be3e-24446b27ccd5">
|
||||
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
||||
<WixVariable Id="WixUILicenseRtf"
|
||||
Value="License.rtf" />
|
||||
|
|
@ -151,9 +151,6 @@
|
|||
<Component Id="CMPNGSPICEBACKANNOTATE">
|
||||
<File Id="NGSPICEBACKANNOTATE" KeyPath="yes" Source="../../src/ngspice_backannotate.tcl" />
|
||||
</Component>
|
||||
<Component Id="CMPTRAVERSAL">
|
||||
<File Id="TRAVERSAL" KeyPath="yes" Source="../../src/traversal.tcl" />
|
||||
</Component>
|
||||
<Component Id="CMPORDERLABELSAWK">
|
||||
<File Id="ORDERLABELSAWK" KeyPath="yes" Source="../../src/order_labels.awk" />
|
||||
</Component>
|
||||
|
|
@ -361,7 +358,6 @@
|
|||
<ComponentRef Id="CMPMAKESYMAWK" />
|
||||
<ComponentRef Id="CMPMAKESYMLCCAWK" />
|
||||
<ComponentRef Id="CMPNGSPICEBACKANNOTATE" />
|
||||
<ComponentRef Id="CMPTRAVERSAL" />
|
||||
<ComponentRef Id="CMPMAKEVHDLFROMSPICEAWK" />
|
||||
<ComponentRef Id="CMPNETLISTCOMPACTORAWK" />
|
||||
<ComponentRef Id="CMPORDERLABELSAWK" />
|
||||
|
|
|
|||
|
|
@ -5880,6 +5880,9 @@
|
|||
<Component Id="cmp5B62A7CAE8EECF932F98EB403B5CDD29" Guid="{E3CBD1A0-81FA-4B30-BCC4-3350FC0F7A14}">
|
||||
<File Id="fil1CACDA915CAC17ACE7F7A3B476C083FF" KeyPath="yes" Source="$(var.docSrcDir)\xschem_man\run_xschem.html" />
|
||||
</Component>
|
||||
<Component Id="cmp814223FC22DFF7462DCE79B3829E6FBF" Guid="{3FE54B70-5CDE-4759-B1FB-EE3ECA812574}">
|
||||
<File Id="fil5DD06C43623DA708411D23E907EEEA81" KeyPath="yes" Source="$(var.docSrcDir)\xschem_man\scripts.html" />
|
||||
</Component>
|
||||
<Component Id="cmp9540E3F9B5835A06B30F0AE43A00BDCA" Guid="{4634F2B8-39C0-4F07-A2C5-89AB39A928C5}">
|
||||
<File Id="fil2934B2FC856C8A8D86E4B92EF92AD1B9" KeyPath="yes" Source="$(var.docSrcDir)\xschem_man\simulation.html" />
|
||||
</Component>
|
||||
|
|
@ -8370,6 +8373,7 @@
|
|||
<ComponentRef Id="cmp9B3A7686BB046FC570A7F71F4AD981E3" />
|
||||
<ComponentRef Id="cmp87920616631BEEA016176533E5C41578" />
|
||||
<ComponentRef Id="cmp5B62A7CAE8EECF932F98EB403B5CDD29" />
|
||||
<ComponentRef Id="cmp814223FC22DFF7462DCE79B3829E6FBF" />
|
||||
<ComponentRef Id="cmp9540E3F9B5835A06B30F0AE43A00BDCA" />
|
||||
<ComponentRef Id="cmp5DB828CEC70D5904EB1C1A5DC881F321" />
|
||||
<ComponentRef Id="cmp6506097EF307EF163BD976300B67E723" />
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1342,6 +1342,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
if x0, y0 not given use mouse coordinates </pre>
|
||||
<li><kbd> rotate_in_place</kbd></li><pre>
|
||||
Rotate selected objects around their 0,0 coordinate point </pre>
|
||||
<li><kbd> round_to_n_digits i n</kbd></li><pre>
|
||||
round number 'i' to 'n' digits </pre>
|
||||
<li><kbd> save [fast]</kbd></li><pre>
|
||||
Save schematic if modified. Does not ask confirmation!
|
||||
if 'fast' is given it is passed to save_schematic() to avoid
|
||||
|
|
@ -1506,7 +1508,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<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>
|
||||
<li><kbd> str_replace str rep with [escape]</kbd></li><pre>
|
||||
<li><kbd> str_replace str rep with [escape] [count]</kbd></li><pre>
|
||||
replace 'rep' with 'with' in string 'str'
|
||||
if rep not preceeded by an 'escape' character </pre>
|
||||
<li><kbd> subst_tok str tok newval</kbd></li><pre>
|
||||
|
|
|
|||
|
|
@ -1482,7 +1482,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
|
|||
/* remove tcleval( given in file selector, if any ... */
|
||||
if(strstr(name1, "tcleval(")) {
|
||||
tclev = 1;
|
||||
my_snprintf(name1, S(name1), "%s", str_replace(name1, "tcleval(", "", 0));
|
||||
my_snprintf(name1, S(name1), "%s", str_replace(name1, "tcleval(", "", 0, -1));
|
||||
}
|
||||
dbg(1, "place_symbol(): 2: name1=%s\n",name1);
|
||||
|
||||
|
|
@ -1788,7 +1788,7 @@ const char *get_sym_name(int inst, int ndir, int ext, int abs_path)
|
|||
|
||||
/* instance based symbol selection */
|
||||
sch = tcl_hook2(str_replace(get_tok_value(xctx->inst[inst].prop_ptr,"schematic", 2), "@symname",
|
||||
get_cell(xctx->inst[inst].name, 0), '\\'));
|
||||
get_cell(xctx->inst[inst].name, 0), '\\', -1));
|
||||
|
||||
if(xctx->tok_size) { /* token exists */
|
||||
if(abs_path)
|
||||
|
|
@ -1965,9 +1965,17 @@ void get_additional_symbols(int what)
|
|||
my_strdup(_ALLOC_ID_, &spice_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"spice_sym_def",6));
|
||||
my_strdup(_ALLOC_ID_, &verilog_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"verilog_sym_def",4));
|
||||
my_strdup(_ALLOC_ID_, &vhdl_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"vhdl_sym_def",4));
|
||||
|
||||
dbg(1, "schematic=%s\n", get_tok_value(xctx->inst[i].prop_ptr,"schematic",2));
|
||||
/* resolve schematic=generator.tcl( @n ) where n=11 is defined in instance attrs */
|
||||
my_strdup2(_ALLOC_ID_, &sch,
|
||||
translate3(get_tok_value(xctx->inst[i].prop_ptr,"schematic",2), 1,
|
||||
xctx->inst[i].prop_ptr, NULL, NULL));
|
||||
dbg(1, "sch=%s\n", sch);
|
||||
|
||||
my_strdup2(_ALLOC_ID_, &sch, tcl_hook2(
|
||||
str_replace( get_tok_value(xctx->inst[i].prop_ptr,"schematic",2), "@symname",
|
||||
get_cell(xctx->inst[i].name, 0), '\\')));
|
||||
str_replace(sch, "@symname", get_cell(xctx->inst[i].name, 0), '\\', -1)));
|
||||
|
||||
dbg(1, "get_additional_symbols(): inst=%d sch=%s\n",i, sch);
|
||||
/* schematic does not exist */
|
||||
if(sch[0] && stat(abs_sym_path(sch, ""), &buf)) {
|
||||
|
|
@ -1982,6 +1990,7 @@ void get_additional_symbols(int what)
|
|||
char *symname_attr = NULL;
|
||||
int ignore_schematic = 0;
|
||||
xSymbol *symptr = xctx->inst[i].ptr + xctx->sym;
|
||||
|
||||
my_strdup2(_ALLOC_ID_, &default_schematic, get_tok_value(symptr->prop_ptr,"default_schematic",0));
|
||||
ignore_schematic = !strcmp(default_schematic, "ignore");
|
||||
|
||||
|
|
@ -2081,12 +2090,17 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback)
|
|||
}
|
||||
dbg(1, "get_sch_from_sym(): current_dirname= %s\n", xctx->current_dirname);
|
||||
dbg(1, "get_sch_from_sym(): symbol %s inst=%d web_url=%d\n", sym->name, inst, web_url);
|
||||
if(inst >= 0) my_strdup(_ALLOC_ID_, &str_tmp, get_tok_value(xctx->inst[inst].prop_ptr, "schematic", 2));
|
||||
if(inst >= 0) {
|
||||
/* resolve schematic=generator.tcl( @n ) where n=11 is defined in instance attrs */
|
||||
my_strdup2(_ALLOC_ID_, &str_tmp,
|
||||
translate3(get_tok_value(xctx->inst[inst].prop_ptr,"schematic",2), 1,
|
||||
xctx->inst[inst].prop_ptr, NULL, NULL));
|
||||
}
|
||||
if(!str_tmp) my_strdup2(_ALLOC_ID_, &str_tmp, get_tok_value(sym->prop_ptr, "schematic", 2));
|
||||
if(str_tmp[0]) { /* schematic attribute in symbol or instance was given */
|
||||
/* @symname in schematic attribute will be replaced with symbol name */
|
||||
my_strdup2(_ALLOC_ID_, &sch, tcl_hook2(str_replace(str_tmp, "@symname",
|
||||
get_cell(sym->name, 0), '\\')));
|
||||
get_cell(sym->name, 0), '\\', -1)));
|
||||
if(is_generator(sch)) { /* generator: return as is */
|
||||
my_strncpy(filename, sch, PATH_MAX);
|
||||
is_gen = 1;
|
||||
|
|
|
|||
215
src/callback.c
215
src/callback.c
|
|
@ -497,41 +497,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw_master = 1;
|
||||
}
|
||||
|
||||
/* move cursor1 */
|
||||
/* set cursor position from master graph x-axis */
|
||||
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
||||
double c;
|
||||
|
||||
c = G_X(xctx->mousex);
|
||||
if(gr->logx) c = pow(10, c);
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(c)));
|
||||
} else {
|
||||
xctx->graph_cursor1_x = c;
|
||||
}
|
||||
need_all_redraw = 1;
|
||||
}
|
||||
/* move cursor2 */
|
||||
/* set cursor position from master graph x-axis */
|
||||
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) {
|
||||
double c;
|
||||
int floaters = there_are_floaters();
|
||||
|
||||
c = G_X(xctx->mousex);
|
||||
if(gr->logx) c = pow(10, c);
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(c)));
|
||||
} else {
|
||||
xctx->graph_cursor2_x = c;
|
||||
}
|
||||
if(tclgetboolvar("live_cursor2_backannotate")) {
|
||||
backannotate_at_cursor_b_pos(r, gr);
|
||||
if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */
|
||||
need_fullredraw = 1;
|
||||
} else {
|
||||
need_all_redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(xctx->ui_state & GRAPHPAN) goto finish; /* After GRAPHPAN only need to check Motion events for cursors */
|
||||
if(xctx->mousey_snap < W_Y(gr->gy2)) {
|
||||
xctx->graph_top = 1;
|
||||
|
|
@ -576,7 +547,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor1_x", 0);
|
||||
if(s[0]) {
|
||||
cursor1 = atof(s);
|
||||
cursor1 = atof_eng(s);
|
||||
} else {
|
||||
cursor1 = xctx->graph_cursor1_x;
|
||||
}
|
||||
|
|
@ -595,7 +566,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor2_x", 0);
|
||||
if(s[0]) {
|
||||
cursor2 = atof_spice(s);
|
||||
cursor2 = atof_eng(s);
|
||||
} else {
|
||||
cursor2 = xctx->graph_cursor2_x;
|
||||
}
|
||||
|
|
@ -613,59 +584,91 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
else if(event == ButtonPress && button == Button3) {
|
||||
/* Numerically set cursor position */
|
||||
if(xctx->graph_flags & 2) {
|
||||
double cursor1;
|
||||
double logcursor, cursor;
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor1_x", 0);
|
||||
if(s[0]) {
|
||||
cursor1 = atof_spice(s);
|
||||
cursor = atof_spice(s);
|
||||
} else {
|
||||
cursor1 = xctx->graph_cursor1_x;
|
||||
cursor = xctx->graph_cursor1_x;
|
||||
}
|
||||
} else {
|
||||
cursor1 = xctx->graph_cursor1_x;
|
||||
cursor = xctx->graph_cursor1_x;
|
||||
}
|
||||
logcursor = cursor;
|
||||
if(gr->logx ) {
|
||||
cursor1 = mylog10(cursor1);
|
||||
logcursor = mylog10(cursor);
|
||||
}
|
||||
if(fabs(xctx->mousex - W_X(cursor1)) < 10) {
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor1), NULL);
|
||||
cursor1 = atof_spice(tclresult());
|
||||
if(fabs(xctx->mousex - W_X(logcursor)) < 10) {
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||
cursor = atof_eng(tclresult());
|
||||
if(r->flags & 4) {
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(cursor1)));
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(cursor)));
|
||||
} else {
|
||||
xctx->graph_cursor1_x = cursor1;
|
||||
xctx->graph_cursor1_x = cursor;
|
||||
}
|
||||
event = 0; button = 0; /* avoid further processing ButtonPress that might set GRAPHPAN */
|
||||
}
|
||||
need_all_redraw = 1;
|
||||
}
|
||||
/* Numerically set cursor position *** DO NOT PUT AN `else if` BELOW *** */
|
||||
if(xctx->graph_flags & 4) {
|
||||
double logcursor, cursor;
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor2_x", 0);
|
||||
if(s[0]) {
|
||||
cursor = atof_spice(s);
|
||||
} else {
|
||||
cursor = xctx->graph_cursor2_x;
|
||||
}
|
||||
} else {
|
||||
cursor = xctx->graph_cursor2_x;
|
||||
}
|
||||
logcursor = cursor;
|
||||
if(gr->logx) {
|
||||
logcursor = mylog10(cursor);
|
||||
}
|
||||
if(fabs(xctx->mousex - W_X(logcursor)) < 10) {
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||
cursor = atof_eng(tclresult());
|
||||
if(r->flags & 4) {
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(cursor)));
|
||||
} else {
|
||||
xctx->graph_cursor2_x = cursor;
|
||||
}
|
||||
event = 0; button = 0; /* avoid further processing ButtonPress that might set GRAPHPAN */
|
||||
}
|
||||
need_fullredraw = 1;
|
||||
}
|
||||
/* Numerically set cursor position */
|
||||
if(xctx->graph_flags & 4) {
|
||||
double cursor2;
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor2_x", 0);
|
||||
if(s[0]) {
|
||||
cursor2 = atof_spice(s);
|
||||
} else {
|
||||
cursor2 = xctx->graph_cursor2_x;
|
||||
}
|
||||
} else {
|
||||
cursor2 = xctx->graph_cursor2_x;
|
||||
/* Numerically set hcursor position *** DO NOT PUT AN `else if` BELOW *** */
|
||||
if(xctx->graph_flags & 128) {
|
||||
double logcursor, cursor;
|
||||
logcursor = cursor = gr->hcursor1_y;
|
||||
if(gr->logy ) {
|
||||
logcursor = mylog10(cursor);
|
||||
}
|
||||
if(gr->logx) {
|
||||
cursor2 = mylog10(cursor2);
|
||||
}
|
||||
if(fabs(xctx->mousex - W_X(cursor2)) < 10) {
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor2), NULL);
|
||||
cursor2 = atof_spice(tclresult());
|
||||
if(r->flags & 4) {
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(cursor2)));
|
||||
} else {
|
||||
xctx->graph_cursor2_x = cursor2;
|
||||
}
|
||||
if(fabs(xctx->mousey - W_Y(logcursor)) < 10) {
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||
cursor = atof_eng(tclresult());
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", dtoa(cursor)));
|
||||
event = 0; button = 0; /* avoid further processing ButtonPress that might set GRAPHPAN */
|
||||
}
|
||||
need_fullredraw = 1;
|
||||
need_redraw_master = 1;
|
||||
}
|
||||
/* Numerically set hcursor position *** DO NOT PUT AN `else if` BELOW *** */
|
||||
if(xctx->graph_flags & 256) {
|
||||
double logcursor, cursor;
|
||||
logcursor = cursor = gr->hcursor2_y;
|
||||
if(gr->logy ) {
|
||||
logcursor = mylog10(cursor);
|
||||
}
|
||||
if(fabs(xctx->mousey - W_Y(logcursor)) < 10) {
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||
cursor = atof_eng(tclresult());
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", dtoa(cursor)));
|
||||
event = 0; button = 0; /* avoid further processing ButtonPress that might set GRAPHPAN */
|
||||
}
|
||||
need_redraw_master = 1;
|
||||
}
|
||||
}
|
||||
else if(event == -3 && button == Button1) {
|
||||
|
|
@ -914,38 +917,54 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(event == ButtonPress && button == Button3) {
|
||||
/* Numerically set hcursor position */
|
||||
if(xctx->graph_flags & 128) {
|
||||
double cursor;
|
||||
cursor = gr->hcursor1_y;
|
||||
if(gr->logy ) {
|
||||
cursor = mylog10(cursor);
|
||||
|
||||
|
||||
|
||||
/* move cursor1 */
|
||||
/* set cursor position from master graph x-axis */
|
||||
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
||||
double c;
|
||||
|
||||
/* selected or locked or master */
|
||||
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
||||
c = G_X(xctx->mousex);
|
||||
if(gr->logx) c = pow(10, c);
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(c)));
|
||||
} else {
|
||||
xctx->graph_cursor1_x = c;
|
||||
}
|
||||
if(fabs(xctx->mousey - W_Y(cursor)) < 10) {
|
||||
xctx->ui_state &= ~GRAPHPAN; /* we are setting a cursor so clear GRAPHPAN set before */
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||
cursor = atof_spice(tclresult());
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", dtoa(cursor)));
|
||||
}
|
||||
need_redraw = 1;
|
||||
}
|
||||
/* Numerically set hcursor position */
|
||||
if(xctx->graph_flags & 256) {
|
||||
double cursor;
|
||||
cursor = gr->hcursor2_y;
|
||||
if(gr->logy ) {
|
||||
cursor = mylog10(cursor);
|
||||
}
|
||||
if(fabs(xctx->mousey - W_Y(cursor)) < 10) {
|
||||
xctx->ui_state &= ~GRAPHPAN; /* we are setting a cursor so clear GRAPHPAN set before */
|
||||
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||
cursor = atof_spice(tclresult());
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", dtoa(cursor)));
|
||||
}
|
||||
need_redraw = 1;
|
||||
need_all_redraw = 1;
|
||||
}
|
||||
}
|
||||
/* move cursor2 */
|
||||
/* set cursor position from master graph x-axis */
|
||||
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) {
|
||||
double c;
|
||||
int floaters = there_are_floaters();
|
||||
|
||||
/* selected or locked or master */
|
||||
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
||||
c = G_X(xctx->mousex);
|
||||
if(gr->logx) c = pow(10, c);
|
||||
if(r->flags & 4) { /* private_cursor */
|
||||
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(c)));
|
||||
} else {
|
||||
xctx->graph_cursor2_x = c;
|
||||
}
|
||||
if(tclgetboolvar("live_cursor2_backannotate")) {
|
||||
backannotate_at_cursor_b_pos(r, gr);
|
||||
if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */
|
||||
need_fullredraw = 1;
|
||||
} else {
|
||||
need_all_redraw = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
else if(event == ButtonPress && button == Button5 && !(state & ShiftMask)) {
|
||||
double delta;
|
||||
/* vertical move of waveforms with mouse wheel */
|
||||
|
|
|
|||
21
src/draw.c
21
src/draw.c
|
|
@ -2915,21 +2915,21 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->hcursor1_y = gr->hcursor2_y = 0.0;
|
||||
val = get_tok_value(r->prop_ptr,"hcursor1_y", 0);
|
||||
if(val[0]) {
|
||||
gr->hcursor1_y = atof_spice(val);
|
||||
gr->hcursor1_y = atof_eng(val);
|
||||
xctx->graph_flags |= 128;
|
||||
}
|
||||
val = get_tok_value(r->prop_ptr,"hcursor2_y", 0);
|
||||
if(val[0]) {
|
||||
gr->hcursor2_y = atof_spice(val);
|
||||
gr->hcursor2_y = atof_eng(val);
|
||||
xctx->graph_flags |= 256;
|
||||
}
|
||||
if(!skip) {
|
||||
gr->gx1 = 0;
|
||||
gr->gx2 = 1e-6;
|
||||
val = get_tok_value(r->prop_ptr,"x1", 0);
|
||||
if(val[0]) gr->gx1 = atof_spice(val);
|
||||
if(val[0]) gr->gx1 = atof_eng(val);
|
||||
val = get_tok_value(r->prop_ptr,"x2", 0);
|
||||
if(val[0]) gr->gx2 = atof_spice(val);
|
||||
if(val[0]) gr->gx2 = atof_eng(val);
|
||||
if(gr->gx1 == gr->gx2) gr->gx2 += 1e-6;
|
||||
gr->gw = gr->gx2 - gr->gx1;
|
||||
}
|
||||
|
|
@ -3012,17 +3012,17 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
val = get_tok_value(r->prop_ptr,"logy", 0);
|
||||
if(val[0] == '1') gr->logy = 1;
|
||||
val = get_tok_value(r->prop_ptr,"y1", 0);
|
||||
if(val[0]) gr->gy1 = atof_spice(val);
|
||||
if(val[0]) gr->gy1 = atof_eng(val);
|
||||
val = get_tok_value(r->prop_ptr,"y2", 0);
|
||||
if(val[0]) gr->gy2 = atof_spice(val);
|
||||
if(val[0]) gr->gy2 = atof_eng(val);
|
||||
if(gr->gy1 == gr->gy2) gr->gy2 += 1.0;
|
||||
val = get_tok_value(r->prop_ptr,"digital", 0);
|
||||
if(val[0]) gr->digital = atoi(val);
|
||||
if(gr->digital) {
|
||||
val = get_tok_value(r->prop_ptr,"ypos1", 0);
|
||||
if(val[0]) gr->ypos1 = atof_spice(val);
|
||||
if(val[0]) gr->ypos1 = atof_eng(val);
|
||||
val = get_tok_value(r->prop_ptr,"ypos2", 0);
|
||||
if(val[0]) gr->ypos2 = atof_spice(val);
|
||||
if(val[0]) gr->ypos2 = atof_eng(val);
|
||||
if(gr->ypos2 == gr->ypos1) gr->ypos2 += 1.0;
|
||||
}
|
||||
gr->posh = gr->ypos2 - gr->ypos1;
|
||||
|
|
@ -3057,6 +3057,7 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->digtxtsizelab = 0.000900 * fabs( gr->h / gr->posh * gr->gh );
|
||||
else
|
||||
gr->digtxtsizelab = 0.001200 * fabs( gr->h / gr->posh * gr->gh );
|
||||
gr->txtsizelab *= gr->magx;
|
||||
|
||||
/* x axis, y axis text sizes */
|
||||
gr->txtsizey = gr->h / gr->divy * 0.0095;
|
||||
|
|
@ -3783,7 +3784,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor1_x", 0);
|
||||
if(s[0]) {
|
||||
cursor1 = atof_spice(s);
|
||||
cursor1 = atof_eng(s);
|
||||
} else {
|
||||
cursor1 = xctx->graph_cursor1_x;
|
||||
}
|
||||
|
|
@ -3794,7 +3795,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
if(r->flags & 4) { /* private_cursor */
|
||||
const char *s = get_tok_value(r->prop_ptr, "cursor2_x", 0);
|
||||
if(s[0]) {
|
||||
cursor2 = atof_spice(s);
|
||||
cursor2 = atof_eng(s);
|
||||
} else {
|
||||
cursor2 = xctx->graph_cursor2_x;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -554,20 +554,20 @@ char *dtoa_eng(double i)
|
|||
size_t n;
|
||||
int suffix = 0;
|
||||
double absi = fabs(i);
|
||||
|
||||
if (absi == 0.0) { suffix = 0;}
|
||||
else if(absi < 1e-23) { i = 0; suffix = 0;}
|
||||
else if(absi >=1e12) { i /= 1e12; suffix = 'T';}
|
||||
else if(absi >=1e9) { i /= 1e9 ; suffix = 'G';}
|
||||
else if(absi >=1e6) { i /= 1e6 ; suffix = 'M';}
|
||||
else if(absi >=1e3) { i /= 1e3 ; suffix = 'k';}
|
||||
else if(absi >=0.1) { suffix = 0;}
|
||||
else if(absi >=1e-3) { i *= 1e3 ; suffix = 'm';}
|
||||
else if(absi >=1e-6) { i *= 1e6 ; suffix = 'u';}
|
||||
else if(absi >=1e-9) { i *= 1e9 ; suffix = 'n';}
|
||||
else if(absi >=1e-12) { i *= 1e12; suffix = 'p';}
|
||||
else if(absi >=1e-15) { i *= 1e15; suffix = 'f';}
|
||||
else { i *= 1e18; suffix = 'a';}
|
||||
dbg(1, "dtoa_eng(): i=%.17g, absi=%.17g\n", i, absi);
|
||||
if (absi == 0.0) { suffix = 0 ;}
|
||||
else if(absi < 0.999999e-23) { i = 0.0 ; suffix = 0 ;}
|
||||
else if(absi > 0.999999e12) { i /= 1e12; suffix = 'T';}
|
||||
else if(absi > 0.999999e9) { i /= 1e9 ; suffix = 'G';}
|
||||
else if(absi > 0.999999e6) { i /= 1e6 ; suffix = 'M';}
|
||||
else if(absi > 0.999999e3) { i /= 1e3 ; suffix = 'k';}
|
||||
else if(absi > 0.999999e-1) { suffix = 0; }
|
||||
else if(absi > 0.999999e-3) { i *= 1e3 ; suffix = 'm';}
|
||||
else if(absi > 0.999999e-6) { i *= 1e6 ; suffix = 'u';}
|
||||
else if(absi > 0.999999e-9) { i *= 1e9 ; suffix = 'n';}
|
||||
else if(absi > 0.999999e-12) { i *= 1e12; suffix = 'p';}
|
||||
else if(absi > 0.999999e-15) { i *= 1e15; suffix = 'f';}
|
||||
else { i *= 1e18; suffix = 'a';}
|
||||
if(suffix) {
|
||||
n = my_snprintf(s, S(s), "%.5g%c", i, suffix);
|
||||
} else {
|
||||
|
|
@ -1481,7 +1481,7 @@ int drc_check(int i)
|
|||
const char *result;
|
||||
const char *replace_res;
|
||||
|
||||
replace_res = str_replace(res, "@symname", xctx->sym[xctx->inst[j].ptr].name, '\\');
|
||||
replace_res = str_replace(res, "@symname", xctx->sym[xctx->inst[j].ptr].name, '\\', -1);
|
||||
result = tcleval(replace_res);
|
||||
if(result && result[0]) {
|
||||
ret = 1;
|
||||
|
|
@ -1799,8 +1799,10 @@ void change_elem_order(int n)
|
|||
if(modified) set_modify(1);
|
||||
}
|
||||
}
|
||||
/* replace substring 'rep' in 'str' with 'with', if 'rep' not preceeded by an 'escape' char */
|
||||
char *str_replace(const char *str, const char *rep, const char *with, int escape)
|
||||
/* replace substring 'rep' in 'str' with 'with', if 'rep' not preceeded by an 'escape' char
|
||||
* 'count' indicates the number of replacements to do or all if -1
|
||||
*/
|
||||
char *str_replace(const char *str, const char *rep, const char *with, int escape, int count)
|
||||
{
|
||||
static char *result = NULL;
|
||||
static size_t size=0;
|
||||
|
|
@ -1809,6 +1811,7 @@ char *str_replace(const char *str, const char *rep, const char *with, int escape
|
|||
size_t with_len;
|
||||
const char *s = str;
|
||||
int cond;
|
||||
int replacements = 0;
|
||||
|
||||
if(s==NULL || rep == NULL || with == NULL || rep[0] == '\0') {
|
||||
my_free(_ALLOC_ID_, &result);
|
||||
|
|
@ -1825,11 +1828,14 @@ char *str_replace(const char *str, const char *rep, const char *with, int escape
|
|||
while(*s) {
|
||||
STR_ALLOC(&result, result_pos + with_len + 1, &size);
|
||||
|
||||
cond = ((s == str) || ((*(s - 1) != escape))) && (!strncmp(s, rep, rep_len));
|
||||
cond = (count == -1 || replacements < count) &&
|
||||
((s == str) || ((*(s - 1) != escape))) &&
|
||||
(!strncmp(s, rep, rep_len));
|
||||
if(cond) {
|
||||
my_strncpy(result + result_pos, with, with_len + 1);
|
||||
result_pos += with_len;
|
||||
s += rep_len;
|
||||
replacements++;
|
||||
} else {
|
||||
result[result_pos++] = *s++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4589,6 +4589,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
/* round_to_n_digits i n
|
||||
* round number 'i' to 'n' digits */
|
||||
else if(!strcmp(argv[1], "round_to_n_digits"))
|
||||
{
|
||||
double r;
|
||||
if(argc > 3) {
|
||||
r = round_to_n_digits(atof(argv[2]), atoi(argv[3]));
|
||||
Tcl_SetResult(interp, dtoa(r), TCL_VOLATILE);
|
||||
}
|
||||
}
|
||||
|
||||
else { cmd_found = 0;}
|
||||
break;
|
||||
case 's': /*----------------------------------------------*/
|
||||
|
|
@ -5538,15 +5549,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
xctx->ui_state2 = MENUSTARTSNAPWIRE;
|
||||
}
|
||||
|
||||
/* str_replace str rep with [escape]
|
||||
/* str_replace str rep with [escape] [count]
|
||||
* replace 'rep' with 'with' in string 'str'
|
||||
* if rep not preceeded by an 'escape' character */
|
||||
else if(!strcmp(argv[1], "str_replace"))
|
||||
{
|
||||
int escape = 0;
|
||||
int escape = 0, count = -1;
|
||||
if(argc > 5) escape = argv[5][0];
|
||||
if(argc > 6) count = atoi(argv[6]);
|
||||
if(argc > 4) {
|
||||
Tcl_AppendResult(interp, str_replace(argv[2], argv[3], argv[4], escape), NULL);
|
||||
Tcl_AppendResult(interp, str_replace(argv[2], argv[3], argv[4], escape, count), NULL);
|
||||
} else {
|
||||
Tcl_SetResult(interp, "Missing arguments", TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
|
|
|
|||
111
src/token.c
111
src/token.c
|
|
@ -67,7 +67,7 @@ const char *tcl_hook2(const char *cmd)
|
|||
return empty;
|
||||
}
|
||||
if(strstr(cmd, "tcleval(") == cmd) {
|
||||
unescaped_res = str_replace(cmd, "\\}", "}", 0);
|
||||
unescaped_res = str_replace(cmd, "\\}", "}", 0, -1);
|
||||
tclvareval("tclpropeval2 {", unescaped_res, "}" , NULL);
|
||||
my_strdup2(_ALLOC_ID_, &result, tclresult());
|
||||
/* dbg(0, "tcl_hook2: return: %s\n", result);*/
|
||||
|
|
@ -1972,7 +1972,7 @@ void print_spice_subckt_nodes(FILE *fd, int symbol)
|
|||
|
||||
/* can not do this, since @symname is used as a token later in format parser */
|
||||
/* my_strdup(_ALLOC_ID_, &format1,
|
||||
* str_replace(format1, "@symname", get_cell(xctx->sym[symbol].name, 0), '\\')); */
|
||||
* str_replace(format1, "@symname", get_cell(xctx->sym[symbol].name, 0), '\\', -1)); */
|
||||
|
||||
if(format1 && strstr(format1, "tcleval(") == format1) {
|
||||
tclres = tcl_hook2(format1);
|
||||
|
|
@ -3645,6 +3645,57 @@ static char *get_pin_attr(const char *token, int inst, int engineering)
|
|||
return value;
|
||||
}
|
||||
|
||||
const char *spice_get_node(const char *token)
|
||||
{
|
||||
const char *pos;
|
||||
|
||||
if((pos = strstr(token, "@spice_get_node "))) {
|
||||
char *node = NULL;
|
||||
char *token2 = NULL;
|
||||
int idx;
|
||||
char sp;
|
||||
int n;
|
||||
size_t len;
|
||||
double val = 0.0;
|
||||
const char *valstr;
|
||||
const char *s;
|
||||
|
||||
dbg(1, "token=%s\n", token);
|
||||
node = my_malloc(_ALLOC_ID_, strlen(token) + 1);
|
||||
n = sscanf(pos, "%*[^ ] %[^ ]%c", node, &sp);
|
||||
len = strlen(node);
|
||||
dbg(1, "node=%s, n=%d, sp=|%c|\n", node, n, sp);
|
||||
idx = get_raw_index(node, NULL);
|
||||
if(idx >= 0) {
|
||||
val = xctx->raw->cursor_b_val[idx];
|
||||
}
|
||||
if(!strcmp(node, "0") || !my_strcasecmp(node, "GND")) {
|
||||
valstr = "0.0";
|
||||
} else if(idx < 0) {
|
||||
valstr = "-";
|
||||
} else {
|
||||
/* always use engineering as these tokens are generated from single
|
||||
* @spice_get_node(...) patterns */
|
||||
valstr = dtoa_eng(val);
|
||||
}
|
||||
dbg(1, "valstr=%s\n", valstr);
|
||||
my_strdup2(_ALLOC_ID_, &token2, str_replace(token, "@spice_get_node ", "", 0, 1));
|
||||
dbg(1, "token2=%s\n", token2);
|
||||
if(n == 2 && sp == ' ') {
|
||||
node[len] = ' ';
|
||||
node[len + 1] = '\0';
|
||||
}
|
||||
s = str_replace(token2, node, valstr, 0, 1);
|
||||
dbg(1, "s=%s\n", s);
|
||||
my_free(_ALLOC_ID_, &token2);
|
||||
my_free(_ALLOC_ID_, &node);
|
||||
return s;
|
||||
} else {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* substitute given tokens in a string with their corresponding values */
|
||||
/* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
|
||||
/* if s==NULL return emty string */
|
||||
|
|
@ -3902,6 +3953,31 @@ const char *translate(int inst, const char* s)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* copy as is: processed by spice_get_node() later
|
||||
* the format is "some_text@spice_get_node <spice_node> some_additional_text"
|
||||
* Examples:
|
||||
* Id=@spice_get_node i(\@m.@path@spiceprefix@name\.msky130_fd_pr__@model\[id])
|
||||
* will translate to:
|
||||
* Id=6.6177u
|
||||
* Id=@spice_get_node i(\@m.@path@spiceprefix@name\.msky130_fd_pr__@model\[id]) A
|
||||
* will translate to:
|
||||
* Id=6.6177uA
|
||||
* note the required separator spaces around the spice node. Spaces are used here as
|
||||
* separators since spice nodes don't allow spaces.
|
||||
* escapes are used for 2 reasons:
|
||||
* mark a @ as a literal character instead of a the start of a @var token to be substituted
|
||||
* mark the end of a @var, like for example @var\iable. In this case @var will
|
||||
* be substituted by xschem instead of @variable
|
||||
*
|
||||
* caveats: only one @spice_get_node is allowed in a string
|
||||
*/
|
||||
else if(strcmp(token,"@spice_get_node")==0 )
|
||||
{
|
||||
STR_ALLOC(&result, 15 + result_pos, &size);
|
||||
memcpy(result+result_pos, token, 16);
|
||||
result_pos += 15;
|
||||
}
|
||||
else if(strncmp(token,"@spice_get_voltage(", 19)==0 )
|
||||
{
|
||||
int start_level; /* hierarchy level where waves were loaded */
|
||||
|
|
@ -3914,7 +3990,7 @@ const char *translate(int inst, const char* s)
|
|||
char *global_net;
|
||||
size_t len;
|
||||
int idx, n, multip;
|
||||
double val;
|
||||
double val = 0.0;
|
||||
const char *valstr;
|
||||
tmp = strlen(token) + 1;
|
||||
if(path) {
|
||||
|
|
@ -3956,8 +4032,8 @@ const char *translate(int inst, const char* s)
|
|||
len = 3;
|
||||
} else if(idx < 0) {
|
||||
valstr = "-";
|
||||
xctx->tok_size = 5;
|
||||
len = 5;
|
||||
xctx->tok_size = 1;
|
||||
len = 1;
|
||||
} else {
|
||||
/* always use engineering as these tokens are generated from single
|
||||
* @spice_get_voltage patterns */
|
||||
|
|
@ -3986,7 +4062,7 @@ const char *translate(int inst, const char* s)
|
|||
char *dev = NULL;
|
||||
size_t len;
|
||||
int idx, n;
|
||||
double val;
|
||||
double val = 0.0;
|
||||
const char *valstr;
|
||||
tmp = strlen(token) + 1;
|
||||
if(path) {
|
||||
|
|
@ -4029,9 +4105,9 @@ const char *translate(int inst, const char* s)
|
|||
val = xctx->raw->cursor_b_val[idx];
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "undef";
|
||||
xctx->tok_size = 5;
|
||||
len = 5;
|
||||
valstr = "-";
|
||||
xctx->tok_size = 1;
|
||||
len = 1;
|
||||
} else {
|
||||
/* always use engineering as these tokens are generated from single
|
||||
* @spice_get_voltage patterns */
|
||||
|
|
@ -4093,9 +4169,9 @@ const char *translate(int inst, const char* s)
|
|||
idx1 = get_raw_index(fqnet1, NULL);
|
||||
idx2 = get_raw_index(fqnet2, NULL);
|
||||
if( (!gnd1 && idx1 < 0) || (!gnd2 && idx2 < 0) ) {
|
||||
valstr = "";
|
||||
xctx->tok_size = 0;
|
||||
len = 0;
|
||||
valstr = "-";
|
||||
xctx->tok_size = 1;
|
||||
len = 1;
|
||||
} else {
|
||||
double val1 = gnd1 ? 0.0 : xctx->raw->cursor_b_val[idx1];
|
||||
double val2 = gnd2 ? 0.0 : xctx->raw->cursor_b_val[idx2];
|
||||
|
|
@ -4126,7 +4202,7 @@ const char *translate(int inst, const char* s)
|
|||
char *dev = NULL;
|
||||
size_t len;
|
||||
int idx;
|
||||
double val;
|
||||
double val = 0.0;
|
||||
const char *valstr;
|
||||
if(path) {
|
||||
int skip = 0;
|
||||
|
|
@ -4166,9 +4242,9 @@ const char *translate(int inst, const char* s)
|
|||
val = xctx->raw->cursor_b_val[idx];
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "";
|
||||
xctx->tok_size = 0;
|
||||
len = 0;
|
||||
valstr = "-";
|
||||
xctx->tok_size = 1;
|
||||
len = 1;
|
||||
} else {
|
||||
valstr = engineering ? dtoa_eng(val) : dtoa(val);
|
||||
len = xctx->tok_size;
|
||||
|
|
@ -4286,7 +4362,8 @@ const char *translate(int inst, const char* s)
|
|||
|
||||
/* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
|
||||
* can be calculated */
|
||||
my_strdup2(_ALLOC_ID_, &translated_tok, tcl_hook2(result));
|
||||
my_strdup2(_ALLOC_ID_, &translated_tok, spice_get_node(tcl_hook2(result)));
|
||||
|
||||
return translated_tok;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ static void delete_schematic_data(int delete_pixmap)
|
|||
/* delete instances, wires, lines, rects, arcs, polys, texts, hash_inst, hash_wire,
|
||||
* inst & wire .node fields, instance name hash */
|
||||
remove_symbols();
|
||||
str_replace(NULL, NULL, NULL, 0);
|
||||
str_replace(NULL, NULL, NULL, 0, -1);
|
||||
escape_chars(NULL, "");
|
||||
sanitize(NULL);
|
||||
is_generator(NULL);
|
||||
|
|
|
|||
|
|
@ -1601,6 +1601,7 @@ extern Ptr_hashentry *ptr_hash_lookup(Ptr_hashtable *hashtable,
|
|||
extern char *trim_chars(const char *str, const char *sep);
|
||||
extern char *find_nth(const char *str, const char *sep, const char *quote, int keep_quote, int n);
|
||||
extern int isonlydigit(const char *s);
|
||||
extern const char *spice_get_node(const char *token);
|
||||
extern const char *translate(int inst, const char* s);
|
||||
extern const char* translate2(Lcc *lcc, int level, char* s);
|
||||
extern const char *translate3(const char* s, int eat_escapes, const char *s1, const char *s2, const char *s3);
|
||||
|
|
@ -1728,7 +1729,7 @@ extern int drc_check(int i);
|
|||
extern void change_elem_order(int n);
|
||||
extern int is_generator(const char *name);
|
||||
extern char *str_chars_replace(const char *str, const char *replace_set, const char with);
|
||||
extern char *str_replace(const char *str, const char *rep, const char *with, int escape);
|
||||
extern char *str_replace(const char *str, const char *rep, const char *with, int escape, int count);
|
||||
extern char *escape_chars(const char *source, const char *charset);
|
||||
extern int set_different_token(char **s,const char *new, const char *old);
|
||||
extern void print_hilight_net(int show);
|
||||
|
|
|
|||
Loading…
Reference in New Issue