merged in fast_raw_read branch
This commit is contained in:
parent
3a25109fe1
commit
9b4bd44fd0
|
|
@ -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], ".");
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
261
src/draw.c
261
src/draw.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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$/) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
352
src/save.c
352
src/save.c
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
153
src/scheduler.c
153
src/scheduler.c
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
143
src/token.c
143
src/token.c
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
18
src/xinit.c
18
src/xinit.c
|
|
@ -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");
|
||||
|
|
|
|||
118
src/xschem.h
118
src/xschem.h
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue