diff --git a/src/actions.c b/src/actions.c index d597b7dd..b855278b 100644 --- a/src/actions.c +++ b/src/actions.c @@ -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], "."); diff --git a/src/callback.c b/src/callback.c index 75ed6b8c..bc06712c 100644 --- a/src/callback.c +++ b/src/callback.c @@ -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) { diff --git a/src/draw.c b/src/draw.c index 83864944..e2bb3290 100644 --- a/src/draw.c +++ b/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;pgc[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;pgraph_names[idx]); + } else dbg(1, "skipping wave: %s\n", raw->names[idx]); for(p=0;pgc[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); diff --git a/src/editprop.c b/src/editprop.c index 15ec5d53..a8e6771a 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -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); } diff --git a/src/gschemtoxschem.awk b/src/gschemtoxschem.awk index 73cf0b80..1bf9fdbb 100755 --- a/src/gschemtoxschem.awk +++ b/src/gschemtoxschem.awk @@ -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$/) { diff --git a/src/hilight.c b/src/hilight.c index 49f5f8c1..b3b1bb6f 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -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 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 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; diff --git a/src/make_sch_from_spice.awk b/src/make_sch_from_spice.awk index be7766cd..3df7c235 100755 --- a/src/make_sch_from_spice.awk +++ b/src/make_sch_from_spice.awk @@ -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) diff --git a/src/make_sym.awk b/src/make_sym.awk index 05eb95f5..f1f8f883 100755 --- a/src/make_sym.awk +++ b/src/make_sym.awk @@ -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 diff --git a/src/netlist.c b/src/netlist.c index b0b23ce7..ecb95693 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -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 */ diff --git a/src/save.c b/src/save.c index 7cbbd168..1d221f3f 100644 --- a/src/save.c +++ b/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 : ""); 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 : ""); + 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 : ""); } 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 : ""); + 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 : ""); } 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 : ""); + 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 : ""); } 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 : ""); + 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 : ""); } 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]; } } } diff --git a/src/scheduler.c b/src/scheduler.c index 757cda7b..77f823bb 100644 --- a/src/scheduler.c +++ b/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 ", 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); } diff --git a/src/symgen.awk b/src/symgen.awk index 00ce09ce..8d7cabe5 100755 --- a/src/symgen.awk +++ b/src/symgen.awk @@ -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) diff --git a/src/systemlib/font.sch b/src/systemlib/font.sch index 45889e2a..d602e8ea 100644 --- a/src/systemlib/font.sch +++ b/src/systemlib/font.sch @@ -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 {} diff --git a/src/token.c b/src/token.c index 9ba6127b..981f977e 100644 --- a/src/token.c +++ b/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 = ""; diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 7a8a014b..526e4b8d 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -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); diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 0dd0d976..9f5c6057 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -329,8 +329,8 @@ int global_vhdl_netlist(int global) /* netlister driver */ for(i=0;isym[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"); diff --git a/src/xinit.c b/src/xinit.c index 58d90001..d31beb9a 100644 --- a/src/xinit.c +++ b/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"); diff --git a/src/xschem.h b/src/xschem.h index 529a465d..518bf4e3 100644 --- a/src/xschem.h +++ b/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); diff --git a/src/xschem.tcl b/src/xschem.tcl index fca65c2a..61ce9bfe 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -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" diff --git a/src/xschemrc b/src/xschemrc index c82ecbe7..0cfbe6aa 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -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