merged in fast_raw_read branch

This commit is contained in:
stefan schippers 2023-10-11 14:05:27 +02:00
parent 3a25109fe1
commit 9b4bd44fd0
20 changed files with 716 additions and 551 deletions

View File

@ -1949,10 +1949,10 @@ int descend_schematic(int instnumber)
p_n_s1 = pin_node;
for(k = 1; k<=mult; ++k) {
single_p = my_strtok_r(p_n_s1, ",", "", &p_n_s2);
single_p = my_strtok_r(p_n_s1, ",", "", 0, &p_n_s2);
p_n_s1 = NULL;
my_strdup2(_ALLOC_ID_, &single_n,
find_nth(net_node, ",", ((inst_number - 1) * mult + k - 1) % net_mult + 1));
find_nth(net_node, ",", "", 0, ((inst_number - 1) * mult + k - 1) % net_mult + 1));
single_n_ptr = single_n;
if(single_n_ptr[0] == '#') {
if(mult > 1) {
@ -1974,7 +1974,7 @@ int descend_schematic(int instnumber)
get_tok_value((xctx->inst[n].ptr+ xctx->sym)->prop_ptr, "template", 0));
dbg(1,"descend_schematic(): inst_number=%d\n", inst_number);
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], find_nth(str, ",", inst_number));
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], find_nth(str, ",", "", 0, inst_number));
my_free(_ALLOC_ID_, &str);
dbg(1,"descend_schematic(): inst_number=%d\n", inst_number);
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], ".");

View File

@ -196,7 +196,8 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
double start, end;
int sweepvar_wrap = 0, sweep_idx;
double xx, cursor2; /* xx is the p-th sweep variable value, cursor2 is cursor 'b' x position */
sweep_idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", 1));
Raw *raw = xctx->raw;
sweep_idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1));
if(sweep_idx < 0) sweep_idx = 0;
cursor2 = xctx->graph_cursor2_x;
start = (gr->gx1 <= gr->gx2) ? gr->gx1 : gr->gx2;
@ -211,15 +212,15 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
if(dataset < 0) dataset = 0; /* if all datasets are plotted use first for backannotation */
dbg(1, "dataset=%d\n", dataset);
ofs = 0;
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
for(dset = 0 ; dset < raw->datasets; dset++) {
double prev_x, prev_prev_x;
int cnt=0, wrap;
register SPICE_DATA *gv = xctx->graph_values[sweep_idx];
register SPICE_DATA *gv = raw->values[sweep_idx];
int s=0;
first = -1;
prev_prev_x = prev_x = 0;
last = ofs;
for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) {
for(p = ofs ; p < ofs + raw->npoints[dset]; p++) {
xx = gv[p];
wrap = ( cnt > 1 && XSIGN(xx - prev_x) != XSIGN(prev_x - prev_prev_x));
if(wrap) {
@ -232,13 +233,13 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
xx, cursor2, first, last, start, end, p, wrap, sweepvar_wrap, ofs);
if(first == -1) first = p;
if(p == first) {
if(xx == cursor2) {dset = xctx->graph_datasets; break;}
if(xx == cursor2) {dset = raw->datasets; break;}
s = XSIGN0(xx - cursor2);
dbg(1, "s=%d\n", s);
} else {
int ss = XSIGN0(xx - cursor2);
dbg(1, "s=%d, ss=%d\n", s, ss);
if(ss != s) {dset = xctx->graph_datasets; break;}
if(ss != s) {dset = raw->datasets; break;}
}
last = p;
}
@ -246,9 +247,9 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
} /* if(xx >= start && xx <= end) */
prev_prev_x = prev_x;
prev_x = xx;
} /* for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) */
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
/* offset pointing to next dataset */
ofs += xctx->graph_npoints[dset];
ofs += raw->npoints[dset];
sweepvar_wrap++;
} /* for(dset...) */
@ -257,22 +258,22 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
if(p > last) {
double sweep0, sweep1;
p = last;
sweep0 = xctx->graph_values[sweep_idx][first];
sweep1 = xctx->graph_values[sweep_idx][p];
sweep0 = raw->values[sweep_idx][first];
sweep1 = raw->values[sweep_idx][p];
if(fabs(sweep0 - cursor2) < fabs(sweep1 - cursor2)) {
p = first;
}
}
dbg(1, "xx=%g, p=%d\n", xx, p);
tcleval("array unset ngspice::ngspice_data");
xctx->graph_annotate_p = p;
for(i = 0; i < xctx->graph_nvars; ++i) {
raw->annot_p = p;
for(i = 0; i < raw->nvars; ++i) {
char s[100];
my_snprintf(s, S(s), "%.4g", xctx->graph_values[i][p]);
dbg(1, "%s = %g\n", xctx->graph_names[i], xctx->graph_values[i][p]);
tclvareval("array set ngspice::ngspice_data [list {", xctx->graph_names[i], "} ", s, "]", NULL);
my_snprintf(s, S(s), "%.4g", raw->values[i][p]);
dbg(1, "%s = %g\n", raw->names[i], raw->values[i][p]);
tclvareval("array set ngspice::ngspice_data [list {", raw->names[i], "} ", s, "]", NULL);
}
tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( xctx->graph_nvars), NULL);
tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( raw->nvars), NULL);
tclvareval("set ngspice::ngspice_data(n\\ points) 1", NULL);
}
}
@ -339,6 +340,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
int track_dset = -2; /* used to find dataset of closest wave to mouse if 't' is pressed */
xRect *r = NULL;
if(!xctx->raw) return 0;
rstate = state; /* rstate does not have ShiftMask bit, so easier to test for KeyPress events */
rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sifficient */
@ -440,7 +442,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
need_all_redraw = 1;
}
} else {
xctx->graph_annotate_p = -1;
xctx->raw->annot_p = -1;
/* need_all_redraw = 1; */
redraw_all_at_end = 1;
}
@ -504,13 +506,13 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
/* parameters for absolute positioning by mouse drag in bottom graph area */
if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
int idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", 1));
int idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1));
int dset = dataset == -1 ? 0 : dataset;
double wwx1, wwx2, pp, delta, ccx, ddx;
if(idx < 0 ) idx = 0;
delta = gr->gw;
wwx1 = get_raw_value(dset, idx, 0);
wwx2 = get_raw_value(dset, idx, xctx->graph_npoints[dset] - 1);
wwx2 = get_raw_value(dset, idx, xctx->raw->npoints[dset] - 1);
if(gr->logx) {
wwx1 = mylog10(wwx1);
wwx2 = mylog10(wwx2);
@ -544,7 +546,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
gr->gx2 = gr->master_gx2;
gr->gw = gr->master_gw;
setup_graph_data(i, 1, gr); /* skip flag set, no reload x1 and x2 fields */
if(gr->dataset >= 0 && gr->dataset < xctx->graph_datasets) dataset =gr->dataset;
if(gr->dataset >= 0 /* && gr->dataset < xctx->raw->datasets */) dataset =gr->dataset;
else dataset = -1;
/* destroy / show measurement widget */
if(i == xctx->graph_master) {
@ -887,7 +889,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
}
}
else if(key == 'f') {
if(xctx->graph_values) {
if(xctx->raw && xctx->raw->values) {
if(xctx->graph_left) { /* full Y zoom*/
if(i == xctx->graph_master) {
need_redraw = graph_fullyzoom(r, gr, dataset);
@ -898,26 +900,26 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
need_redraw = graph_fullxzoom(r, gr, dataset);
}
}
} /* graph_values */
} /* raw->values */
} /* key == 'f' */
/* absolute positioning by mouse drag in bottom graph area */
else if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
if(xctx->graph_values) {
if(xctx->raw && xctx->raw->values) {
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
/*
* this calculation is done in 1st loop, only for master graph
* and applied to all locked graphs
int idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", 1));
int idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1));
int dset = dataset == -1 ? 0 : dataset;
double wwx1, wwx2, pp, delta, ccx, ddx;
if(idx < 0 ) idx = 0;
delta = gr->gw;
wwx1 = get_raw_value(dset, idx, 0);
wwx2 = get_raw_value(dset, idx, xctx->graph_npoints[dset] - 1);
wwx2 = get_raw_value(dset, idx, xctx->raw->npoints[dset] - 1);
if(gr->logx) {
wwx1 = mylog10(wwx1);
wwx2 = mylog10(wwx2);
@ -2744,80 +2746,80 @@ int rstate; /* (reduced state, without ShiftMask) */
if(xctx->last_command == STARTWIRE) start_wire(mx, my);
break;
}
if(xctx->ui_state & MENUSTARTWIRECUT) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT)) {
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1);
xctx->ui_state &=~MENUSTARTWIRECUT;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTWIRECUT2) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT2)) {
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0);
xctx->ui_state &=~MENUSTARTWIRECUT2;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTMOVE) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTMOVE)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
/* stretch nets that land on selected instance pins if connect_by_kissing == 2 */
/* select_attached_nets(); */
move_objects(START,0,0,0);
xctx->ui_state &=~MENUSTARTMOVE;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTWIRE) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
new_wire(PLACE, xctx->mousex_snap, xctx->mousey_snap);
xctx->ui_state &=~MENUSTARTWIRE;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTSNAPWIRE) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTSNAPWIRE)) {
double x, y;
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
xctx->mx_double_save = my_round(x / c_snap) * c_snap;
xctx->my_double_save = my_round(y / c_snap) * c_snap;
new_wire(PLACE, x, y);
xctx->ui_state &=~MENUSTARTSNAPWIRE;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTLINE) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTLINE)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
new_line(PLACE);
xctx->ui_state &=~MENUSTARTLINE;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTRECT) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTRECT)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
new_rect(PLACE);
xctx->ui_state &=~MENUSTARTRECT;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTPOLYGON) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTPOLYGON)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
new_polygon(PLACE);
xctx->ui_state &=~MENUSTARTPOLYGON;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTARC) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTARC)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
new_arc(PLACE, 180.);
xctx->ui_state &=~MENUSTARTARC;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTCIRCLE) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTCIRCLE)) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
new_arc(PLACE, 360.);
xctx->ui_state &=~MENUSTARTCIRCLE;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & MENUSTARTZOOM) {
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTZOOM)) {
zoom_rectangle(START);
xctx->ui_state &=~MENUSTARTZOOM;
xctx->ui_state &=~MENUSTART;
break;
}
if(xctx->ui_state & STARTZOOM) {

View File

@ -869,8 +869,9 @@ static void drawgrid()
double delta,tmp;
#if DRAW_ALL_CAIRO==0
int i=0;
int big_gr;
big_gr = tclgetboolvar("big_grid_points");
int big_gr = tclgetboolvar("big_grid_points");
int axes = tclgetboolvar("draw_grid_axes");
#endif
dbg(1, "drawgrid(): draw grid\n");
if( !tclgetboolvar("draw_grid") || !has_x) return;
@ -890,7 +891,7 @@ static void drawgrid()
cairo_move_to(xctx->cairo_ctx, xctx->areax1+1, y);
cairo_line_to(xctx->cairo_ctx, xctx->areax2-1, y);
#else
XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y);
if(axes) XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y);
#endif
}
if(xctx->draw_pixmap) {
@ -898,7 +899,7 @@ static void drawgrid()
cairo_move_to(xctx->cairo_save_ctx, xctx->areax1+1, y);
cairo_line_to(xctx->cairo_save_ctx, xctx->areax2-1, y);
#else
XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y);
if(axes) XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y);
#endif
}
}
@ -908,7 +909,7 @@ static void drawgrid()
cairo_move_to(xctx->cairo_ctx, x, xctx->areay1+1);
cairo_line_to(xctx->cairo_ctx, x, xctx->areay2-1);
#else
XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1);
if(axes) XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1);
#endif
}
if(xctx->draw_pixmap) {
@ -916,7 +917,7 @@ static void drawgrid()
cairo_move_to(xctx->cairo_save_ctx, x, xctx->areay1+1);
cairo_line_to(xctx->cairo_save_ctx, x, xctx->areay2-1);
#else
XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1);
if(axes) XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1);
#endif
}
}
@ -1899,13 +1900,13 @@ static double get_unit(const char *val)
int sch_waves_loaded(void)
{
int i;
if(xctx->graph_raw_level == -1) return -1;
else if(xctx->graph_values && xctx->graph_names && xctx->graph_raw_schname) {
dbg(1, "sch_waves_loaded(): graph_raw_schname=%s\n", xctx->graph_raw_schname);
if(!xctx->raw || xctx->raw->level == -1) return -1;
else if(xctx->raw && xctx->raw->values && xctx->raw->names && xctx->raw->schname) {
dbg(1, "sch_waves_loaded(): raw->schname=%s\n", xctx->raw->schname);
for(i = xctx->currsch; i >= 0; i--) {
dbg(1, "sch_waves_loaded(): %d --> %s\n", i, xctx->sch[i]);
if( !xctx->sch[i] ) continue;
if( !strcmp(xctx->graph_raw_schname, xctx->sch[i]) ) {
if( !strcmp(xctx->raw->schname, xctx->sch[i]) ) {
dbg(1, "sch_waves_loaded(): returning %d\n", i);
return i;
}
@ -1968,18 +1969,18 @@ static SPICE_DATA **get_bus_idx_array(const char *ntok, int *n_bits)
char *saven, *nptr, *ntok_copy = NULL;
const char *bit_name;
*n_bits = count_items(ntok, ";,", "") - 1;
/* dbg(0, "get_bus_idx_array(): ntok=%s\n", ntok); */
/* dbg(0, "get_bus_idx_array(): *n_bits=%d\n", *n_bits); */
dbg(1, "get_bus_idx_array(): ntok=%s\n", ntok);
dbg(1, "get_bus_idx_array(): *n_bits=%d\n", *n_bits);
idx_arr = my_malloc(_ALLOC_ID_, (*n_bits) * sizeof(SPICE_DATA *));
p = 0;
my_strdup2(_ALLOC_ID_, &ntok_copy, ntok);
nptr = ntok_copy;
my_strtok_r(nptr, ";,", "", &saven); /*strip off bus name (1st field) */
while( (bit_name = my_strtok_r(NULL, ";,", "", &saven)) ) {
my_strtok_r(nptr, ";,", "", 0, &saven); /*strip off bus name (1st field) */
while( (bit_name = my_strtok_r(NULL, ";, ", "", 0, &saven)) ) {
int idx;
if(p >= *n_bits) break; /* security check to avoid out of bound writing */
if( (idx = get_raw_index(bit_name)) != -1) {
idx_arr[p] = xctx->graph_values[idx];
idx_arr[p] = xctx->raw->values[idx];
} else {
idx_arr[p] = NULL;
}
@ -2011,11 +2012,11 @@ int graph_fullxzoom(xRect *r, Graph_ctx *gr, int dataset)
if( sch_waves_loaded() >= 0) {
int need_redraw = 0;
double xx1, xx2;
int idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", 1));
int idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1));
int dset = dataset == -1 ? 0 : dataset;
if(idx < 0 ) idx = 0;
xx1 = get_raw_value(dset, idx, 0);
xx2 = get_raw_value(dset, idx, xctx->graph_npoints[dset] -1);
xx2 = get_raw_value(dset, idx, xctx->raw->npoints[dset] -1);
if(gr->logx) {
xx1 = mylog10(xx1);
xx2 = mylog10(xx2);
@ -2040,8 +2041,11 @@ int graph_fullyzoom(xRect *r, Graph_ctx *gr, int dataset)
int sweep_idx = 0;
double val, start, end;
double min=0.0, max=0.0;
int first = 1;
int firstyval = 1;
char *saves, *sptr, *stok, *sweep = NULL, *saven, *nptr, *ntok, *node = NULL;
Raw *raw = xctx->raw;
dbg(1, "graph_fullyzoom(): dataset=%d\n", dataset);
my_strdup2(_ALLOC_ID_, &node, get_tok_value(r->prop_ptr,"node",0));
my_strdup2(_ALLOC_ID_, &sweep, get_tok_value(r->prop_ptr,"sweep",0));
nptr = node;
@ -2049,52 +2053,71 @@ int graph_fullyzoom(xRect *r, Graph_ctx *gr, int dataset)
start = (gr->gx1 <= gr->gx2) ? gr->gx1 : gr->gx2;
end = (gr->gx1 <= gr->gx2) ? gr->gx2 : gr->gx1;
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) {
stok = my_strtok_r(sptr, "\n\t ", "\"", &saves);
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", 0, &saven)) ) {
stok = my_strtok_r(sptr, "\n\t ", "\"", 0, &saves);
nptr = sptr = NULL;
if(stok && stok[0]) {
sweep_idx = get_raw_index(stok);
if( sweep_idx == -1) sweep_idx = 0;
}
dbg(1, "graph_fullyzoom(): ntok=%s\n", ntok);
bus_msb = strstr(ntok, ",");
v = -1;
if(!bus_msb) {
char *express = NULL;
if(strstr(ntok, ";")) {
my_strdup2(_ALLOC_ID_, &express, find_nth(ntok, ";", 2));
my_strdup2(_ALLOC_ID_, &express, find_nth(ntok, ";", "\"", 0, 2));
} else {
my_strdup2(_ALLOC_ID_, &express, ntok);
}
if(strpbrk(express, " \n\t")) {
/* just probe a single point to get the index. custom data column already calculated */
v = calc_custom_data_yrange(sweep_idx, express, gr);
/* v = calc_custom_data_yrange(sweep_idx, express, gr); */ /* why this? */
v = raw->nvars;
} else {
v = get_raw_index(express);
}
my_free(_ALLOC_ID_, &express);
my_free(_ALLOC_ID_, &express);
dbg(1, "graph_fullyzoom(): v=%d\n", v);
}
if(v >= 0) {
if(xctx->raw && v >= 0) {
int sweepvar_wrap = 0; /* incremented on new dataset or sweep variable wrap */
int ofs = 0;
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
for(p = ofs; p < ofs + xctx->graph_npoints[dset]; ++p) {
double sweepval;
if(gr->logx) sweepval = mylog10(xctx->graph_values[sweep_idx][p]);
else sweepval = xctx->graph_values[sweep_idx][p];
if(dataset >= 0 && dataset != dset) continue;
if( sweepval < start ||
sweepval > end) continue;
if(gr->logy)
val =mylog10(xctx->graph_values[v][p]);
else
val = xctx->graph_values[v][p];
if(first || val < min) min = val;
if(first || val > max) max = val;
first = 0;
}
ofs += xctx->graph_npoints[dset];
}
for(dset = 0 ; dset < raw->datasets; dset++) {
double xx, xx0;
int cnt=0, wrap;
register SPICE_DATA *gv = raw->values[sweep_idx];
for(p = ofs ; p < ofs + raw->npoints[dset]; p++) {
if(gr->logx) xx = mylog10(gv[p]);
else xx = gv[p];
if(p == ofs) xx0 = xx;
wrap = (cnt > 1 && xx == xx0);
if(wrap) {
sweepvar_wrap++;
cnt = 0;
}
if(dataset == -1 || dataset == sweepvar_wrap) {
dbg(1, "graph_fullyzoom(): dataset=%d node=%s\n", dataset, raw->names[v]);
if( xx >= start && xx <= end) {
if(gr->logy)
val =mylog10(raw->values[v][p]);
else
val = raw->values[v][p];
if(firstyval || val < min) min = val;
if(firstyval || val > max) max = val;
firstyval = 0;
}
}
if(xx >= start && xx <= end) {
++cnt;
}
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
/* offset pointing to next dataset */
ofs += raw->npoints[dset];
sweepvar_wrap++;
} /* for(dset...) */
}
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) */
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", 0, &saven)) ) */
if(max == min) max += 0.01;
min = floor_to_n_digits(min, 2);
max = ceil_to_n_digits(max, 2);
@ -2141,18 +2164,23 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx
double vthh = gr->gy1 * 0.2 + gr->gy2 * 0.8;
double vthl = gr->gy1 * 0.8 + gr->gy2 * 0.2;
int hex_digits = ((n_bits - 1) >> 2) + 1;
Raw *raw = xctx->raw;
if(!raw) {
dbg(0, "draw_graph_bus_points(): no raw struct allocated\n");
return;
}
for(p=0;p<cadlayers; ++p) {
XSetLineAttributes(display, xctx->gc[p],
XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
}
if(gr->logx) {
lx1 = W_X(mylog10(xctx->graph_values[sweep_idx][first]));
lx2 = W_X(mylog10(xctx->graph_values[sweep_idx][last]));
lx1 = W_X(mylog10(raw->values[sweep_idx][first]));
lx2 = W_X(mylog10(raw->values[sweep_idx][last]));
} else {
lx1 = W_X(xctx->graph_values[sweep_idx][first]);
lx2 = W_X(xctx->graph_values[sweep_idx][last]);
lx1 = W_X(raw->values[sweep_idx][first]);
lx2 = W_X(raw->values[sweep_idx][last]);
}
if(c1 >= gr->ypos1 && c1 <=gr->ypos2) {
set_thick_waves(1, wcnt, wave_col, gr);
@ -2163,9 +2191,9 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx
/* hex_digits = */
get_bus_value(n_bits, hex_digits, idx_arr, p, busval, vthl, vthh);
if(gr->logx) {
xval = W_X(mylog10(xctx->graph_values[sweep_idx][p]));
xval = W_X(mylog10(raw->values[sweep_idx][p]));
} else {
xval = W_X(xctx->graph_values[sweep_idx][p]);
xval = W_X(raw->values[sweep_idx][p]);
}
/* used to draw bus value before 1st transition */
if(p == first) {
@ -2210,7 +2238,14 @@ static void draw_graph_points(int idx, int first, int last,
double s1;
double s2;
double c = 0, c1;
register SPICE_DATA *gv = xctx->graph_values[idx];
Raw *raw = xctx->raw;
register SPICE_DATA *gv;
if(!raw) {
dbg(0, "draw_graph_points(): no raw struct allocated\n");
return;
}
gv = raw->values[idx];
dbg(1, "draw_graph_points: idx=%d, first=%d, last=%d, wcnt=%d\n", idx, first, last, wcnt);
for(p=0;p<cadlayers; ++p) {
@ -2263,7 +2298,7 @@ static void draw_graph_points(int idx, int first, int last,
check_cairo_drawpoints(ct, wave_col, point, poly_npoints);
#endif
set_thick_waves(0, wcnt, wave_col, gr);
} else dbg(1, "skipping wave: %s\n", xctx->graph_names[idx]);
} else dbg(1, "skipping wave: %s\n", raw->names[idx]);
for(p=0;p<cadlayers; ++p) {
XSetLineAttributes(display, xctx->gc[p], XLINEWIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN);
}
@ -2603,7 +2638,7 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
/* draw sweep variable(s) on x-axis */
if(wcnt == 0 || (stok && stok[0])) {
if(sch_waves_loaded() >= 0) stok = xctx->graph_names[sweep_idx];
if(sch_waves_loaded() >= 0) stok = xctx->raw->names[sweep_idx];
if(gr->unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , gr->unitx_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : "");
draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0,
@ -2611,14 +2646,14 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
}
/* draw node labels in graph */
if(bus_msb) {
if(gr->unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", find_nth(ntok, ";,", 1), gr->unity_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s",find_nth(ntok, ";,", 1));
if(gr->unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", find_nth(ntok, ";,", "\"", 0, 1), gr->unity_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s",find_nth(ntok, ";,", "\"", 0, 1));
} else {
char *ntok_ptr = NULL;
char *alias_ptr = NULL;
if(strstr(ntok, ";")) {
my_strdup2(_ALLOC_ID_, &alias_ptr, find_nth(ntok, ";", 1));
my_strdup2(_ALLOC_ID_, &ntok_ptr, find_nth(ntok, ";", 2));
my_strdup2(_ALLOC_ID_, &alias_ptr, find_nth(ntok, ";", "\"", 0, 1));
my_strdup2(_ALLOC_ID_, &ntok_ptr, find_nth(ntok, ";", "\"", 0, 2));
}
else {
my_strdup2(_ALLOC_ID_, &alias_ptr, ntok);
@ -2695,6 +2730,10 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
double yy;
/* show values of signals if cursor1 active */
if(idx == -1) return;
if(!xctx->raw) {
dbg(0, "show_node_measures(): no raw struct allocated\n");
return;
}
if(measure_p >= 0) {
/* draw node values in graph */
@ -2706,8 +2745,8 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
double diffx;
char *fmt1, *fmt2;
double yy1;
yy1 = xctx->graph_values[idx][measure_p-1];
diffy = xctx->graph_values[idx][measure_p] - yy1;
yy1 = xctx->raw->values[idx][measure_p-1];
diffy = xctx->raw->values[idx][measure_p] - yy1;
diffx = measure_x - measure_prev_x;
yy = yy1 + diffy / diffx * (xctx->graph_cursor1_x - measure_prev_x);
if(XSIGN0(gr->gy1) != XSIGN0(gr->gy2) && fabs(yy) < 1e-4 * fabs(gr->gh)) yy = 0.0;
@ -2791,9 +2830,9 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
sptr = sweep;
n_nodes = count_items(node, " \t\n", "\"");
/* process each node given in "node" attribute, get also associated color/sweep var if any */
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) {
ctok = my_strtok_r(cptr, " ", "", &savec);
stok = my_strtok_r(sptr, "\t\n ", "\"", &saves);
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", 0, &saven)) ) {
ctok = my_strtok_r(cptr, " ", "", 0, &savec);
stok = my_strtok_r(sptr, "\t\n ", "\"", 0, &saves);
nptr = cptr = sptr = NULL;
dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL");
if(stok && stok[0]) {
@ -2857,7 +2896,7 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
}
}
++wcnt;
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", 0, &saven)) ) */
my_free(_ALLOC_ID_, &node);
my_free(_ALLOC_ID_, &color);
my_free(_ALLOC_ID_, &sweep);
@ -2873,21 +2912,26 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr)
int idx = -1;
int p, dset, ofs;
int first, last;
double xx; /* the p-th sweep variable value: xctx->graph_values[sweep_idx][p] */
double xx; /* the p-th sweep variable value: xctx->raw->values[sweep_idx][p] */
double xx0 = 0; /* first sweep value */
double start;
double end;
int sweepvar_wrap = 0; /* incremented on new dataset or sweep variable wrap */
int dataset = gr->dataset;
Raw *raw = xctx->raw;
if(!raw) {
dbg(0, "calc_custom_data_yrange(): no raw struct allocated\n");
return idx;
}
ofs = 0;
start = (gr->gx1 <= gr->gx2) ? gr->gx1 : gr->gx2;
end = (gr->gx1 <= gr->gx2) ? gr->gx2 : gr->gx1;
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
for(dset = 0 ; dset < raw->datasets; dset++) {
int cnt=0, wrap;
register SPICE_DATA *gv = xctx->graph_values[sweep_idx];
register SPICE_DATA *gv = raw->values[sweep_idx];
first = -1;
last = ofs;
for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) {
for(p = ofs ; p < ofs + raw->npoints[dset]; p++) {
if(gr->logx)
xx = mylog10(gv[p]);
else
@ -2913,14 +2957,14 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr)
last = p;
++cnt;
} /* if(xx >= start && xx <= end) */
} /* for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) */
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
if(first != -1) {
if(dataset == -1 || dataset == sweepvar_wrap) {
idx = plot_raw_custom_data(sweep_idx, first, last, express);
}
}
/* offset pointing to next dataset */
ofs += xctx->graph_npoints[dset];
ofs += raw->npoints[dset];
sweepvar_wrap++;
} /* for(dset...) */
return idx;
@ -2938,9 +2982,13 @@ int find_closest_wave(int i, Graph_ctx *gr)
xRect *r = &xctx->rect[GRIDLAYER][i];
int closest_dataset = -1;
double min=-1.0;
if(gr->digital) return -1;
Raw *raw = xctx->raw;
if(!raw) {
dbg(0, "find_closest_wave(): no raw struct allocated\n");
return -1;
}
if(gr->digital) return -1;
yval = G_Y(xctx->mousey);
xval = G_X(xctx->mousex);
/* get data to plot */
@ -2949,11 +2997,11 @@ int find_closest_wave(int i, Graph_ctx *gr)
nptr = node;
sptr = sweep;
/* process each node given in "node" attribute, get also associated sweep var if any*/
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) {
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", 0, &saven)) ) {
if(strstr(ntok, ",")) {
if(find_nth(ntok, ";,", 2)[0]) continue; /* bus signal: skip */
if(find_nth(ntok, ";,", "\"", 0, 2)[0]) continue; /* bus signal: skip */
}
stok = my_strtok_r(sptr, "\t\n ", "\"", &saves);
stok = my_strtok_r(sptr, "\t\n ", "\"", 0, &saves);
nptr = sptr = NULL;
dbg(1, "ntok=%s\n", ntok);
if(stok && stok[0]) {
@ -2965,9 +3013,9 @@ int find_closest_wave(int i, Graph_ctx *gr)
/* if ntok following possible 'alias;' definition contains spaces --> custom data plot */
idx = -1;
expression = 0;
if(xctx->graph_values) {
if(raw->values) {
if(strstr(ntok, ";")) {
my_strdup2(_ALLOC_ID_, &express, find_nth(ntok, ";", 2));
my_strdup2(_ALLOC_ID_, &express, find_nth(ntok, ";", "\"", 0, 2));
} else {
my_strdup2(_ALLOC_ID_, &express, ntok);
}
@ -2975,7 +3023,7 @@ int find_closest_wave(int i, Graph_ctx *gr)
expression = 1;
}
}
if(expression) idx = xctx->graph_nvars;
if(expression) idx = raw->nvars;
else idx = get_raw_index(express);
dbg(1, "find_closest_wave(): expression=%d, idx=%d\n", expression, idx);
if( idx != -1 ) {
@ -2990,20 +3038,20 @@ int find_closest_wave(int i, Graph_ctx *gr)
start = (gr->gx1 <= gr->gx2) ? gr->gx1 : gr->gx2;
end = (gr->gx1 <= gr->gx2) ? gr->gx2 : gr->gx1;
/* loop through all datasets found in raw file */
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
for(dset = 0 ; dset < raw->datasets; dset++) {
double prev_x = 0.0;
int cnt=0, wrap;
register SPICE_DATA *gvx = xctx->graph_values[sweep_idx];
register SPICE_DATA *gvx = raw->values[sweep_idx];
register SPICE_DATA *gvy;
if(expression) plot_raw_custom_data(sweep_idx, ofs, ofs + xctx->graph_npoints[dset]-1, express);
gvy = xctx->graph_values[idx];
if(expression) plot_raw_custom_data(sweep_idx, ofs, ofs + raw->npoints[dset]-1, express);
gvy = raw->values[idx];
dbg(1, "find_closest_wave(): dset=%d\n", dset);
first = -1;
/* Process "npoints" simulation items
* p loop split repeated 2 timed (for x and y points) to preserve cache locality */
last = ofs;
dbg(1, "find_closest_wave(): xval=%g yval=%g\n", xval, yval);
for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) {
for(p = ofs ; p < ofs + raw->npoints[dset]; p++) {
if(gr->logx) xx = mylog10(gvx[p]);
else xx = gvx[p];
if(p == ofs) xx0 = xx;
@ -3041,15 +3089,15 @@ int find_closest_wave(int i, Graph_ctx *gr)
++cnt;
} /* if(xx >= start && xx <= end) */
prev_x = xx;
} /* for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) */
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
/* offset pointing to next dataset */
ofs += xctx->graph_npoints[dset];
ofs += raw->npoints[dset];
sweepvar_wrap++;
} /* for(dset...) */
} /* if( (idx = get_raw_index(ntok)) != -1 ) */
++wcnt;
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", 0, &saven)) ) */
dbg(0, "closest dataset=%d\n", closest_dataset);
if(express) my_free(_ALLOC_ID_, &express);
my_free(_ALLOC_ID_, &node);
@ -3082,25 +3130,26 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
double measure_prev_x = 0.0;
char *express = NULL;
xRect *r = &xctx->rect[GRIDLAYER][i];
Raw *raw = xctx->raw;
if(xctx->only_probes) return;
if(RECT_OUTSIDE( gr->sx1, gr->sy1, gr->sx2, gr->sy2,
xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2)) return;
#if 0
dbg(0, "draw_graph(): window: %d %d %d %d\n", xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2);
dbg(0, "draw_graph(): graph: %g %g %g %g\n", gr->sx1, gr->sy1, gr->sx2, gr->sy2);
dbg(0, "draw_graph(): i = %d, flags = %d\n", i, flags);
#endif
#if 0
dbg(0, "draw_graph(): window: %d %d %d %d\n", xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2);
dbg(0, "draw_graph(): graph: %g %g %g %g\n", gr->sx1, gr->sy1, gr->sx2, gr->sy2);
dbg(0, "draw_graph(): i = %d, flags = %d\n", i, flags);
#endif
/* draw stuff */
if(flags & 8) {
#if !defined(__unix__) && HAS_CAIRO==1
#if !defined(__unix__) && HAS_CAIRO==1
double sw = (gr->sx2 - gr->sx1);
double sh = (gr->sy2 - gr->sy1);
clear_cairo_surface(xctx->cairo_save_ctx, gr->sx1, gr->sy1, sw, sh);
clear_cairo_surface(xctx->cairo_ctx, gr->sx1, gr->sy1, sw, sh);
#endif
#endif
/* graph box, gridlines and axes */
draw_graph_grid(gr, ct);
/* get data to plot */
@ -3112,12 +3161,14 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
sptr = sweep;
n_nodes = count_items(node, " \t\n", "\"");
/* process each node given in "node" attribute, get also associated color/sweep var if any*/
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) {
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", 4, &saven)) ) {
if(strstr(ntok, ",")) {
my_strdup2(_ALLOC_ID_, &bus_msb, find_nth(ntok, ";,", 2));
my_strdup2(_ALLOC_ID_, &bus_msb, find_nth(ntok, ";,", "\"", 0, 2));
my_strdup2(_ALLOC_ID_, &bus_msb, find_nth(bus_msb, " ", "", 0, 1)); /* chop spaces */
}
ctok = my_strtok_r(cptr, " ", "", &savec);
stok = my_strtok_r(sptr, "\t\n ", "\"", &saves);
dbg(1, "ntok=|%s|, bus_msb=|%s|\n", ntok, bus_msb ? bus_msb : "NULL");
ctok = my_strtok_r(cptr, " ", "", 0, &savec);
stok = my_strtok_r(sptr, "\t\n ", "\"", 0, &saves);
nptr = cptr = sptr = NULL;
dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL");
if(ctok && ctok[0]) wc = atoi(ctok);
@ -3133,9 +3184,9 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
/* if ntok following possible 'alias;' definition contains spaces --> custom data plot */
idx = -1;
expression = 0;
if(xctx->graph_values && !bus_msb) {
if(raw && raw->values && !bus_msb) {
if(strstr(ntok, ";")) {
my_strdup2(_ALLOC_ID_, &express, find_nth(ntok, ";", 2));
my_strdup2(_ALLOC_ID_, &express, find_nth(ntok, ";", "\"", 0, 2));
} else {
my_strdup2(_ALLOC_ID_, &express, ntok);
}
@ -3148,7 +3199,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
int p, dset, ofs;
int poly_npoints;
int first, last;
double xx; /* the p-th sweep variable value: xctx->graph_values[sweep_idx][p] */
double xx; /* the p-th sweep variable value: raw->values[sweep_idx][p] */
double xx0 = 0.0; /* the first sweep value */
double start;
double end;
@ -3168,19 +3219,19 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
bbox(ADD,gr->x1, gr->y1, gr->x2, gr->y2);
bbox(SET, 0.0, 0.0, 0.0, 0.0);
/* loop through all datasets found in raw file */
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
for(dset = 0 ; dset < raw->datasets; dset++) {
double prev_x;
int cnt=0, wrap;
register SPICE_DATA *gv = xctx->graph_values[sweep_idx];
register SPICE_DATA *gv = raw->values[sweep_idx];
first = -1;
poly_npoints = 0;
my_realloc(_ALLOC_ID_, &point, xctx->graph_npoints[dset] * sizeof(XPoint));
my_realloc(_ALLOC_ID_, &point, raw->npoints[dset] * sizeof(XPoint));
/* Process "npoints" simulation items
* p loop split repeated 2 timed (for x and y points) to preserve cache locality */
prev_x = 0;
last = ofs;
for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) {
for(p = ofs ; p < ofs + raw->npoints[dset]; p++) {
if(gr->logx) xx = mylog10(gv[p]);
else xx = gv[p];
if(p == ofs) xx0 = xx;
@ -3228,7 +3279,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
++cnt;
} /* if(xx >= start && xx <= end) */
prev_x = xx;
} /* for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) */
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
if(first != -1) {
if(dataset == -1 || dataset == sweepvar_wrap) {
/* plot graph. Bus bundles are not plotted if graph is not digital.*/
@ -3246,7 +3297,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
}
}
/* offset pointing to next dataset */
ofs += xctx->graph_npoints[dset];
ofs += raw->npoints[dset];
sweepvar_wrap++;
} /* for(dset...) */
bbox(END, 0.0, 0.0, 0.0, 0.0);
@ -3258,7 +3309,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
} /* if( expression || (idx = get_raw_index(bus_msb ? bus_msb : express)) != -1 ) */
++wcnt;
if(bus_msb) my_free(_ALLOC_ID_, &bus_msb);
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", 0, &saven)) ) */
if(express) my_free(_ALLOC_ID_, &express);
my_free(_ALLOC_ID_, &node);
my_free(_ALLOC_ID_, &color);

View File

@ -140,10 +140,13 @@ char *my_fgets(FILE *fd, size_t *line_len)
* character, removed from input and all characters before next quote are considered
* as part of the token. backslash can be used to enter literal quoting characters and
* literal backslashes.
* behavior described above can be changed if keep_quote is not zero:
* keep_quote == 1: keep quotes and backslahes
* keep_quote == 4: remove surrounding "...", keep everything in between
* if quote is empty no backslash is removed from input and behavior is identical
* to strtok_r
*/
char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr)
char *my_strtok_r(char *str, const char *delim, const char *quote, int keep_quote, char **saveptr)
{
char *tok;
int q = 0; /* quote */
@ -160,11 +163,11 @@ char *my_strtok_r(char *str, const char *delim, const char *quote, char **savept
if(ne) *(*saveptr - ne) = **saveptr; /* shift back eating escapes / quotes */
if(!e && strchr(quote, **saveptr)) {
q = !q;
++ne;
if(keep_quote != 1) ++ne;
}
if(quote[0] && !e && **saveptr == '\\') { /* if quote is empty string do not skip backslashes either */
if(!e && **saveptr == '\\') { /* do not skip backslashes either */
e = 1;
++ne;
if(keep_quote == 0) ++ne;
} else e = 0;
++(*saveptr);
}

View File

@ -461,7 +461,7 @@ function print_header()
"device @name @device\n" \
"@comptag\"\n"
}
print "v {xschem version=3.4.4 file_version=1.2}"
print "v {xschem version=3.4.5 file_version=1.2}"
template_attrs = "template=\"" template_attrs "\"\n"
if(FILENAME ~/\.sym$/) {

View File

@ -529,14 +529,13 @@ void hilight_parent_pins(void)
dbg(1, "p_n_s1=%s\n", p_n_s1);
for(k = 1; k<=mult; ++k) {
xctx->currsch++;
/* entry = bus_hilight_hash_lookup(find_nth(pin_node, ",", k), 0, XLOOKUP); */
entry = bus_hilight_hash_lookup(my_strtok_r(p_n_s1, ",", "", &p_n_s2), 0, XLOOKUP);
entry = bus_hilight_hash_lookup(my_strtok_r(p_n_s1, ",", "", 0, &p_n_s2), 0, XLOOKUP);
p_n_s1 = NULL;
xctx->currsch--;
if(entry)
{
dbg(1, "found hilight entry in child: %s\n", entry->token);
bus_hilight_hash_lookup(find_nth(net_node, ",",
bus_hilight_hash_lookup(find_nth(net_node, ",", "", 0,
((inst_number - 1) * mult + k - 1) % net_mult + 1), entry->value, XINSERT);
}
else
@ -548,7 +547,7 @@ void hilight_parent_pins(void)
* you should unhilight all net probes, hilight the desired child pins and then go up */
/*
* bus_hilight_hash_lookup(find_nth(net_node, ",",
* bus_hilight_hash_lookup(find_nth(net_node, ",", "", 0,
* ((inst_number - 1) * mult + k - 1) % net_mult + 1), 0, XDELETE);
*/
}
@ -596,21 +595,15 @@ void hilight_child_pins(void)
for(k = 1; k<=mult; ++k) {
dbg(1, "hilight_child_pins(): looking nth net:%d, k=%d, inst_number=%d, mult=%d\n",
(inst_number-1)*mult+k, k, inst_number, mult);
/* dbg(1, "hilight_child_pins(): looking net:%s\n", find_nth(net_node, ",",
((inst_number - 1) * mult + k - 1) % net_mult + 1)); */
xctx->currsch--;
entry = bus_hilight_hash_lookup(find_nth(net_node, ",",
entry = bus_hilight_hash_lookup(find_nth(net_node, ",", "", 0,
((inst_number - 1) * mult + k - 1) % net_mult + 1), 0, XLOOKUP);
xctx->currsch++;
if(entry) {
/* bus_hilight_hash_lookup(find_nth(pin_node, ",", k), entry->value, XINSERT_NOREPLACE); */
bus_hilight_hash_lookup(my_strtok_r(p_n_s1, ",", "", &p_n_s2), entry->value, XINSERT_NOREPLACE);
/* dbg(1, "hilight_child_pins(): inserting: %s\n", find_nth(pin_node, ",", k)); */
bus_hilight_hash_lookup(my_strtok_r(p_n_s1, ",", "", 0, &p_n_s2), entry->value, XINSERT_NOREPLACE);
}
else {
/* bus_hilight_hash_lookup(find_nth(pin_node, ",", k), 0, XDELETE); */
bus_hilight_hash_lookup(my_strtok_r(p_n_s1, ",", "", &p_n_s2), 0, XDELETE);
/* dbg(1, "hilight_child_pins(): deleting: %s\n", find_nth(pin_node, ",", k)); */
bus_hilight_hash_lookup(my_strtok_r(p_n_s1, ",", "", 0, &p_n_s2), 0, XDELETE);
}
p_n_s1 = NULL;
} /* for(k..) */
@ -902,7 +895,7 @@ static void drill_hilight(int mode)
expandlabel(netname, &mult);
dbg(1, "inst=%s, pin=%d, netname=%s, mult=%d\n", xctx->inst[i].instname, j, netname, mult);
for(k = 1; k <= mult; ++k) {
netbitname = find_nth(netname, ",", k);
netbitname = find_nth(netname, ",", "", 0, k);
dbg(1, "netbitname=%s\n", netbitname);
if( (entry=bus_hilight_hash_lookup(netbitname, 0, XLOOKUP)) ) {
if( hilight_connected_inst || (symbol->type && IS_LABEL_SH_OR_PIN(symbol->type)) ) {
@ -914,7 +907,7 @@ static void drill_hilight(int mode)
int n = 1;
const char *propag;
dbg(1, "drill_hilight(): inst=%d propagate_str=%s\n", i, propagate_str);
while((propag = find_nth(propagate_str, ",", n++))[0]) {
while((propag = find_nth(propagate_str, ",", "", 0, n++))[0]) {
propagate = atoi(propag);
if(propagate < 0 || propagate >= npin) {
@ -931,7 +924,7 @@ static void drill_hilight(int mode)
} else {
my_strdup2(_ALLOC_ID_, &propagated_net, net_name(i, propagate, &mult2, 1, 0));
}
netbitname = find_nth(propagated_net, ",", k);
netbitname = find_nth(propagated_net, ",", "", 0, k);
dbg(1, "netbitname=%s\n", netbitname);
/* add net to highlight list */
if(!netbitname[0]) continue;
@ -988,7 +981,7 @@ static void send_net_to_bespice(int simtype, const char *node)
expanded_tok = expandlabel(tok, &tok_mult);
my_strdup2(_ALLOC_ID_, &p, xctx->sch_path[xctx->currsch]+1);
for(k=1; k<=tok_mult; ++k) {
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", k));
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", "", 0, k));
/* bespice command syntax :
add_voltage_on_spice_node_to_plot <plot name> <section name> <hierarchical spice node name> <flag clear> [<color>]
plot name is "*" => automatic
@ -1018,7 +1011,7 @@ static void send_net_to_graph(char **s, int simtype, const char *node)
if(tok[0] == '#') tok++;
if(node_entry && (node_entry->d.port == 0 ||
/* !strcmp(xctx->sch_path[xctx->currsch], ".") */
xctx->currsch == xctx->graph_raw_level
xctx->currsch == xctx->raw->level
)) {
char *t=NULL, *p=NULL;
char *path;
@ -1038,7 +1031,7 @@ static void send_net_to_graph(char **s, int simtype, const char *node)
}
strtolower(path);
for(k=1; k<=tok_mult; ++k) {
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", k));
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", "", 0, k));
strtolower(t);
if(simtype == 0 ) { /* ngspice */
dbg(1, "%s%s color=%d\n", path, t, c);
@ -1080,7 +1073,7 @@ static void send_net_to_gaw(int simtype, const char *node)
path = p;
strtolower(path);
for(k=1; k<=tok_mult; ++k) {
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", k));
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", "", 0, k));
strtolower(t);
if(simtype == 0 ) { /* ngspice */
tclvareval("puts $gaw_fd {copyvar v(", path, t,
@ -1114,7 +1107,7 @@ static void send_current_to_bespice(int simtype, const char *node)
expanded_tok = expandlabel(tok, &tok_mult);
my_strdup2(_ALLOC_ID_, &p, xctx->sch_path[xctx->currsch]+1);
for(k=1; k<=tok_mult; ++k) {
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", k));
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", "", 0, k));
/* bespice command syntax :
add_current_through_spice_device_to_plot <plot name> <section name> <hierarchical spice device name> <flag clear> [<color>]
plot name is "*" => automatic
@ -1156,7 +1149,7 @@ static void send_current_to_graph(char **s, int simtype, const char *node)
strtolower(path);
there_is_hierarchy = (strstr(path, ".") != NULL);
for(k=1; k<=tok_mult; ++k) {
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", k));
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", "", 0, k));
strtolower(t);
if(!simtype) { /* ngspice */
my_snprintf(ss, S(ss), "i(%s%s%s) %d", there_is_hierarchy ? "v." : "", path, t, c);
@ -1196,7 +1189,7 @@ static void send_current_to_gaw(int simtype, const char *node)
strtolower(path);
there_is_hierarchy = (xctx->currsch > 0);
for(k=1; k<=tok_mult; ++k) {
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", k));
my_strdup(_ALLOC_ID_, &t, find_nth(expanded_tok, ",", "", 0, k));
strtolower(t);
if(!simtype) { /* spice */
tclvareval("puts $gaw_fd {copyvar i(", there_is_hierarchy ? "v." : "", path, t,
@ -1586,7 +1579,7 @@ static void propagate_logic()
}
dbg(1, "propagate_logic(): inst=%d pin %d, goto=%s\n", i,j, xctx->simdata[i].pin[j].go_to);
while(1) {
propag = find_nth(xctx->simdata[i].pin[j].go_to, ",", n);
propag = find_nth(xctx->simdata[i].pin[j].go_to, ",", "", 0, n);
++n;
if(!propag[0]) break;
propagate = atoi(propag);
@ -1933,7 +1926,7 @@ char *resolved_net(const char *net)
my_strdup2(_ALLOC_ID_, &exp_net, expandlabel(net, &mult));
n_s1 = exp_net;
for(k = 0; k < mult; k++) {
char *net_name = my_strtok_r(n_s1, ",", "", &n_s2);
char *net_name = my_strtok_r(n_s1, ",", "", 0, &n_s2);
level = xctx->currsch;
n_s1 = NULL;
resolved_net = net_name;

View File

@ -694,7 +694,7 @@ function print_sym(sym, template, format, subckt_name, sym_type, extra, dir, pin
print "start print symbol: " sym
print "v {xschem version=3.4.4 file_version=1.2}"
print "v {xschem version=3.4.5 file_version=1.2}"
print "K {type=" sym_type > sym
# print "format=\"@name @pinlist @symname " format_translate(template) "\"" > sym
iii = format_translate(template, extra)

View File

@ -68,7 +68,7 @@ function beginfile(f)
text_voffset=20
lab_voffset=4
ip=op=n_pin=0
print "v {xschem version=3.4.4 file_version=1.2}" > sym
print "v {xschem version=3.4.5 file_version=1.2}" > sym
if(template=="") {
printf "%s", "K {type=subcircuit\nformat=\"@name @pinlist @symname\"\n" >sym
printf "%s\n", "template=\"name=x1\"" >sym

View File

@ -625,8 +625,8 @@ static void name_generics()
my_strdup(_ALLOC_ID_, &sig_type,"");
bus_node_hash_lookup(inst[n].node[p],"", XINSERT, 1, sig_type,"", "","");
} else {
my_strdup(_ALLOC_ID_, &sig_type,get_tok_value(
(inst[i].ptr+ xctx->sym)->rect[GENERICLAYER][j-rects].prop_ptr, "sig_type",0));
my_strdup(_ALLOC_ID_, &sig_type,
get_tok_value((inst[i].ptr+ xctx->sym)->rect[GENERICLAYER][j-rects].prop_ptr, "sig_type", 0));
/* insert generic label in hash table as a port so it will not */
/* be declared as a signal in the vhdl netlist. this is a workaround */
/* that should be fixed 25092001 */

View File

@ -43,7 +43,7 @@ char **parse_cmd_string(const char *cmd, int *argc)
*argc = 0;
my_strdup2(_ALLOC_ID_, &cmd_copy, cmd);
cmd_ptr = cmd_copy;
while( (argv[*argc] = my_strtok_r(cmd_ptr, " \t", "'\"", &cmd_save)) ) {
while( (argv[*argc] = my_strtok_r(cmd_ptr, " \t", "'\"", 0, &cmd_save)) ) {
cmd_ptr = NULL;
dbg(1, "--> %s\n", argv[*argc]);
(*argc)++;
@ -383,50 +383,54 @@ void transpose_matrix(double *a, int r, int c)
* data layout in memory arranged to maximize cache locality
* when looking up data
*/
static void read_binary_block(FILE *fd)
static void read_binary_block(FILE *fd, Raw *raw)
{
int p, v;
double *tmp;
int offset = 0;
int ac = 0;
if(!strcmp(xctx->graph_sim_type, "ac")) ac = 1; /* AC analysis, complex numbers twice the size */
if(!raw) {
dbg(0, "read_binary_block() no raw struct allocated\n");
return;
}
if(!strcmp(raw->sim_type, "ac")) ac = 1; /* AC analysis, complex numbers twice the size */
for(p = 0 ; p < xctx->graph_datasets; p++) {
offset += xctx->graph_npoints[p];
for(p = 0 ; p < raw->datasets; p++) {
offset += raw->npoints[p];
}
/* read buffer */
tmp = my_calloc(_ALLOC_ID_, xctx->graph_nvars, (sizeof(double *) ));
tmp = my_calloc(_ALLOC_ID_, raw->nvars, (sizeof(double *) ));
/* allocate storage for binary block, add one data column for custom data plots */
if(!xctx->graph_values) xctx->graph_values = my_calloc(_ALLOC_ID_, xctx->graph_nvars + 1, sizeof(SPICE_DATA *));
for(p = 0 ; p <= xctx->graph_nvars; p++) {
if(!raw->values) raw->values = my_calloc(_ALLOC_ID_, raw->nvars + 1, sizeof(SPICE_DATA *));
for(p = 0 ; p <= raw->nvars; p++) {
my_realloc(_ALLOC_ID_,
&xctx->graph_values[p], (offset + xctx->graph_npoints[xctx->graph_datasets]) * sizeof(SPICE_DATA));
&raw->values[p], (offset + raw->npoints[raw->datasets]) * sizeof(SPICE_DATA));
}
/* read binary block */
for(p = 0; p < xctx->graph_npoints[xctx->graph_datasets]; p++) {
if(fread(tmp, sizeof(double) , xctx->graph_nvars, fd) != xctx->graph_nvars) {
for(p = 0; p < raw->npoints[raw->datasets]; p++) {
if(fread(tmp, sizeof(double) , raw->nvars, fd) != raw->nvars) {
dbg(0, "Warning: binary block is not of correct size\n");
}
/* assign to xschem struct, memory aligned per variable, for cache locality */
if(ac) {
for(v = 0; v < xctx->graph_nvars; v += 2) { /*AC analysis: calculate magnitude */
for(v = 0; v < raw->nvars; v += 2) { /*AC analysis: calculate magnitude */
if( v == 0 ) /* sweep var */
xctx->graph_values[v][offset + p] = (SPICE_DATA)sqrt( tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]);
raw->values[v][offset + p] = (SPICE_DATA)sqrt( tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]);
else /* magnitude */
/* avoid 0 for dB calculations */
if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) xctx->graph_values[v][offset + p] = 1e-35f;
else xctx->graph_values[v][offset + p] =
if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) raw->values[v][offset + p] = 1e-35f;
else raw->values[v][offset + p] =
(SPICE_DATA)sqrt(tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]);
/* AC analysis: calculate phase */
if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) xctx->graph_values[v + 1] [offset + p] = 0.0;
else xctx->graph_values[v + 1] [offset + p] =
if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) raw->values[v + 1] [offset + p] = 0.0;
else raw->values[v + 1] [offset + p] =
(SPICE_DATA)(atan2(tmp[v + 1], tmp[v]) * 180.0 / XSCH_PI);
}
}
else for(v = 0; v < xctx->graph_nvars; v++) {
xctx->graph_values[v][offset + p] = (SPICE_DATA)tmp[v];
else for(v = 0; v < raw->nvars; v++) {
raw->values[v][offset + p] = (SPICE_DATA)tmp[v];
}
}
my_free(_ALLOC_ID_, &tmp);
@ -455,14 +459,25 @@ static void read_binary_block(FILE *fd)
* 157 i(v1) current
* Binary:
*/
static int read_dataset(FILE *fd, const char *type)
static int read_dataset(FILE *fd, Raw **rawptr, const char *type)
{
int variables = 0, i, done_points = 0;
char *line = NULL, *varname = NULL, *lowerline = NULL;
int n = 0, done_header = 0, ac = 0;
int exit_status = 0, npoints, nvars;
int dbglev=1;
xctx->graph_sim_type = NULL;
Raw *raw;
if(!rawptr) {
dbg(0, "read_dataset(): NULL rawptr given\n");
return 0;
}
raw = *rawptr;
if(!raw) {
dbg(0, "read_dataset(): no raw struct allocated\n");
return 0;
}
raw->sim_type = NULL;
dbg(1, "read_dataset(): type=%s\n", type ? type : "<NULL>");
while((line = my_fgets(fd, NULL))) {
my_strdup2(_ALLOC_ID_, &lowerline, line);
@ -473,17 +488,17 @@ static int read_dataset(FILE *fd, const char *type)
"Use binary format in ngspice (set filetype=binary)\n");
tcleval("alert_ {read_dataset(): ASCII raw files can not be read. "
"Use binary format in ngspice (set filetype=binary)}");
free_rawfile(0);
free_rawfile(rawptr, 0);
exit_status = 0;
goto read_dataset_done;
}
/* after this line comes the binary blob made of nvars * npoints * sizeof(double) bytes */
if(!strcmp(line, "Binary:\n") || !strcmp(line, "Binary:\r\n")) {
if(xctx->graph_sim_type) {
if(raw->sim_type) {
done_header = 1;
dbg(dbglev, "read_dataset(): read binary block, nvars=%d npoints=%d\n", nvars, npoints);
read_binary_block(fd);
xctx->graph_datasets++;
read_binary_block(fd, raw);
raw->datasets++;
exit_status = 1;
} else {
dbg(dbglev, "read_dataset(): skip binary block, nvars=%d npoints=%d\n", nvars, npoints);
@ -493,44 +508,44 @@ static int read_dataset(FILE *fd, const char *type)
ac = 0;
}
/* if type is given (not NULL) choose the simulation that matches type, else take the first one */
/* if xctx->graph_sim_type is set skip all datasets that do not match */
/* if raw->sim_type is set skip all datasets that do not match */
else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "transient analysis")) {
if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "tran")) xctx->graph_sim_type = NULL;
else if(type && !strcmp(type, "tran")) xctx->graph_sim_type = "tran";
else if(type && strcmp(type, "tran")) xctx->graph_sim_type = NULL;
else xctx->graph_sim_type = "tran";
dbg(dbglev, "read_dataset(): tran graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : "<NULL>");
if(raw->sim_type && strcmp(raw->sim_type, "tran")) raw->sim_type = NULL;
else if(type && !strcmp(type, "tran")) raw->sim_type = "tran";
else if(type && strcmp(type, "tran")) raw->sim_type = NULL;
else raw->sim_type = "tran";
dbg(dbglev, "read_dataset(): tran raw->sim_type=%s\n", raw->sim_type ? raw->sim_type : "<NULL>");
}
else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "dc transfer characteristic")) {
if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "dc")) xctx->graph_sim_type = NULL;
else if(type && !strcmp(type, "dc")) xctx->graph_sim_type = "dc";
else if(type && strcmp(type, "dc")) xctx->graph_sim_type = NULL;
else xctx->graph_sim_type = "dc";
dbg(dbglev, "read_dataset(): dc graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : "<NULL>");
if(raw->sim_type && strcmp(raw->sim_type, "dc")) raw->sim_type = NULL;
else if(type && !strcmp(type, "dc")) raw->sim_type = "dc";
else if(type && strcmp(type, "dc")) raw->sim_type = NULL;
else raw->sim_type = "dc";
dbg(dbglev, "read_dataset(): dc raw->sim_type=%s\n", raw->sim_type ? raw->sim_type : "<NULL>");
}
else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "operating point")) {
if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "op")) xctx->graph_sim_type = NULL;
else if(type && !strcmp(type, "op")) xctx->graph_sim_type = "op";
else if(type && strcmp(type, "op")) xctx->graph_sim_type = NULL;
else xctx->graph_sim_type = "op";
dbg(dbglev, "read_dataset(): op graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : "<NULL>");
if(raw->sim_type && strcmp(raw->sim_type, "op")) raw->sim_type = NULL;
else if(type && !strcmp(type, "op")) raw->sim_type = "op";
else if(type && strcmp(type, "op")) raw->sim_type = NULL;
else raw->sim_type = "op";
dbg(dbglev, "read_dataset(): op raw->sim_type=%s\n", raw->sim_type ? raw->sim_type : "<NULL>");
}
else if(!strncmp(line, "Plotname:", 9) &&
( strstr(lowerline, "ac analysis") || strstr(lowerline, "sp analysis")) ) {
ac = 1;
if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "ac")) xctx->graph_sim_type = NULL;
else if(type && !strcmp(type, "ac")) xctx->graph_sim_type = "ac";
else if(type && strcmp(type, "ac")) xctx->graph_sim_type = NULL;
else xctx->graph_sim_type = "ac";
dbg(dbglev, "read_dataset(): ac graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : "<NULL>");
if(raw->sim_type && strcmp(raw->sim_type, "ac")) raw->sim_type = NULL;
else if(type && !strcmp(type, "ac")) raw->sim_type = "ac";
else if(type && strcmp(type, "ac")) raw->sim_type = NULL;
else raw->sim_type = "ac";
dbg(dbglev, "read_dataset(): ac raw->sim_type=%s\n", raw->sim_type ? raw->sim_type : "<NULL>");
}
else if(!strncmp(line, "Plotname:", 9)) {
char name[PATH_MAX];
xctx->graph_sim_type = NULL;
raw->sim_type = NULL;
n = sscanf(line, "Plotname: %s", name);
if(n==1) {
if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "custom")) xctx->graph_sim_type = NULL;
else if(type && !strcmp(type, name)) xctx->graph_sim_type = "custom";
if(raw->sim_type && strcmp(raw->sim_type, "custom")) raw->sim_type = NULL;
else if(type && !strcmp(type, name)) raw->sim_type = "custom";
}
}
/* points and vars are needed for all sections (also ones we are not interested in)
@ -540,16 +555,16 @@ static int read_dataset(FILE *fd, const char *type)
n = sscanf(line, "No. of Data Rows : %d", &npoints);
if(n < 1) {
dbg(0, "read_dataset(): WAARNING: malformed raw file, aborting\n");
free_rawfile(0);
free_rawfile(rawptr, 0);
exit_status = 0;
goto read_dataset_done;
}
if(xctx->graph_sim_type) {
my_realloc(_ALLOC_ID_, &xctx->graph_npoints, (xctx->graph_datasets+1) * sizeof(int));
xctx->graph_npoints[xctx->graph_datasets] = npoints;
/* multi-point OP is equivalent to a DC sweep. Change xctx->graph_sim_type */
if(xctx->graph_npoints[xctx->graph_datasets] > 1 && !strcmp(xctx->graph_sim_type, "op") ) {
xctx->graph_sim_type = "dc";
if(raw->sim_type) {
my_realloc(_ALLOC_ID_, &raw->npoints, (raw->datasets+1) * sizeof(int));
raw->npoints[raw->datasets] = npoints;
/* multi-point OP is equivalent to a DC sweep. Change raw->sim_type */
if(raw->npoints[raw->datasets] > 1 && !strcmp(raw->sim_type, "op") ) {
raw->sim_type = "dc";
}
}
done_points = 1;
@ -559,7 +574,7 @@ static int read_dataset(FILE *fd, const char *type)
dbg(dbglev, "read_dataset(): nvars=%d\n", nvars);
if(ac) nvars <<= 1;
if(xctx->graph_datasets > 0 && xctx->graph_nvars != nvars && xctx->graph_sim_type) {
if(raw->datasets > 0 && raw->nvars != nvars && raw->sim_type) {
dbg(0, "Xschem requires all datasets to be saved with identical and same number of variables\n");
dbg(0, "There is a mismatch, so this and following datasets will not be read\n");
/* exit_status = 1; */ /* do not set, if something useful has been read keep exit status as is */
@ -568,40 +583,40 @@ static int read_dataset(FILE *fd, const char *type)
if(n < 1) {
dbg(0, "read_dataset(): WAARNING: malformed raw file, aborting\n");
free_rawfile(0);
free_rawfile(rawptr, 0);
exit_status = 0;
goto read_dataset_done;
}
if(xctx->graph_sim_type) {
xctx->graph_nvars = nvars;
if(raw->sim_type) {
raw->nvars = nvars;
}
}
else if(!done_points && !strncmp(line, "No. Points:", 11)) {
n = sscanf(line, "No. Points: %d", &npoints);
if(n < 1) {
dbg(0, "read_dataset(): WAARNING: malformed raw file, aborting\n");
free_rawfile(0);
free_rawfile(rawptr, 0);
exit_status = 0;
goto read_dataset_done;
}
if(xctx->graph_sim_type) {
my_realloc(_ALLOC_ID_, &xctx->graph_npoints, (xctx->graph_datasets+1) * sizeof(int));
xctx->graph_npoints[xctx->graph_datasets] = npoints;
/* multi-point OP is equivalent to a DC sweep. Change xctx->graph_sim_type */
if(xctx->graph_npoints[xctx->graph_datasets] > 1 && !strcmp(xctx->graph_sim_type, "op") ) {
xctx->graph_sim_type = "dc";
if(raw->sim_type) {
my_realloc(_ALLOC_ID_, &raw->npoints, (raw->datasets+1) * sizeof(int));
raw->npoints[raw->datasets] = npoints;
/* multi-point OP is equivalent to a DC sweep. Change raw->sim_type */
if(raw->npoints[raw->datasets] > 1 && !strcmp(raw->sim_type, "op") ) {
raw->sim_type = "dc";
}
}
}
if(xctx->graph_sim_type && !done_header && variables) {
if(raw->sim_type && !done_header && variables) {
char *ptr;
/* get the list of lines with index and node name */
if(!xctx->graph_names) xctx->graph_names = my_calloc(_ALLOC_ID_, xctx->graph_nvars, sizeof(char *));
if(!raw->names) raw->names = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(char *));
my_realloc(_ALLOC_ID_, &varname, strlen(line) + 1) ;
n = sscanf(line, "%d %s", &i, varname); /* read index and name of saved waveform */
if(n < 2) {
dbg(0, "read_dataset(): WAARNING: malformed raw file, aborting\n");
free_rawfile(0);
free_rawfile(rawptr, 0);
exit_status = 0;
goto read_dataset_done;
}
@ -612,23 +627,23 @@ static int read_dataset(FILE *fd, const char *type)
if(*ptr == ':') *ptr = '.';
++ptr;
}
if(xctx->graph_sim_type && !strcmp(xctx->graph_sim_type, "ac")) { /* AC */
my_strcat(_ALLOC_ID_, &xctx->graph_names[i << 1], varname);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[i << 1], (i << 1), XINSERT_NOREPLACE);
if(raw->sim_type && !strcmp(raw->sim_type, "ac")) { /* AC */
my_strcat(_ALLOC_ID_, &raw->names[i << 1], varname);
int_hash_lookup(&raw->table, raw->names[i << 1], (i << 1), XINSERT_NOREPLACE);
if(strstr(varname, "v(") == varname || strstr(varname, "i(") == varname)
my_mstrcat(_ALLOC_ID_, &xctx->graph_names[(i << 1) + 1], "ph(", varname + 2, NULL);
my_mstrcat(_ALLOC_ID_, &raw->names[(i << 1) + 1], "ph(", varname + 2, NULL);
else
my_mstrcat(_ALLOC_ID_, &xctx->graph_names[(i << 1) + 1], "ph(", varname, ")", NULL);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[(i << 1) + 1], (i << 1) + 1, XINSERT_NOREPLACE);
my_mstrcat(_ALLOC_ID_, &raw->names[(i << 1) + 1], "ph(", varname, ")", NULL);
int_hash_lookup(&raw->table, raw->names[(i << 1) + 1], (i << 1) + 1, XINSERT_NOREPLACE);
} else {
my_strcat(_ALLOC_ID_, &xctx->graph_names[i], varname);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[i], i, XINSERT_NOREPLACE);
my_strcat(_ALLOC_ID_, &raw->names[i], varname);
int_hash_lookup(&raw->table, raw->names[i], i, XINSERT_NOREPLACE);
}
/* use hash table to store index number of variables */
dbg(dbglev, "read_dataset(): get node list -> names[%d] = %s\n", i, xctx->graph_names[i]);
dbg(dbglev, "read_dataset(): get node list -> names[%d] = %s\n", i, raw->names[i]);
}
/* after this line comes the list of indexes and associated nodes */
if(xctx->graph_sim_type && !strncmp(line, "Variables:", 10)) {
if(raw->sim_type && !strncmp(line, "Variables:", 10)) {
variables = 1 ;
}
my_free(_ALLOC_ID_, &line);
@ -637,43 +652,42 @@ static int read_dataset(FILE *fd, const char *type)
if(line) my_free(_ALLOC_ID_, &line);
if(lowerline) my_free(_ALLOC_ID_, &lowerline);
if(varname) my_free(_ALLOC_ID_, &varname);
if(exit_status == 1 && xctx->graph_datasets && xctx->graph_npoints) {
if(exit_status == 1 && raw->datasets && raw->npoints) {
dbg(dbglev, "raw file read: datasets=%d, last dataset points=%d, nvars=%d\n",
xctx->graph_datasets, xctx->graph_npoints[xctx->graph_datasets-1], xctx->graph_nvars);
raw->datasets, raw->npoints[raw->datasets-1], raw->nvars);
}
return exit_status;
}
void free_rawfile(int dr)
void free_rawfile(Raw **rawptr, int dr)
{
int i;
Raw *raw;
int deleted = 0;
if(!rawptr || !*rawptr) return;
raw = *rawptr;
dbg(1, "free_rawfile(): clearing data\n");
if(xctx->graph_names) {
if(raw->names) {
deleted = 1;
for(i = 0 ; i < xctx->graph_nvars; ++i) {
my_free(_ALLOC_ID_, &xctx->graph_names[i]);
for(i = 0 ; i < raw->nvars; ++i) {
my_free(_ALLOC_ID_, &raw->names[i]);
}
my_free(_ALLOC_ID_, &xctx->graph_names);
my_free(_ALLOC_ID_, &raw->names);
}
if(xctx->graph_values) {
if(raw->values) {
deleted = 1;
/* free also extra column for custom data plots */
for(i = 0 ; i <= xctx->graph_nvars; ++i) {
my_free(_ALLOC_ID_, &xctx->graph_values[i]);
for(i = 0 ; i <= raw->nvars; ++i) {
my_free(_ALLOC_ID_, &raw->values[i]);
}
my_free(_ALLOC_ID_, &xctx->graph_values);
my_free(_ALLOC_ID_, &raw->values);
}
if(xctx->graph_npoints) my_free(_ALLOC_ID_, &xctx->graph_npoints);
xctx->graph_allpoints = 0;
if(xctx->graph_raw_schname) my_free(_ALLOC_ID_, &xctx->graph_raw_schname);
xctx->graph_raw_level = -1;
tclsetintvar("graph_raw_level", -1);
xctx->graph_datasets = 0;
xctx->graph_nvars = 0;
xctx->graph_annotate_p = -1;
if(xctx->graph_raw_table.table) int_hash_free(&xctx->graph_raw_table);
if(raw->npoints) my_free(_ALLOC_ID_, &raw->npoints);
if(raw->schname) my_free(_ALLOC_ID_, &raw->schname);
tclsetintvar("raw_level", -1);
if(raw->table.table) int_hash_free(&raw->table);
my_free(_ALLOC_ID_, rawptr);
if(deleted && dr) draw();
}
@ -703,17 +717,22 @@ char *base64_from_file(const char *f, size_t *length)
return b64s;
}
int raw_read_from_attr(const char *type)
int raw_read_from_attr(Raw **rawptr, const char *type)
{
int res = 0;
unsigned char *s;
size_t decoded_length;
FILE *fd;
char *tmp_filename;
Raw *raw;
if(xctx->graph_values || xctx->graph_npoints || xctx->graph_nvars || xctx->graph_datasets) {
dbg(0, "raw_read(_from_attr(): must clear current raw file before loading new\n");
if(!rawptr) {
dbg(0, "raw_read_from_attr(): NULL rawptr given\n");
return res;
}
raw = *rawptr;
if(raw) {
dbg(0, "raw_read_from_attr(): must clear current raw file before loading new\n");
return res;
}
if(xctx->lastsel==1 && xctx->sel_array[0].type==ELEMENT) {
@ -727,7 +746,7 @@ int raw_read_from_attr(const char *type)
fwrite(s, decoded_length, 1, fd);
fclose(fd);
my_free(_ALLOC_ID_, &s);
res = raw_read(tmp_filename, type);
res = raw_read(tmp_filename, rawptr, type);
unlink(tmp_filename);
} else {
dbg(0, "read_rawfile_from_attr(): failed to open file %s for reading\n", tmp_filename);
@ -738,29 +757,41 @@ int raw_read_from_attr(const char *type)
}
/* read a ngspice raw file (with data portion in binary format) */
int raw_read(const char *f, const char *type)
int raw_read(const char *f, Raw **rawptr, const char *type)
{
int res = 0;
FILE *fd;
if(xctx->graph_values || xctx->graph_npoints || xctx->graph_nvars || xctx->graph_datasets) {
Raw *raw;
if(!rawptr) {
dbg(0, "NULL rawptr pointer given\n");
return res;
}
if(*rawptr) {
dbg(0, "raw_read(): must clear current raw file before loading new\n");
return res;
}
int_hash_init(&xctx->graph_raw_table, HASHSIZE);
*rawptr = my_calloc(_ALLOC_ID_, 1, sizeof(Raw));
raw = *rawptr;
raw->level = -1;
tclsetintvar("raw_level", -1);
raw->annot_p = -1;
int_hash_init(&raw->table, HASHSIZE);
fd = fopen(f, fopen_read_mode);
if(fd) {
if((res = read_dataset(fd, type)) == 1) {
if((res = read_dataset(fd, rawptr, type)) == 1) {
int i;
my_strdup2(_ALLOC_ID_, &xctx->graph_raw_schname, xctx->sch[xctx->currsch]);
xctx->graph_raw_level = xctx->currsch;
tclsetintvar("graph_raw_level", xctx->currsch);
xctx->graph_allpoints = 0;
for(i = 0; i < xctx->graph_datasets; ++i) {
xctx->graph_allpoints += xctx->graph_npoints[i];
my_strdup2(_ALLOC_ID_, &raw->schname, xctx->sch[xctx->currsch]);
raw->level = xctx->currsch;
tclsetintvar("raw_level", xctx->currsch);
raw->allpoints = 0;
for(i = 0; i < raw->datasets; ++i) {
raw->allpoints += raw->npoints[i];
}
dbg(0, "Raw file data read: %s\n", f);
dbg(0, "points=%d, vars=%d, datasets=%d\n",
xctx->graph_allpoints, xctx->graph_nvars, xctx->graph_datasets);
raw->allpoints, raw->nvars, raw->datasets);
} else {
dbg(0, "raw_read(): no useful data found\n");
}
@ -803,17 +834,22 @@ int table_read(const char *f)
char *line = NULL, *line_ptr, *line_save;
const char *line_tok;
if(xctx->graph_values || xctx->graph_npoints || xctx->graph_nvars || xctx->graph_datasets) {
if(xctx->raw) {
dbg(0, "table_read(): must clear current data file before loading new\n");
return 0;
}
xctx->raw = my_calloc(_ALLOC_ID_, 1, sizeof(Raw));
xctx->raw->level = -1;
tclsetintvar("raw_level", -1);
xctx->raw->annot_p = -1;
/* quick inspect file and get upper bound of number of data lines */
ufd = open(f, O_RDONLY);
if(ufd < 0) goto err;
count_lines_bytes(ufd, &lines, &bytes);
close(ufd);
int_hash_init(&xctx->graph_raw_table, HASHSIZE);
int_hash_init(&xctx->raw->table, HASHSIZE);
fd = fopen(f, fopen_read_mode);
if(fd) {
int nline = 0;
@ -838,9 +874,9 @@ int table_read(const char *f)
prev_empty = 1;
goto clear;
}
if(!xctx->graph_datasets || (prev_prev_empty == 1 && prev_empty == 1) ) {
xctx->graph_datasets++;
my_realloc(_ALLOC_ID_, &xctx->graph_npoints, xctx->graph_datasets * sizeof(int));
if(!xctx->raw->datasets || (prev_prev_empty == 1 && prev_empty == 1) ) {
xctx->raw->datasets++;
my_realloc(_ALLOC_ID_, &xctx->raw->npoints, xctx->raw->datasets * sizeof(int));
dataset_points = 0;
}
prev_prev_empty = prev_empty = 0;
@ -849,22 +885,22 @@ int table_read(const char *f)
#ifdef __unix__
while( (line_tok = strtok_r(line_ptr, " \t\n", &line_save)) ) {
#else
while( (line_tok = my_strtok_r(line_ptr, " \t\n", "", &line_save)) ) {
while( (line_tok = my_strtok_r(line_ptr, " \t\n", "", 0, &line_save)) ) {
#endif
line_ptr = NULL;
/* dbg(1,"%s ", line_tok); */
if(nline == 0) { /* header line */
my_realloc(_ALLOC_ID_, &xctx->graph_names, (field + 1) * sizeof(char *));
xctx->graph_names[field] = NULL;
my_strcat(_ALLOC_ID_, &xctx->graph_names[field], line_tok);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[field], field, XINSERT_NOREPLACE);
xctx->graph_nvars = field + 1;
my_realloc(_ALLOC_ID_, &xctx->raw->names, (field + 1) * sizeof(char *));
xctx->raw->names[field] = NULL;
my_strcat(_ALLOC_ID_, &xctx->raw->names[field], line_tok);
int_hash_lookup(&xctx->raw->table, xctx->raw->names[field], field, XINSERT_NOREPLACE);
xctx->raw->nvars = field + 1;
} else { /* data line */
if(field >= xctx->graph_nvars) break;
if(field >= xctx->raw->nvars) break;
#if SPICE_DATA_TYPE == 1 /* float */
xctx->graph_values[field][npoints] = (SPICE_DATA)my_atof(line_tok);
xctx->raw->values[field][npoints] = (SPICE_DATA)my_atof(line_tok);
#else /* double */
xctx->graph_values[field][npoints] = (SPICE_DATA)my_atod(line_tok);
xctx->raw->values[field][npoints] = (SPICE_DATA)my_atod(line_tok);
#endif
}
++field;
@ -873,32 +909,32 @@ int table_read(const char *f)
++npoints;
dataset_points++;
}
xctx->graph_npoints[xctx->graph_datasets - 1] = dataset_points;
xctx->raw->npoints[xctx->raw->datasets - 1] = dataset_points;
/* dbg(1, "\n"); */
++nline;
if(nline == 1) {
int f;
xctx->graph_values = my_calloc(_ALLOC_ID_, xctx->graph_nvars + 1, sizeof(SPICE_DATA *));
for(f = 0; f <= xctx->graph_nvars; f++) { /* one extra column for wave expressions */
my_realloc(_ALLOC_ID_, &xctx->graph_values[f], lines * sizeof(SPICE_DATA));
xctx->raw->values = my_calloc(_ALLOC_ID_, xctx->raw->nvars + 1, sizeof(SPICE_DATA *));
for(f = 0; f <= xctx->raw->nvars; f++) { /* one extra column for wave expressions */
my_realloc(_ALLOC_ID_, &xctx->raw->values[f], lines * sizeof(SPICE_DATA));
}
}
clear:
my_free(_ALLOC_ID_, &line);
} /* while(line ....) */
xctx->graph_allpoints = 0;
xctx->raw->allpoints = 0;
if(res == 1) {
int i;
my_strdup2(_ALLOC_ID_, &xctx->graph_raw_schname, xctx->sch[xctx->currsch]);
xctx->graph_raw_level = xctx->currsch;
tclsetintvar("graph_raw_level", xctx->currsch);
xctx->graph_allpoints = 0;
for(i = 0; i < xctx->graph_datasets; ++i) {
xctx->graph_allpoints += xctx->graph_npoints[i];
my_strdup2(_ALLOC_ID_, &xctx->raw->schname, xctx->sch[xctx->currsch]);
xctx->raw->level = xctx->currsch;
tclsetintvar("raw_level", xctx->currsch);
xctx->raw->allpoints = 0;
for(i = 0; i < xctx->raw->datasets; ++i) {
xctx->raw->allpoints += xctx->raw->npoints[i];
}
dbg(0, "Table file data read: %s\n", f);
dbg(0, "points=%d, vars=%d, datasets=%d\n",
xctx->graph_allpoints, xctx->graph_nvars, xctx->graph_datasets);
xctx->raw->allpoints, xctx->raw->nvars, xctx->raw->datasets);
} else {
dbg(0, "table_read(): no useful data found\n");
}
@ -923,17 +959,17 @@ int get_raw_index(const char *node)
if(sch_waves_loaded() >= 0) {
my_strncpy(inode, node, S(inode));
strtolower(inode);
entry = int_hash_lookup(&xctx->graph_raw_table, inode, 0, XLOOKUP);
entry = int_hash_lookup(&xctx->raw->table, inode, 0, XLOOKUP);
if(!entry) {
my_snprintf(vnode, S(vnode), "v(%s)", inode);
entry = int_hash_lookup(&xctx->graph_raw_table, vnode, 0, XLOOKUP);
entry = int_hash_lookup(&xctx->raw->table, vnode, 0, XLOOKUP);
}
if(!entry && strstr(inode, "i(v.x")) {
char *ptr = inode;
inode[2] = 'i';
inode[3] = '(';
ptr += 2;
entry = int_hash_lookup(&xctx->graph_raw_table, ptr, 0, XLOOKUP);
entry = int_hash_lookup(&xctx->raw->table, ptr, 0, XLOOKUP);
}
if(entry) return entry->value;
}
@ -1026,14 +1062,14 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr)
Stack1 stack1[STACKMAX];
double stack2[STACKMAX]={0}, tmp, result, avg;
int stackptr1 = 0, stackptr2 = 0;
SPICE_DATA *y = xctx->graph_values[xctx->graph_nvars]; /* custom plot data column */
SPICE_DATA *x = xctx->graph_values[sweep_idx];
SPICE_DATA *sweepx = xctx->graph_values[0];
SPICE_DATA *y = xctx->raw->values[xctx->raw->nvars]; /* custom plot data column */
SPICE_DATA *x = xctx->raw->values[sweep_idx];
SPICE_DATA *sweepx = xctx->raw->values[0];
my_strdup2(_ALLOC_ID_, &ntok_copy, expr);
ntok_ptr = ntok_copy;
dbg(1, "plot_raw_custom_data(): expr=%s\n", expr);
while( (n = my_strtok_r(ntok_ptr, " \t\n", "", &ntok_save)) ) {
while( (n = my_strtok_r(ntok_ptr, " \t\n", "", 0, &ntok_save)) ) {
if(stackptr1 >= STACKMAX -2) {
dbg(0, "stack overflow in graph expression parsing. Interrupted\n");
my_free(_ALLOC_ID_, &ntok_copy);
@ -1106,8 +1142,8 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr)
if(stack1[i].i == NUMBER) { /* number */
stack2[stackptr2++] = stack1[i].d;
}
else if(stack1[i].i == SPICE_NODE && stack1[i].idx < xctx->graph_nvars) { /* spice node */
stack2[stackptr2++] = xctx->graph_values[stack1[i].idx][p];
else if(stack1[i].i == SPICE_NODE && stack1[i].idx < xctx->raw->nvars) { /* spice node */
stack2[stackptr2++] = xctx->raw->values[stack1[i].idx][p];
}
if(stackptr2 > 1) { /* 2 argument operators */
@ -1370,23 +1406,23 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr)
y[p] = (SPICE_DATA)stack2[0];
} /* for(p = first ...) */
ravg_store(0, 0, 0, 0, 0.0); /* clear data */
return xctx->graph_nvars;
return xctx->raw->nvars;
}
double get_raw_value(int dataset, int idx, int point)
{
int i, ofs;
ofs = 0;
if(xctx->graph_values) {
if(xctx->raw && xctx->raw->values) {
if(dataset == -1) {
if(point < xctx->graph_allpoints)
return xctx->graph_values[idx][point];
if(point < xctx->raw->allpoints)
return xctx->raw->values[idx][point];
} else {
for(i = 0; i < dataset; ++i) {
ofs += xctx->graph_npoints[i];
ofs += xctx->raw->npoints[i];
}
if(ofs + point < xctx->graph_allpoints) {
return xctx->graph_values[idx][ofs + point];
if(ofs + point < xctx->raw->allpoints) {
return xctx->raw->values[idx][ofs + point];
}
}
}

View File

@ -272,19 +272,19 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
tclsetboolvar("live_cursor2_backannotate", 1);
tclsetvar("rawfile_loaded", "0");
free_rawfile(1);
free_rawfile(&xctx->raw, 1);
tcleval("array unset ngspice::ngspice_data");
raw_read(f, "op");
if(xctx->graph_values) {
xctx->graph_annotate_p = 0;
for(i = 0; i < xctx->graph_nvars; ++i) {
raw_read(f, &xctx->raw, "op");
if(xctx->raw && xctx->raw->values) {
xctx->raw->annot_p = 0;
for(i = 0; i < xctx->raw->nvars; ++i) {
char s[100];
int p = 0;
my_snprintf(s, S(s), "%.4g", xctx->graph_values[i][p]);
dbg(1, "%s = %g\n", xctx->graph_names[i], xctx->graph_values[i][p]);
tclvareval("array set ngspice::ngspice_data [list {", xctx->graph_names[i], "} ", s, "]", NULL);
my_snprintf(s, S(s), "%.4g", xctx->raw->values[i][p]);
dbg(1, "%s = %g\n", xctx->raw->names[i], xctx->raw->values[i][p]);
tclvareval("array set ngspice::ngspice_data [list {", xctx->raw->names[i], "} ", s, "]", NULL);
}
tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( xctx->graph_nvars), NULL);
tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( xctx->raw->nvars), NULL);
tclvareval("set ngspice::ngspice_data(n\\ points) 1", NULL);
draw();
}
@ -296,7 +296,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "arc"))
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
xctx->ui_state |= MENUSTARTARC;
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTARC;
}
/* attach_labels
@ -447,7 +448,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "circle"))
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
xctx->ui_state |= MENUSTARTCIRCLE;
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTCIRCLE;
}
/* clear [force] [symbol|schematic]
@ -885,13 +887,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else { cmd_found = 0;}
break;
case 'f': /*----------------------------------------------*/
/* find_nth string sep n
/* find_nth string sep quote keep_quote n
* Find n-th field string separated by characters in sep. 1st field is in position 1
* xschem find_nth {aaa,bbb,ccc,ddd} {,} 2 --> bbb */
* do not split quoted fields (if quote characters are given) and return unquoted.
* xschem find_nth {aaa,bbb,ccc,ddd} {,} 2 --> bbb
* xschem find_nth {aaa, "bbb, ccc" , ddd} { ,} {"} 2 --> bbb, ccc
*/
if(!strcmp(argv[1], "find_nth"))
{
if(argc > 4) {
Tcl_SetResult(interp, find_nth(argv[2], argv[3], atoi(argv[4])), TCL_VOLATILE);
if(argc > 6) {
Tcl_SetResult(interp, find_nth(argv[2], argv[3], argv[4], atoi(argv[5]), atoi(argv[6])), TCL_VOLATILE);
}
}
@ -1385,7 +1390,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* Get value of attribute 'sym_attr' of symbol 'sym_name'
* 'with_quotes' (default:0) is an integer passed to get_tok_value()
*
* getprop rect layer num attr
* getprop rect layer num attr [with_quotes]
* if '1' is given as 'keep' return backslashes and unescaped quotes if present in value
* Get attribute 'attr' of rectangle number 'num' on layer 'layer'
*
* getprop text num attr
@ -1462,7 +1468,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int slot;
if((ss = strchr(xctx->inst[inst].instname, ':')) ) {
sscanf(ss + 1, "%d", &slot);
if(strstr(value, ":")) value = find_nth(value, ":", slot);
if(strstr(value, ":")) value = find_nth(value, ":", "", 0, slot);
}
Tcl_SetResult(interp, (char *)value, TCL_VOLATILE);
}
@ -1494,9 +1500,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, "xschem getprop rect needs <color> <n> <token>", TCL_STATIC);
return TCL_ERROR;
} else {
int with_quotes = 0;
int c = atoi(argv[3]);
int n = atoi(argv[4]);
Tcl_SetResult(interp, (char *)get_tok_value(xctx->rect[c][n].prop_ptr, argv[5], 2), TCL_VOLATILE);
if(argc > 6) with_quotes = atoi(argv[6]);
Tcl_SetResult(interp, (char *)get_tok_value(xctx->rect[c][n].prop_ptr, argv[5], with_quotes), TCL_VOLATILE);
}
} else if(!strcmp(argv[2], "text")) { /* xschem getprop text n token */
if(argc < 5) {
@ -1999,7 +2007,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
for(p = 0;p < no_of_pins; p++) {
pin = get_tok_value(rct[p].prop_ptr,argv[3],0);
if(slot > 0 && !strcmp(argv[3], "pinnumber") && strstr(pin, ":")) pin = find_nth(pin, ":", slot);
if(slot > 0 && !strcmp(argv[3], "pinnumber") && strstr(pin, ":")) pin = find_nth(pin, ":", "", 0, slot);
if(!strcmp(pin, argv[4])) break;
}
if(p >= no_of_pins) {
@ -2141,7 +2149,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
set_modify(1);
}
else xctx->ui_state |= MENUSTARTLINE;
else {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTLINE;
}
}
/* line_width n
@ -2531,9 +2542,30 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
move_objects(START,0,0,0);
move_objects( END,0,atof(argv[2]), atof(argv[3]));
}
else xctx->ui_state |= MENUSTARTMOVE;
else {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTMOVE;
}
Tcl_ResetResult(interp);
}
/* my_strtok_r str delim quote keep_quote
* test for my_strtok_r() function */
else if(!strcmp(argv[1], "my_strtok_r"))
{
if(argc > 5) {
char *strcopy = NULL, *strptr = NULL, *saveptr = NULL, *tok;
my_strdup(_ALLOC_ID_, &strcopy, argv[2]);
strptr = strcopy;
while( (tok = my_strtok_r(strptr, argv[3], argv[4], atoi(argv[5]), &saveptr)) ) {
strptr = NULL;
Tcl_AppendResult(interp, "{", tok, "}\n", NULL);
}
my_free(_ALLOC_ID_, &strptr);
}
}
else { cmd_found = 0;}
break;
case 'n': /*----------------------------------------------*/
@ -2853,7 +2885,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "polygon"))
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
xctx->ui_state |= MENUSTARTPOLYGON;
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTPOLYGON;
}
/* preview_window create|draw|destroy [winpath] [file]
@ -3037,7 +3070,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
tclsetvar("rawfile_loaded", "0");
free_rawfile(1);
free_rawfile(&xctx->raw, 1);
Tcl_ResetResult(interp);
}
@ -3058,11 +3091,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "raw_query"))
{
int i;
Raw *raw = xctx->raw;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
Tcl_ResetResult(interp);
if(argc > 2 && !strcmp(argv[2], "loaded")) {
Tcl_SetResult(interp, my_itoa(sch_waves_loaded()), TCL_VOLATILE);
} else if(xctx->graph_values) {
} else if(raw && raw->values) {
/* xschem rawfile_query value v(ldcp) 123 */
if(argc > 4 && !strcmp(argv[2], "value")) {
int dataset = -1;
@ -3070,11 +3104,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
const char *node = argv[3];
int idx = -1;
if(argc > 5) dataset = atoi(argv[5]);
if((dataset >= 0 && point >= 0 && point < xctx->graph_npoints[dataset]) ||
(point >= 0 && point < xctx->graph_allpoints)) {
if((dataset >= 0 && point >= 0 && point < raw->npoints[dataset]) ||
(point >= 0 && point < raw->allpoints)) {
if(isonlydigit(node)) {
int i = atoi(node);
if(i >= 0 && i < xctx->graph_nvars) {
if(i >= 0 && i < raw->nvars) {
idx = i;
}
} else {
@ -3098,7 +3132,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
idx = get_raw_index(argv[3]);
if(argc > 4) dataset = atoi(argv[4]);
if(idx >= 0) {
int np = xctx->graph_npoints[dataset];
int np = raw->npoints[dataset];
Tcl_ResetResult(interp);
for(p = 0; p < np; p++) {
sprintf(n, "%.10e", get_raw_value(dataset, idx, p));
@ -3106,21 +3140,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
} else if(argc > 2 && !strcmp(argv[2], "datasets")) {
Tcl_SetResult(interp, my_itoa(xctx->graph_datasets), TCL_VOLATILE);
Tcl_SetResult(interp, my_itoa(raw->datasets), TCL_VOLATILE);
} else if(argc > 2 && !strcmp(argv[2], "points")) {
int dset = -1;
if(argc > 3) dset = atoi(argv[3]);
if(dset == -1) Tcl_SetResult(interp, my_itoa(xctx->graph_allpoints), TCL_VOLATILE);
if(dset == -1) Tcl_SetResult(interp, my_itoa(raw->allpoints), TCL_VOLATILE);
else {
if(dset >= 0 && dset < xctx->graph_datasets)
Tcl_SetResult(interp, my_itoa(xctx->graph_npoints[dset]), TCL_VOLATILE);
if(dset >= 0 && dset < raw->datasets)
Tcl_SetResult(interp, my_itoa(raw->npoints[dset]), TCL_VOLATILE);
}
} else if(argc > 2 && !strcmp(argv[2], "vars")) {
Tcl_SetResult(interp, my_itoa(xctx->graph_nvars), TCL_VOLATILE);
Tcl_SetResult(interp, my_itoa(raw->nvars), TCL_VOLATILE);
} else if(argc > 2 && !strcmp(argv[2], "list")) {
for(i = 0 ; i < xctx->graph_nvars; ++i) {
for(i = 0 ; i < raw->nvars; ++i) {
if(i > 0) Tcl_AppendResult(interp, "\n", NULL);
Tcl_AppendResult(interp, xctx->graph_names[i], NULL);
Tcl_AppendResult(interp, raw->names[i], NULL);
}
}
}
@ -3136,15 +3170,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int res = 0;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(sch_waves_loaded() >= 0) {
free_rawfile(1);
free_rawfile(&xctx->raw, 1);
tclsetvar("rawfile_loaded", "0");
} else if(argc > 2) {
free_rawfile(0);
free_rawfile(&xctx->raw, 0);
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[2], home_dir);
tcleval(f);
my_strncpy(f, tclresult(), S(f));
if(argc > 3) res = raw_read(f, argv[3]);
else res = raw_read(f, NULL);
if(argc > 3) res = raw_read(f, &xctx->raw, argv[3]);
else res = raw_read(f, &xctx->raw, NULL);
if(sch_waves_loaded() >= 0) {
tclsetvar("rawfile_loaded", "1");
draw();
@ -3164,11 +3198,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(sch_waves_loaded() >= 0) {
free_rawfile(1);
free_rawfile(&xctx->raw, 1);
} else {
free_rawfile(0);
if(argc > 2) raw_read_from_attr(argv[2]);
else raw_read_from_attr(NULL);
free_rawfile(&xctx->raw, 0);
if(argc > 2) raw_read_from_attr(&xctx->raw, argv[2]);
else raw_read_from_attr(&xctx->raw, NULL);
if(sch_waves_loaded() >= 0) {
tclsetvar("rawfile_loaded", "1");
draw();
@ -3235,7 +3269,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
set_modify(1);
}
else xctx->ui_state |= MENUSTARTRECT;
else {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTRECT;
}
}
/* redo
@ -4148,7 +4185,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Graph_ctx *gr = &xctx->graph_struct;
int dataset;
setup_graph_data(n, 0, gr);
if(gr->dataset >= 0 && gr->dataset < xctx->graph_datasets) dataset = gr->dataset;
if(xctx->raw && gr->dataset >= 0 && gr->dataset < xctx->raw->datasets) dataset = gr->dataset;
else dataset = -1;
graph_fullxzoom(r, gr, dataset);
}
@ -4157,7 +4194,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Graph_ctx *gr = &xctx->graph_struct;
int dataset;
setup_graph_data(n, 0, gr);
if(gr->dataset >= 0 && gr->dataset < xctx->graph_datasets) dataset = gr->dataset;
if(xctx->raw && gr->dataset >= 0 && gr->dataset < xctx->raw->datasets) dataset = gr->dataset;
else dataset = -1;
graph_fullyzoom(r, gr, dataset);
}
@ -4278,7 +4315,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "snap_wire"))
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
xctx->ui_state |= MENUSTARTSNAPWIRE;
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTSNAPWIRE;
}
/* str_replace str rep with [escape]
@ -4408,13 +4446,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
char f[PATH_MAX + 100];
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(sch_waves_loaded() >= 0) {
free_rawfile(1);
free_rawfile(&xctx->raw, 1);
tclsetvar("rawfile_loaded", "0");
} else if(argc > 2) {
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[2], home_dir);
tcleval(f);
my_strncpy(f, tclresult(), S(f));
free_rawfile(0);
free_rawfile(&xctx->raw, 0);
table_read(f);
if(sch_waves_loaded() >= 0) {
tclsetvar("rawfile_loaded", "1");
@ -4740,7 +4778,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(tclgetboolvar("autotrim_wires")) trim_wires();
set_modify(1);
}
else xctx->ui_state |= MENUSTARTWIRE;
else {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTWIRE;
}
}
/* wire_cut [x y] [noalign]
* start a wire cut operation. Point the mouse in the middle of a wire and
@ -4757,8 +4798,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(argc > 3) {
break_wires_at_point(atof(argv[2]), atof(argv[3]), align);
} else {
if(align) xctx->ui_state |= MENUSTARTWIRECUT;
else xctx->ui_state |= MENUSTARTWIRECUT2;
if(align) {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTWIRECUT;
} else {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTWIRECUT2;
}
}
Tcl_ResetResult(interp);
}
@ -4799,7 +4845,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
draw();
}
else {
xctx->ui_state |=MENUSTARTZOOM;
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTZOOM;
}
Tcl_ResetResult(interp);
}

View File

@ -393,7 +393,7 @@ function attrs(a)
function header()
{
print "v {xschem version=3.4.4 file_version=1.2}"
print "v {xschem version=3.4.5 file_version=1.2}"
}
function round(n)

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.4 file_version=1.2
v {xschem version=3.4.5 file_version=1.2
}
G {font file}
K {}

View File

@ -423,6 +423,8 @@ static void get_pin_and_attr(const char *token, char **pin_num_or_name, char **p
/* 1: return backslashes and quotes as part of the token value if they are present */
/* bit 1: */
/* 1: do not perform tcl_hook2 substitution */
/* bit: 2 = 1: same as bit 0 = 1, but remove surrounding "..." quotes, keep everything in between */
const char *get_tok_value(const char *s,const char *tok, int with_quotes)
{
@ -481,7 +483,9 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes)
}
if( (with_quotes & 1) || escape || (c != '\\' && c != '"')) token[token_pos++]=(char)c;
} else if(state == TOK_VALUE) {
if( (with_quotes & 1) || escape || (c != '\\' && c != '"')) result[value_pos++]=(char)c;
if( with_quotes & 1) result[value_pos++] = (char)c;
else if(( with_quotes & 4) && (escape || c != '"')) result[value_pos++] = (char)c;
else if( escape || (c != '\\' && c != '"')) result[value_pos++]=(char)c;
} else if(state == TOK_ENDTOK || state == TOK_SEP) {
if(token_pos) {
token[token_pos] = '\0';
@ -675,7 +679,7 @@ void hash_names(int inst, int action)
strtoupper(upinst);
upinst_ptr = upinst;
while( (single_name = my_strtok_r(upinst_ptr, ",", "", &upinst_state)) ) {
while( (single_name = my_strtok_r(upinst_ptr, ",", "", 0, &upinst_state)) ) {
upinst_ptr = NULL;
dbg(1, "hash_names(): inst %d, name %s --> %d\n", i, single_name, action);
int_hash_lookup(&xctx->inst_name_table, single_name, i, action);
@ -702,7 +706,7 @@ static int name_is_used(char *name, const char *old_basename, const char *brkt,
my_strdup(_ALLOC_ID_, &upinst, expandlabel(name, &mult));
strtoupper(upinst);
upinst_ptr = upinst;
while( (single_name = my_strtok_r(upinst_ptr, ",", "", &upinst_state)) ) {
while( (single_name = my_strtok_r(upinst_ptr, ",", "", 0, &upinst_state)) ) {
upinst_ptr = NULL;
entry = int_hash_lookup(&xctx->inst_name_table, single_name, 1, XLOOKUP);
if(entry) {
@ -1088,7 +1092,7 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200
sscanf(ss+1, "%s", tmpstr);
if(isonlydigit(tmpstr)) {
slot = atoi(tmpstr);
if(strstr(value,":")) value = find_nth(value, ":", slot);
if(strstr(value,":")) value = find_nth(value, ":", "", 0, slot);
}
}
my_free(_ALLOC_ID_, &tmpstr);
@ -1360,17 +1364,22 @@ int count_items(const char *s, const char *sep, const char *quote)
const char *ptr;
int items = 0;
int state = 0; /* 1 if item is being processed */
int c, q = 0;
int c, q = 0, e = 0;
ptr = s;
while( (c = *(unsigned char *)ptr ++) ) {
if(strchr(quote, c)) q = !q;
if(q || !strchr(sep, c)) { /* not a separator */
while( (c = *(unsigned char *)ptr++) ) {
if(!e && c == '\\') {
e = 1;
continue;
}
if(!e && strchr(quote, c)) q = !q;
if(e || q || !strchr(sep, c)) { /* not a separator */
if(!state) items++;
state = 1;
} else {
state = 0;
}
e = 0;
}
dbg(1, "count_items: s=%s, items=%d\n", s, items);
return items;
@ -2185,7 +2194,7 @@ int print_spice_element(FILE *fd, int inst)
sscanf(ss+1, "%s", tmpstr);
if(isonlydigit(tmpstr)) {
slot = atoi(tmpstr);
if(strstr(value,":")) value = find_nth(value, ":", slot);
if(strstr(value,":")) value = find_nth(value, ":", "", 0, slot);
}
}
my_free(_ALLOC_ID_, &tmpstr);
@ -2355,8 +2364,8 @@ void print_tedax_element(FILE *fd, int inst)
if(!int_hash_lookup(&table, pinname, 1, XINSERT_NOREPLACE)) {
dbg(1, "#net=%s pinname=%s pin=%s net_mult=%d pin_mult=%d\n", net, pinname, pin, net_mult, pin_mult);
for(n = 0; n < net_mult; ++n) {
my_strdup(_ALLOC_ID_, &netbit, find_nth(net, ",", n+1));
my_strdup(_ALLOC_ID_, &pinbit, find_nth(pin, ",", n+1));
my_strdup(_ALLOC_ID_, &netbit, find_nth(net, ",", "", 0, n+1));
my_strdup(_ALLOC_ID_, &pinbit, find_nth(pin, ",", "", 0, n+1));
fprintf(fd, "__map__ %s -> %s\n",
pinbit ? pinbit : "__UNCONNECTED_PIN__",
netbit ? netbit : "__UNCONNECTED_PIN__");
@ -2409,8 +2418,8 @@ void print_tedax_element(FILE *fd, int inst)
/* fprintf(errfp, "extra_pinnumber: |%s|\n", extra_pinnumber); */
/* fprintf(errfp, "extra: |%s|\n", extra); */
for(extra_ptr = extra, extra_pinnumber_ptr = extra_pinnumber; ; extra_ptr=NULL, extra_pinnumber_ptr=NULL) {
extra_pinnumber_token=my_strtok_r(extra_pinnumber_ptr, " ", "", &saveptr1);
extra_token=my_strtok_r(extra_ptr, " ", "", &saveptr2);
extra_pinnumber_token=my_strtok_r(extra_pinnumber_ptr, " ", "", 0, &saveptr1);
extra_token=my_strtok_r(extra_ptr, " ", "", 0, &saveptr2);
if(!extra_token) break;
/* fprintf(errfp, "extra_pinnumber_token: |%s|\n", extra_pinnumber_token); */
/* fprintf(errfp, "extra_token: |%s|\n", extra_token); */
@ -2577,7 +2586,7 @@ void print_tedax_element(FILE *fd, int inst)
sscanf(ss+1, "%s", tmpstr);
if(isonlydigit(tmpstr)) {
slot = atoi(tmpstr);
if(strstr(value,":")) value = find_nth(value, ":", slot);
if(strstr(value,":")) value = find_nth(value, ":", "", 0, slot);
}
}
my_free(_ALLOC_ID_, &tmpstr);
@ -2837,7 +2846,7 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
sscanf(ss+1, "%s", tmpstr);
if(isonlydigit(tmpstr)) {
slot = atoi(tmpstr);
if(strstr(value,":")) value = find_nth(value, ":", slot);
if(strstr(value,":")) value = find_nth(value, ":", "", 0, slot);
}
}
my_free(_ALLOC_ID_, &tmpstr);
@ -3056,7 +3065,7 @@ void print_verilog_element(FILE *fd, int inst)
if(v_extra) {
const char *val;
for(extra_ptr = v_extra; ; extra_ptr=NULL) {
extra_token=my_strtok_r(extra_ptr, " ", "", &saveptr1);
extra_token=my_strtok_r(extra_ptr, " ", "", 0, &saveptr1);
if(!extra_token) break;
val = get_tok_value(xctx->inst[inst].prop_ptr, extra_token, 0);
@ -3152,14 +3161,14 @@ const char *net_name(int i, int j, int *multip, int hash_prefix_unnamed_net, int
else
my_snprintf(str_node, S(str_node), "%s", (xctx->inst[i].node[j])+1 );
}
expandlabel(get_tok_value( /* remove quotes --. */
(xctx->inst[i].ptr + xctx->sym)->rect[PINLAYER][j].prop_ptr,"name",0), multip);
expandlabel(
get_tok_value( (xctx->inst[i].ptr + xctx->sym)->rect[PINLAYER][j].prop_ptr,"name",0), multip);
return expandlabel(str_node, &tmp);
}
else
{
expandlabel(get_tok_value( /* remove quotes --. */
(xctx->inst[i].ptr + xctx->sym)->rect[PINLAYER][j].prop_ptr,"name",0), multip);
expandlabel(
get_tok_value( (xctx->inst[i].ptr + xctx->sym)->rect[PINLAYER][j].prop_ptr,"name",0), multip);
return expandlabel(xctx->inst[i].node[j], &tmp);
}
}
@ -3177,53 +3186,65 @@ int isonlydigit(const char *s)
}
/* find nth field in str separated by sep. 1st field is position 1
* find_nth("aaa,bbb,ccc,ddd", ',', 2) --> "bbb"
* separators inside quotes are not considered as field separators
* if keep_quote == 1 keep quoting characters and backslashes in returned field
* if keep_quote == 4 same as above but remove surrounding "..."
* find_nth("aaa,bbb,ccc,ddd", ",", 0, 2) --> bbb
* find_nth("aaa, \"bbb, \" ccc\" , ddd", " ,", "\"", 0, 2) --> bbb, " ccc
* find_nth("aaa, \"bbb, \" ccc\" , ddd", " ,", "\"", 1, 2) --> "bbb, \" ccc"
* find_nth("aaa, \"bbb, \" ccc\" , ddd", " ,", "\"", 4, 2) --> bbb, \" ccc
*/
char *find_nth(const char *str, const char *sep, int n)
char *find_nth(const char *str, const char *sep, const char *quote, int keep_quote, int n)
{
static char *result=NULL; /* safe to keep even with multiple schematic windows */
static size_t result_size = 0; /* safe to keep even with multiple schematic windows */
int i;
int i, q = 0, e = 0; /* e: escape */
int result_pos;
size_t len;
char *ptr;
int count = -1;
int count = 0, first_nonsep=1;
/* clean up static data */
if(!str) {
my_free(_ALLOC_ID_, &result);
result_size = 0;
return NULL;
}
/* allocate storage for result */
len = strlen(str) + 1;
if(len > result_size) {
result_size = len + CADCHUNKALLOC;
my_realloc(_ALLOC_ID_, &result, result_size);
}
memcpy(result, str, len);
i = 0;
while(result[i] && strchr(sep, result[i])) i++; /* strip off leading separators */
ptr = result + i;
for(count=1; result[i] != 0; ++i) {
if(strchr(sep, result[i])) {
result[i]=0;
if(count==n) {
dbg(1, "1 find_nth(): returning %s\n", ptr);
return ptr;
result_pos = 0;
for(i = 0; str[i]; i++) {
if(!e && strchr(quote, str[i])) {
q = !q;
if(keep_quote != 1) {
continue;
}
++i;
while(result[i] && strchr(sep, result[i])) i++;
ptr = result + i;
++count;
}
if(!e && str[i] =='\\') { /* only recognize escape if there are some quoting chars */
e = 1;
continue;
}
if(!e && !q && strchr(sep, str[i])) {
first_nonsep = 1;
if(count == n) { /* first == 1 --> separators at beginning are not preceded by a field */
break; /* we have found the 'count'th field, return. */
}
} else {
if(first_nonsep) count++; /* found a new field */
first_nonsep=0;
if(count == n) {
if(e == 1 && keep_quote) result[result_pos++] = '\\';
result[result_pos++] = str[i]; /* if field matches requested one store result */
}
}
e = 0;
}
if(count==n) {
dbg(1, "2 find_nth(): returning %s\n", ptr);
return ptr;
}
else {
result[0] = '\0';
dbg(1, "3 find_nth(): returning %s\n", result);
return result;
}
result[result_pos++] = '\0';
return result;
}
/* given a token like @#pin:attr get value of pin attribute 'attr'
@ -3298,7 +3319,7 @@ static char *get_pin_attr(const char *token, int inst, int s_pnetname)
sscanf(ss+1, "%s", tmpstr);
if(isonlydigit(tmpstr)) {
slot = atoi(tmpstr);
if(strstr(value,":")) my_strdup2(_ALLOC_ID_, &value, find_nth(value, ":", slot));
if(strstr(value,":")) my_strdup2(_ALLOC_ID_, &value, find_nth(value, ":", "", 0, slot));
}
}
my_free(_ALLOC_ID_, &tmpstr);
@ -3499,7 +3520,7 @@ const char *translate(int inst, const char* s)
{
int start_level; /* hierarchy level where waves were loaded */
int live = tclgetboolvar("live_cursor2_backannotate");
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->graph_annotate_p>=0) {
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) {
int multip;
int no_of_pins= (xctx->inst[inst].ptr + xctx->sym)->rects[PINLAYER];
if(no_of_pins == 1) {
@ -3541,7 +3562,7 @@ const char *translate(int inst, const char* s)
dbg(1, "translate() @spice_get_voltage: fqnet=%s start_level=%d\n", fqnet, start_level);
idx = get_raw_index(fqnet);
if(idx >= 0) {
val = xctx->graph_values[idx][xctx->graph_annotate_p];
val = xctx->raw->values[idx][xctx->raw->annot_p];
}
if(idx < 0) {
valstr = "";
@ -3569,7 +3590,7 @@ const char *translate(int inst, const char* s)
int start_level; /* hierarchy level where waves were loaded */
int live = tclgetboolvar("live_cursor2_backannotate");
dbg(1, "--> %s\n", token);
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->graph_annotate_p>=0) {
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) {
char *fqnet = NULL;
const char *path = xctx->sch_path[xctx->currsch] + 1;
char *net = NULL;
@ -3598,7 +3619,7 @@ const char *translate(int inst, const char* s)
dbg(1, "translate(): net=%s, fqnet=%s start_level=%d\n", net, fqnet, start_level);
idx = get_raw_index(fqnet);
if(idx >= 0) {
val = xctx->graph_values[idx][xctx->graph_annotate_p];
val = xctx->raw->values[idx][xctx->raw->annot_p];
}
if(idx < 0) {
valstr = "";
@ -3624,7 +3645,7 @@ const char *translate(int inst, const char* s)
{
int start_level; /* hierarchy level where waves were loaded */
int live = tclgetboolvar("live_cursor2_backannotate");
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->graph_annotate_p>=0) {
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) {
char *fqdev = NULL;
const char *path = xctx->sch_path[xctx->currsch] + 1;
char *dev = NULL;
@ -3666,7 +3687,7 @@ const char *translate(int inst, const char* s)
dbg(1, "fqdev=%s\n", fqdev);
idx = get_raw_index(fqdev);
if(idx >= 0) {
val = xctx->graph_values[idx][xctx->graph_annotate_p];
val = xctx->raw->values[idx][xctx->raw->annot_p];
}
if(idx < 0) {
valstr = "";
@ -3686,13 +3707,13 @@ const char *translate(int inst, const char* s)
} /* if(n == 1) */
my_free(_ALLOC_ID_, &dev);
} /* if(path) */
} /* if((start_level = sch_waves_loaded()) >= 0 && xctx->graph_annotate_p>=0) */
} /* if((start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) */
}
else if(strcmp(token,"@spice_get_diff_voltage")==0 )
{
int start_level; /* hierarchy level where waves were loaded */
int live = tclgetboolvar("live_cursor2_backannotate");
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->graph_annotate_p>=0) {
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) {
int multip;
int no_of_pins= (xctx->inst[inst].ptr + xctx->sym)->rects[PINLAYER];
if(no_of_pins == 2) {
@ -3727,11 +3748,11 @@ const char *translate(int inst, const char* s)
dbg(1, "translate(): fqnet2=%s start_level=%d\n", fqnet2, start_level);
idx1 = get_raw_index(fqnet1);
if(idx1 >= 0) {
val1 = xctx->graph_values[idx1][xctx->graph_annotate_p];
val1 = xctx->raw->values[idx1][xctx->raw->annot_p];
}
idx2 = get_raw_index(fqnet2);
if(idx2 >= 0) {
val2 = xctx->graph_values[idx2][xctx->graph_annotate_p];
val2 = xctx->raw->values[idx2][xctx->raw->annot_p];
}
val = val1 - val2;
if(idx1 < 0 || idx2 < 0) {
@ -3759,7 +3780,7 @@ const char *translate(int inst, const char* s)
{
int start_level; /* hierarchy level where waves were loaded */
int live = tclgetboolvar("live_cursor2_backannotate");
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->graph_annotate_p>=0) {
if(live && (start_level = sch_waves_loaded()) >= 0 && xctx->raw->annot_p>=0) {
char *fqdev = NULL;
const char *path = xctx->sch_path[xctx->currsch] + 1;
char *dev = NULL;
@ -3798,7 +3819,7 @@ const char *translate(int inst, const char* s)
strtolower(fqdev);
idx = get_raw_index(fqdev);
if(idx >= 0) {
val = xctx->graph_values[idx][xctx->graph_annotate_p];
val = xctx->raw->values[idx][xctx->raw->annot_p];
}
if(idx < 0) {
valstr = "";

View File

@ -508,7 +508,7 @@ int verilog_block_netlist(FILE *fd, int i)
if(extra) {
for(extra_ptr = extra; ; extra_ptr=NULL) {
extra_token=my_strtok_r(extra_ptr, " ", "", &saveptr1);
extra_token=my_strtok_r(extra_ptr, " ", "", 0, &saveptr1);
if(!extra_token) break;
if(tmp) fprintf(fd, " ,\n");
fprintf(fd, " %s", extra_token);
@ -550,7 +550,7 @@ int verilog_block_netlist(FILE *fd, int i)
if(extra2) {
saveptr1 = NULL;
for(extra_ptr = extra2; ; extra_ptr=NULL) {
extra_token=my_strtok_r(extra_ptr, " ", "", &saveptr1);
extra_token=my_strtok_r(extra_ptr, " ", "", 0, &saveptr1);
if(!extra_token) break;
fprintf(fd, " inout %s ;\n", extra_token);
fprintf(fd, " wire %s ;\n", extra_token);

View File

@ -329,8 +329,8 @@ int global_vhdl_netlist(int global) /* netlister driver */
for(i=0;i<xctx->sym[j].rects[PINLAYER]; ++i)
{
if(strboolcmp(get_tok_value(xctx->sym[j].rect[PINLAYER][i].prop_ptr,"vhdl_ignore",0), "true")) {
my_strdup(_ALLOC_ID_, &sig_type,get_tok_value(
xctx->sym[j].rect[PINLAYER][i].prop_ptr,"sig_type",0));
my_strdup(_ALLOC_ID_, &sig_type,
get_tok_value( xctx->sym[j].rect[PINLAYER][i].prop_ptr,"sig_type",0));
my_strdup(_ALLOC_ID_, &port_value,
get_tok_value(xctx->sym[j].rect[PINLAYER][i].prop_ptr,"value", 0) );
if(!sig_type || sig_type[0]=='\0') my_strdup(_ALLOC_ID_, &sig_type,"std_logic");

View File

@ -441,12 +441,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
xctx->mooz=1/CADINITIALZOOM;
xctx->xorigin=CADINITIALX;
xctx->yorigin=CADINITIALY;
xctx->graph_names = NULL;
xctx->graph_values = NULL;
xctx->graph_nvars = 0;
xctx->graph_npoints = NULL;
xctx->graph_allpoints = 0;
xctx->graph_datasets = 0;
xctx->raw = NULL;
xctx->graph_master = 0;
xctx->graph_cursor1_x = 0;
xctx->graph_flags = 0;
@ -454,11 +449,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
xctx->graph_bottom = 0;
xctx->graph_left = 0;
xctx->graph_lastsel = -1;
xctx->graph_sim_type = NULL; /* type of sim, "tran", "dc", "op", "ac", ... */
xctx->graph_annotate_p = -1; /* point in raw file to use for annotating voltages/currents/etc */
xctx->graph_struct.hilight_wave = -1; /* index of wave */
xctx->graph_raw_schname = NULL;
xctx->graph_raw_level = -1; /* hierarchy level where raw file has been read */
xctx->wires = 0;
xctx->instances = 0;
xctx->symbols = 0;
@ -474,12 +465,11 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
xctx->rectcolor= 4; /* this is the current layer when xschem started. */
xctx->currsch = 0;
xctx->ui_state = 0;
xctx->ui_state2 = 0;
xctx->lw = 0.0;
xctx->need_reb_sel_arr = 1;
xctx->lastsel = 0;
xctx->maxsel = 0;
xctx->graph_raw_table.size = 0;
xctx->graph_raw_table.table = NULL;
xctx->node_redraw_table.size = 0;
xctx->node_redraw_table.table = NULL;
xctx->prep_net_structs = 0;
@ -679,7 +669,7 @@ static void delete_schematic_data(int delete_pixmap)
escape_chars(NULL);
sanitize(NULL);
is_generator(NULL);
free_rawfile(0);
free_rawfile(&xctx->raw, 0);
free_xschem_data(); /* delete the xctx struct */
}
@ -903,7 +893,7 @@ static void xwin_exit(void)
translate(0, NULL); /* clear static data in function */
translate2(NULL, 0, NULL); /* clear static data in function */
subst_token(NULL, NULL, NULL); /* clear static data in function */
find_nth(NULL, "", 0); /* clear static data in function */
find_nth(NULL, "", "", 0, 0); /* clear static data in function */
tcl_hook2(NULL); /* clear static data in function */
save_ascii_string(NULL, NULL, 0); /* clear static data in function */
dbg(1, "xwin_exit(): removing font\n");

View File

@ -23,7 +23,7 @@
#ifndef CADGLOBALS
#define CADGLOBALS
#define XSCHEM_VERSION "3.4.4"
#define XSCHEM_VERSION "3.4.5"
#define XSCHEM_FILE_VERSION "1.2"
#if HAS_PIPE == 1
@ -209,39 +209,44 @@ extern char win_temp_dir[PATH_MAX];
#define CAD_TEDAX_NETLIST 4
#define CAD_SYMBOL_ATTRS 5
#define STARTWIRE 1U /* possible states, encoded in global 'rubber' */
#define STARTRECT 4U
#define STARTLINE 8U
#define SELECTION 16U /* signals that some objects are selected. */
#define STARTSELECT 32U /* used for drawing a selection rectangle */
#define STARTMOVE 64U /* used for move/copy operations */
#define STARTCOPY 128U /* used for move/copy operations */
#define STARTZOOM 256U /* used for move/copy operations */
#define STARTMERGE 512U /* used fpr merge schematic/symbol */
#define MENUSTARTWIRE 1024U /* start wire invoked from menu */
#define MENUSTARTLINE 2048U /* start line invoked from menu */
#define MENUSTARTRECT 4096U /* start rect invoked from menu */
#define MENUSTARTZOOM 8192U /* start zoom box invoked from menu */
#define STARTPAN 16384U /* new pan method with mouse button3 */
#define PLACE_TEXT 32768U
#define MENUSTARTSNAPWIRE 65536U /* start wire invoked from menu, snap to pin variant 20171022 */
#define STARTPOLYGON 131072U
#define MENUSTARTPOLYGON 262144U
#define STARTARC 524288U
#define MENUSTARTARC 1048576U
#define MENUSTARTCIRCLE 2097152U
#define PLACE_SYMBOL 4194304U /* used in move_objects after place_symbol to avoid storing intermediate undo state */
#define START_SYMPIN 8388608U
#define GRAPHPAN 16777216U /* bit 24 */
#define MENUSTARTMOVE 33554432U
#define MENUSTARTWIRECUT 67108864U /* bit 26 */
#define MENUSTARTWIRECUT2 134217728U /* bit 27 : do not align cut point to snap */
/* possible states, encoded in global 'ui_state' */
#define STARTWIRE 1U
#define STARTRECT 2U
#define STARTLINE 4U
#define SELECTION 8U /* signals that some objects are selected. */
#define STARTSELECT 16U /* used for drawing a selection rectangle */
#define STARTMOVE 32U /* used for move/copy operations */
#define STARTCOPY 64U /* used for move/copy operations */
#define STARTZOOM 128U /* used for move/copy operations */
#define STARTMERGE 256U /* used fpr merge schematic/symbol */
#define STARTPAN 512U /* new pan method with mouse button3 */
#define PLACE_TEXT 1024U
#define STARTPOLYGON 2048U
#define STARTARC 4096U
#define PLACE_SYMBOL 8192U /* used in move_objects after place_symbol to avoid storing intermediate undo state */
#define START_SYMPIN 16384U
#define GRAPHPAN 32768U /* bit 15 */
#define MENUSTART 65536U /* bit 16 */
#define SELECTED 1U /* used in the .sel field for selected objs. */
#define SELECTED1 2U /* first point selected... */
#define SELECTED2 4U /* second point selected... */
#define SELECTED3 8U
#define SELECTED4 16U
/* sub states encoded in global ui_state2 to reduce ui_state bits usage */
#define MENUSTARTWIRE 1U /* start wire invoked from menu */
#define MENUSTARTLINE 2U /* start line invoked from menu */
#define MENUSTARTRECT 4U /* start rect invoked from menu */
#define MENUSTARTZOOM 8U /* start zoom box invoked from menu */
#define MENUSTARTSNAPWIRE 16U /* start wire invoked from menu, snap to pin variant 20171022 */
#define MENUSTARTPOLYGON 32U
#define MENUSTARTARC 64U
#define MENUSTARTCIRCLE 128U
#define MENUSTARTMOVE 256U
#define MENUSTARTWIRECUT 512U
#define MENUSTARTWIRECUT2 1024U /* do not align cut point to snap */
#define WIRE 1 /* types of defined objects */
#define xRECT 2
#define LINE 4
@ -615,7 +620,6 @@ typedef struct
char *instname; /* 20150409 instance name (example: I23) */
} xInstance;
typedef struct
{
double x;
@ -756,6 +760,29 @@ struct hilight_hashentry
int time; /*delta-time for sims */
};
typedef struct {
/* spice raw file specific data */
char **names;
SPICE_DATA **values;
int nvars;
int *npoints;
int allpoints; /* all points of all datasets combined */
int datasets;
Int_hashtable table;
const char *sim_type; /* type of sim, "tran", "dc", "ac", "op", ... */
int annot_p; /* point in raw file to use for annotating schematic voltages/currents/etc */
/* when descending hierarchy xctx->current_name changes, xctx->raw_schname
* holds the name of the top schematic from which the raw file was loaded */
char *schname;
int level; /* hierarchy level where raw file has been read MIRRORED IN TCL*/
} Raw;
/* for netlist.c */
typedef struct instpinentry Instpinentry;
struct instpinentry
@ -874,8 +901,9 @@ typedef struct {
double zoom;
double mooz;
double lw;
unsigned int ui_state ; /* this signals that we are doing a net place,panning etc.
* used to prevent nesting of some commands */
unsigned int ui_state; /* this signals that we are doing a net place,panning etc.
* used to prevent nesting of some commands */
unsigned int ui_state2; /* sub states of ui_state MENUSTART bit */
double mousex,mousey; /* mouse coord. */
double mousex_snap,mousey_snap; /* mouse coord. snapped to grid */
double mx_double_save, my_double_save;
@ -1005,13 +1033,10 @@ typedef struct {
int undo_initialized;
/* graph context struct */
Graph_ctx graph_struct;
/* spice raw file specific data */
char **graph_names;
SPICE_DATA **graph_values;
int graph_nvars;
int *graph_npoints;
int graph_allpoints; /* all points of all datasets combined */
int graph_datasets;
Raw *raw; /* spice simulation data struct pointer */
/* */
/* data related to all graphs, so not stored in per-graph graph_struct */
double graph_cursor1_x;
double graph_cursor2_x;
@ -1030,13 +1055,6 @@ typedef struct {
int graph_bottom;
int graph_left;
int graph_lastsel; /* last graph that was clicked (selected) */
const char *graph_sim_type; /* type of sim, "tran", "dc", "ac", "op", ... */
int graph_annotate_p; /* point in raw file to use for annotating schematic voltages/currents/etc */
Int_hashtable graph_raw_table;
/* when descending hierarchy xctx->current_name changes, xctx->graph_raw_schname
* holds the name of the top schematic from which the raw file was loaded */
char *graph_raw_schname;
int graph_raw_level; /* hierarchy level where raw file has been read MIRRORED IN TCL*/
/* */
XSegment *biggridpoint;
XPoint *gridpoint;
@ -1163,7 +1181,7 @@ extern int filter_data(const char *din, const size_t ilen,
char **dout, size_t *olen, const char *cmd);
extern int embed_rawfile(const char *rawfile);
extern int read_rawfile_from_attr(const char *b64s, size_t length, const char *type);
extern int raw_read_from_attr(const char *type);
extern int raw_read_from_attr(Raw **rawptr, const char *type);
extern char *base64_from_file(const char *f, size_t *length);
extern int set_rect_flags(xRect *r);
extern int set_text_flags(xText *t);
@ -1176,8 +1194,8 @@ extern unsigned char *base64_decode(const char *data, const size_t input_length,
extern char *base64_encode(const unsigned char *data, const size_t input_length, size_t *output_length, int brk);
extern unsigned char *ascii85_encode(const unsigned char *data, const size_t input_length, size_t *output_length);
extern int get_raw_index(const char *node);
extern void free_rawfile(int dr);
extern int raw_read(const char *f, const char *type);
extern void free_rawfile(Raw **rawptr, int dr);
extern int raw_read(const char *f, Raw **rawptr, const char *type);
extern int table_read(const char *f);
extern double get_raw_value(int dataset, int idx, int point);
extern int plot_raw_custom_data(int sweep_idx, int first, int last, const char *ntok);
@ -1463,7 +1481,7 @@ extern void ptr_hash_free(Ptr_hashtable *hashtable);
extern Ptr_hashentry *ptr_hash_lookup(Ptr_hashtable *hashtable,
const char *token, void * const value, int what);
extern char *find_nth(const char *str, const char *sep, int n);
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 *translate(int inst, const char* s);
extern const char* translate2(Lcc *lcc, int level, char* s);
@ -1482,7 +1500,7 @@ extern void my_strndup(int id, char **dest, const char *src, size_t n);
extern size_t my_strdup2(int id, char **dest, const char *src);
extern char *my_fgets(FILE *fd, size_t *line_len);
extern size_t my_fgets_skip(FILE *fd);
extern char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr);
extern char *my_strtok_r(char *str, const char *delim, const char *quote, int keep_quote, char **saveptr);
extern char **parse_cmd_string(const char *cmd, int *argc);
extern int my_strncpy(char *d, const char *s, size_t n);
extern int my_strcasecmp(const char *s1, const char *s2);

View File

@ -743,12 +743,12 @@ namespace eval ngspice {
}
proc ngspice::get_current {n} {
global graph_raw_level
global raw_level
set path [string range [xschem get sch_path] 1 end]
# skip hierarchy components above the level where raw file has been loaded.
# node path names to look up in raw file begin from there.
set skip 0
while { $skip < $graph_raw_level } {
while { $skip < $raw_level } {
regsub {^[^.]*\.} $path {} path
incr skip
}
@ -787,12 +787,12 @@ proc ngspice::get_current {n} {
}
proc ngspice::get_diff_voltage {n m} {
global graph_raw_level
global raw_level
set path [string range [xschem get sch_path] 1 end]
# skip hierarchy components above the level where raw file has been loaded.
# node path names to look up in raw file begin from there.
set skip 0
while { $skip < $graph_raw_level } {
while { $skip < $raw_level } {
regsub {^[^.]*\.} $path {} path
incr skip
}
@ -818,12 +818,12 @@ proc ngspice::get_diff_voltage {n m} {
proc ngspice::get_voltage {n} {
global graph_raw_level
global raw_level
set path [string range [xschem get sch_path] 1 end]
# skip hierarchy components above the level where raw file has been loaded.
# node path names to look up in raw file begin from there.
set skip 0
while { $skip < $graph_raw_level } {
while { $skip < $raw_level } {
regsub {^[^.]*\.} $path {} path
incr skip
}
@ -853,12 +853,12 @@ proc update_schematic_header {} {
}
proc ngspice::get_node {n} {
global graph_raw_level
global raw_level
set path [string range [xschem get sch_path] 1 end]
# skip hierarchy components above the level where raw file has been loaded.
# node path names to look up in raw file begin from there.
set skip 0
while { $skip < $graph_raw_level } {
while { $skip < $raw_level } {
regsub {^[^.]*\.} $path {} path
incr skip
}
@ -1741,7 +1741,7 @@ proc graph_add_nodes_from_list {nodelist} {
set node [string trim [.graphdialog.center.right.text1 get 1.0 {end - 1 chars}] " \n"]
xschem setprop rect 2 $graph_selected color $col fastundo
graph_update_nodelist
regsub -all {\\?(["\\])} $node {\\\1} node_quoted ;#"4vim
regsub -all {[\\"]} $node "\\\\&" node_quoted
xschem setprop rect 2 $graph_selected node $node_quoted fast
xschem draw_graph $graph_selected
}
@ -1774,7 +1774,7 @@ proc graph_add_nodes_from_list {nodelist} {
append nnn "\n"
}
append nnn $sel
regsub -all {\\?(["\\])} $nnn {\\\1} node_quoted ;#"4vim
regsub -all {[\\"]} $nnn "\\\\&" node_quoted
xschem setprop rect 2 [xschem get graph_lastsel] node $node_quoted fast
xschem draw_graph [xschem get graph_lastsel]
}
@ -1918,7 +1918,7 @@ proc graph_fill_listbox {} {
proc graph_update_node {node} {
global graph_selected
graph_update_nodelist
regsub -all {\\?(["\\])} $node {\\\1} node_quoted ;#"4vim
regsub -all {[\\"]} $node "\\\\&" node_quoted
graph_push_undo
xschem setprop rect 2 $graph_selected node $node_quoted fast
xschem draw_graph $graph_selected
@ -2354,7 +2354,7 @@ proc graph_edit_properties {n} {
eval .graphdialog.center.left.list1 insert 0 [graph_get_signal_list [xschem raw_query list] {}]
# fill data in right textbox
set plotted_nodes [xschem getprop rect 2 $n node]
set plotted_nodes [xschem getprop rect 2 $n node 0]
if {[string length $plotted_nodes] > 0 && [string index $plotted_nodes end] ne "\n"} {append plotted_nodes \n}
.graphdialog.center.right.text1 insert 1.0 $plotted_nodes
graph_update_nodelist
@ -3772,7 +3772,7 @@ proc tclpropeval {s instname symname} {
# this hook is called in translate() if whole string is contained in a tcleval(...) construct
proc tclpropeval2 {s} {
global debug_var env path graph_raw_level
global debug_var env path raw_level
set netlist_type [xschem get netlist_type]
# puts "tclpropeval2: s=|$s|"
@ -3781,7 +3781,7 @@ proc tclpropeval2 {s} {
# skip hierarchy components above the level where raw file has been loaded.
# node path names to look up in raw file begin from there.
set skip 0
while { $skip < $graph_raw_level } {
while { $skip < $raw_level } {
regsub {^[^.]*\.} $path {} path
incr skip
}
@ -5590,19 +5590,19 @@ set tctx::global_list {
autotrim_wires bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers
cadsnap cairo_font_name change_lw color_ps colors compare_sch constrained_move
copy_cell crosshair_layer custom_label_prefix custom_token dark_colors dark_colorscheme
delay_flag dim_bg dim_value
disable_unique_names do_all_inst draw_crosshair draw_grid draw_window edit_prop_pos edit_prop_size
delay_flag dim_bg dim_value disable_unique_names do_all_inst draw_crosshair
draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size
edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch
filetmp fix_broken_tiled_fill flat_netlist fullscreen gaw_fd gaw_tcp_address graph_bus
graph_change_done graph_digital graph_linewidth_mult graph_logx
graph_logy graph_rainbow graph_raw_level graph_schname graph_sel_color graph_sel_wave
graph_logy graph_rainbow graph_schname graph_sel_color graph_sel_wave
graph_selected graph_sort graph_unlocked hide_empty_graphs hide_symbols hsize
incr_hilight infowindow_text input_line_cmd input_line_data launcher_default_program
light_colors line_width live_cursor2_backannotate local_netlist_dir lvs_ignore
lvs_netlist measure_text netlist_dir netlist_show netlist_type no_ask_save
no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes path pathlist
persistent_command preserve_unchanged_attrs prev_symbol ps_colors ps_paper_size rainbow_colors
rawfile_loaded rcode recentfile
raw_level rawfile_loaded rcode recentfile
replace_key retval retval_orig rotated_text search_case search_exact search_found search_schematic
search_select search_value selected_tok show_hidden_texts show_infowindow
show_infowindow_after_netlist show_pin_net_names
@ -6791,6 +6791,7 @@ set_ne unselect_partial_sel_wires 0
set_ne draw_crosshair 0
set_ne draw_grid 1
set_ne big_grid_points 0
set_ne draw_grid_axes 1
set_ne persistent_command 0
set_ne autotrim_wires 0
set_ne compare_sch 0
@ -6821,7 +6822,7 @@ set_ne graph_rainbow 0
set_ne graph_selected {}
set_ne graph_schname {}
set_ne graph_change_done 0 ;# used to push undo only once when editing graphs
set_ne graph_raw_level -1 ;# hierarchy level where raw file has been loaded
set_ne raw_level -1 ;# hierarchy level where raw file has been loaded
set_ne graph_linewidth_mult 2.0 ;# default multiplier (w.r.t. xschem lines) for line width in graphs
# user clicked this wave
set_ne graph_sel_wave {}
@ -6889,7 +6890,7 @@ if {!$rainbow_colors} {
"#aa2222" "#7ccc40" "#00ffcc" "#ce0097" "#d2d46b"
"#ef6158" "#fdb200"}
set_ne dark_colors {
"#000000" "#00ccee" "#3f3f3f" "#cccccc" "#88dd00"
"#000000" "#00ccee" "#4f4f4f" "#cccccc" "#88dd00"
"#bb2200" "#00ccee" "#ff0000" "#ffff00" "#ffffff"
"#ff00ff" "#00ff00" "#0044dd" "#aaaa00" "#aaccaa"
"#ff7777" "#bfff81" "#00ffcc" "#ce0097" "#d2d46b"

View File

@ -219,6 +219,9 @@
#### enable to scale grid point size as done with lines at close zoom, default: 0
# set big_grid_points 0
#### enable drawing grid axes. Default: enabled (1)
# set draw_grid_axes 1
#### enable grouping contiguous bits of bus slices in net->pin instance
#### assignments for verilog netlists. Default: disabled (0)
# set verilog_bitblast 0