From 58a43ccc4df91e8072614999f7c93cd8ade80bdb Mon Sep 17 00:00:00 2001 From: schippes Date: Sat, 15 Aug 2020 10:48:26 +0200 Subject: [PATCH] code cleanups, preparing for editprop combobox token selector --- src/save.c | 26 +++--- src/scheduler.c | 47 ++++++----- src/token.c | 84 +++++++++++++++---- src/xinit.c | 1 + src/xschem.h | 1 + src/xschem.tcl | 20 +++-- .../examples/LCC_instances_embed.sch | 10 ++- 7 files changed, 124 insertions(+), 65 deletions(-) diff --git a/src/save.c b/src/save.c index e6b0ee41..f69d8a2b 100644 --- a/src/save.c +++ b/src/save.c @@ -820,26 +820,22 @@ void load_ascii_string(char **ptr, FILE *fd) return; } if(begin) { - if(c=='\\') { - escape=1; - c=fgetc(fd); - if(c==EOF) { - fprintf(errfp, "EOF reached, malformed {...} string input, missing close brace\n"); - my_free(1150, ptr); - my_free(890, &str); - return; - } - } else escape=0; - str[i]=c; - if(c=='}' && !escape) { - str[i]='\0'; - break; + if(!escape) { + if(c=='}') { + str[i]='\0'; + break; + } + if(c=='\\') { + escape=1; + continue; + } } + str[i]=c; + escape = 0; i++; } else if(c=='{') begin=1; } dbg(2, "load_ascii_string(): string read=%s\n",str? str:""); - /* fscanf(fd, " "); */ my_strdup(329, ptr, str); dbg(2, "load_ascii_string(): loaded %s\n",*ptr? *ptr:""); my_free(891, &str); diff --git a/src/scheduler.c b/src/scheduler.c index daa69620..b9a0d8ea 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1344,6 +1344,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg enable_layers(); Tcl_ResetResult(interp); } + else if(argc == 4 && !strcmp(argv[1], "list_tokens")) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, list_tokens(argv[2], atoi(argv[3])), NULL); + } else if(!strcmp(argv[1],"select_connected_nets")) { @@ -1428,28 +1432,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg return TCL_OK; } } - - /* 20171010 allows to retrieve name of n-th parent schematic */ - else if(argc >= 3 && !strcmp(argv[1],"get") && !strcmp(argv[2],"schname") ) { - int x; - if(argc == 4) x = atoi(argv[3]); - else x = currentsch; - if(x<0 && currentsch+x>=0) { - Tcl_AppendResult(interp, schematic[currentsch+x], NULL); - } else if(x<=currentsch) { - Tcl_AppendResult(interp, schematic[x], NULL); - } - } - else if(argc >=3 && !strcmp(argv[1],"get") && !strcmp(argv[2],"sch_path")) { /* 20121121 */ - int x; - if(argc == 4) x = atoi(argv[3]); - else x = currentsch; - if(x<0 && currentsch+x>=0) { - Tcl_AppendResult(interp, sch_path[currentsch+x], NULL); - } else if(x<=currentsch) { - Tcl_AppendResult(interp, sch_path[x], NULL); - } - } else if(!strcmp(argv[1],"instance_bbox")) { int i; char s[200]; @@ -1508,6 +1490,27 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg * ********** xschem get subcommands */ + /* 20171010 allows to retrieve name of n-th parent schematic */ + else if(argc >= 3 && !strcmp(argv[1],"get") && !strcmp(argv[2],"schname") ) { + int x; + if(argc == 4) x = atoi(argv[3]); + else x = currentsch; + if(x<0 && currentsch+x>=0) { + Tcl_AppendResult(interp, schematic[currentsch+x], NULL); + } else if(x<=currentsch) { + Tcl_AppendResult(interp, schematic[x], NULL); + } + } + else if(argc >=3 && !strcmp(argv[1],"get") && !strcmp(argv[2],"sch_path")) { /* 20121121 */ + int x; + if(argc == 4) x = atoi(argv[3]); + else x = currentsch; + if(x<0 && currentsch+x>=0) { + Tcl_AppendResult(interp, sch_path[currentsch+x], NULL); + } else if(x<=currentsch) { + Tcl_AppendResult(interp, sch_path[x], NULL); + } + } else if(argc == 4 && !strcmp(argv[1],"get") && !strcmp(argv[2],"expandlabel")) { /* 20121121 */ int tmp, llen; char *result=NULL; diff --git a/src/token.c b/src/token.c index 616c5902..10ab7091 100644 --- a/src/token.c +++ b/src/token.c @@ -399,6 +399,65 @@ int set_different_token(char **s,char *new, char *old, int object, int n) return mod; } +/* return a string containing the list of all tokens in s */ +/* with_quotes: */ +/* 0: eat non escaped quotes (") */ +/* 1: return unescaped quotes as part of the token value if they are present */ +/* 2: eat backslashes */ +const char *list_tokens(const char *s, int with_quotes) +{ + static char *token=NULL; + static int sizetok=0; + register int c, state=XBEGIN, space; + register int token_pos=0; + int quote=0; + int escape=0; + + if(s==NULL) { + my_free(435, &token); + sizetok = 0; + return "";; + } + while(1) { + c=*s++; + space=SPACE(c) ; + if( (state==XBEGIN || state==XENDTOK) && !space && c != '=') state=XTOKEN; + else if( state==XTOKEN && space && !quote && !escape) state=XENDTOK; + else if( (state==XTOKEN || state==XENDTOK) && c=='=') state=XSEPARATOR; + else if( state==XSEPARATOR && !space) state=XVALUE; + else if( state==XVALUE && space && !quote && !escape ) state=XEND; + if(token_pos>=sizetok) { + sizetok+=CADCHUNKALLOC; + my_realloc(434, &token,sizetok); + token[0] = '\0'; + } + if(c=='"') { + if(!escape) quote=!quote; + } + if(state==XTOKEN) { + if(c=='"') { + if((with_quotes & 1) || escape) token[token_pos++]=c; + } + else if( !(c == '\\' && (with_quotes & 2)) ) token[token_pos++]=c; + else if(escape && c == '\\') token[token_pos++]=c; + } else if(state==XVALUE) { + /* do nothing */ + } else if(state==XENDTOK || state==XSEPARATOR) { + if(token_pos) { + token[token_pos++]= ' '; + } + } else if(state==XEND) { + state=XBEGIN; + } + escape = (c=='\\' && !escape); + if(c=='\0') { + if(token_pos) { + token[token_pos-1]= (c != '\0' ) ? ' ' : '\0'; + } + return token; + } + } +} /* state machine that parses a string made up of = ... */ /* couples and returns the value of the given token */ @@ -428,12 +487,6 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) return ""; } get_tok_value_size = get_tok_size = 0; - if(!size) { - size=CADCHUNKALLOC; - sizetok=CADCHUNKALLOC; - my_realloc(434, &result,size); - my_realloc(435, &token,sizetok); - } dbg(2, "get_tok_value(): looking for <%s> in <%s>\n",tok,s); while(1) { c=*s++; @@ -866,18 +919,17 @@ const char *get_cell_w_ext(const char *str, int no_of_dir) } - - int count_labels(char *s) +/* not used? */ +int count_labels(char *s) { - int i=1; - int c; + int i=1; + int c; - if(s==NULL) return 1; - while( (c=(*s++)) ) - { - if(c==',') i++; - } - return i; + if(s==NULL) return 1; + while( (c=(*s++)) ) { + if(c==',') i++; + } + return i; } void print_vhdl_element(FILE *fd, int inst) /* 20071217 */ diff --git a/src/xinit.c b/src/xinit.c index 30fc04a0..85217185 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -291,6 +291,7 @@ void xwin_exit(void) clear_expandlabel_data(); get_sym_template(NULL, NULL); /* clear static data in function */ get_tok_value(NULL, NULL, 0); /* clear static data in function */ + list_tokens(NULL, 0); /* clear static data in function */ 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 */ diff --git a/src/xschem.h b/src/xschem.h index fcdeef61..91035aea 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -899,6 +899,7 @@ extern void print_verilog_element(FILE *fd, int inst); extern void print_verilog_primitive(FILE *fd, int inst); extern void print_vhdl_primitive(FILE *fd, int inst); extern const char *get_tok_value(const char *s,const char *tok,int with_quotes); +extern const char *list_tokens(const char *s, int with_quotes); extern int my_snprintf(char *str, int size, const char *fmt, ...); extern size_t my_strdup(int id, char **dest, const char *src); extern void my_strndup(int id, char **dest, const char *src, int n); diff --git a/src/xschem.tcl b/src/xschem.tcl index e24cbbbf..de361c45 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1969,7 +1969,7 @@ proc change_color {} { } proc edit_prop {txtlabel} { - global edit_prop_default_geometry infowindow_text + global edit_prop_default_geometry infowindow_text selected_tok global prev_symbol retval symbol rcode no_change_attrs preserve_unchanged_attrs copy_cell tcl_debug editprop_semaphore global user_wants_copy_cell editprop_sympath set user_wants_copy_cell 0 @@ -2032,7 +2032,7 @@ proc edit_prop {txtlabel} { set prev_symbol [abs_sym_path $prev_symbol] if { ($abssymbol ne $prev_symbol) && $copy_cell } { - if { ![regexp {^/} $symbol] } { + if { ![regexp {^/} $symbol] && ![regexp {^[a-zA-Z]:} $symbol] } { set symlist [file split $symbol] set symlen [llength $symlist] set abssymbol "[path_head $prev_symbol $symlen]/$symbol" @@ -2079,9 +2079,11 @@ proc edit_prop {txtlabel} { } checkbutton .dialog.f2.r1 -text "No change properties" -variable no_change_attrs -state normal checkbutton .dialog.f2.r2 -text "Preserve unchanged props" -variable preserve_unchanged_attrs -state normal - checkbutton .dialog.f2.r3 -text "Copy cell" -variable copy_cell -state normal -command { - - } + checkbutton .dialog.f2.r3 -text "Copy cell" -variable copy_cell -state normal + set tok_list " [xschem list_tokens $retval 0]" + set selected_tok {} + label .dialog.f2.r4 -text { Edit Attr:} + ttk::combobox .dialog.f2.r5 -values $tok_list -textvariable selected_tok -state readonly -width 10 pack .dialog.f1.l2 .dialog.f1.e2 .dialog.f1.b1 .dialog.f1.b2 .dialog.f1.b3 .dialog.f1.b4 .dialog.f1.b5 -side left -expand 1 pack .dialog.f4 -side top -anchor nw @@ -2092,6 +2094,8 @@ proc edit_prop {txtlabel} { pack .dialog.f2.r1 -side left pack .dialog.f2.r2 -side left pack .dialog.f2.r3 -side left + # pack .dialog.f2.r4 -side left + # pack .dialog.f2.r5 -side left pack .dialog.yscroll -side right -fill y pack .dialog.xscroll -side bottom -fill x pack .dialog.e1 -fill both -expand yes @@ -2432,7 +2436,7 @@ proc rel_sym_path {symbol} { global pathlist current_dirname set name {} - if {[regexp {^/} $symbol]} {set symbol [file normalize $symbol]} + if {[regexp {^/} $symbol] || [regexp {^[A-Za-z]:} $symbol]} {set symbol [file normalize $symbol]} foreach path_elem $pathlist { if { ![string compare $path_elem .] && [info exist current_dirname]} { set path_elem $current_dirname @@ -2476,7 +2480,7 @@ proc abs_sym_path {fname {ext {} } } { regsub {^\./} $fname {} fname } set name {} - if { ![regexp {^/} $fname] } { + if { ![regexp {^/} $fname] && ![regexp {^[A-Za-z]:} $fname] } { foreach path_elem $pathlist { if { ![string compare $path_elem .] && [info exist current_dirname]} { set path_elem $current_dirname @@ -2489,7 +2493,7 @@ proc abs_sym_path {fname {ext {} } } { } } if { ![string compare $name {}] } { - if { [regexp {^/} $fname] } { + if { [regexp {^/} $fname] || [regexp {^[a-zA-Z]:} $fname] } { set name $fname } else { set name "$current_dirname/$fname" diff --git a/xschem_library/examples/LCC_instances_embed.sch b/xschem_library/examples/LCC_instances_embed.sch index 259f515a..6853d0db 100644 --- a/xschem_library/examples/LCC_instances_embed.sch +++ b/xschem_library/examples/LCC_instances_embed.sch @@ -260,8 +260,8 @@ C {cmos_inv.sch} 140 -300 0 0 {name=Xinv WN=15u WP=45u LLN=3u LLP=3u embed=true} [ v {xschem version=2.9.7 file_version=1.2} G {type=subcircuit -format="@name @pinlist @symname WN=@WN WP=@WP LLN=@LLN LLP=@LLP" -template="name=X1 WN=15u WP=45u LLN=3u LLP=3u" +format="@name @pinlist @symname WN=@WN WP=@WP LLN=@LLN LLP=@LLP m=@m" +template="name=X1 WN=15u WP=45u LLN=3u LLP=3u m=1" } V {} S {} @@ -343,6 +343,8 @@ C {cmos_inv.sym} 280 -230 0 0 {name=Xinv2 WN=15u WP=45u LLN=3u LLP=3u embed=true v {xschem version=2.9.7 file_version=1.2} G {type=subcircuit format="@name @pinlist @symname WN=@WN WP=@WP LLN=@LLN LLP=@LLP m=@m" +verilog_primitive=true +verilog_format="assign #80 @@Z = ~ @@A ;" template="name=X1 WN=15u WP=45u LLN=3u LLP=3u m=1" } V {} @@ -496,7 +498,7 @@ B 7 348.75 -741.25 351.25 -738.75 {name=p dir=in} T {@name} 250 -915 0 0 0.5 0.5 {} T {@symname} 253.75 -115 0 0 0.5 0.5 {} T {$X2} 300 -475 0 0 0.2 0.2 {} -T {cmos_inv.sch} 303.75 -155 0 0 0.2 0.2 {} +T {cmos_inv} 303.75 -155 0 0 0.2 0.2 {} T {$15u\\/$3u\\/$1} 367.5 -258.75 0 0 0.2 0.2 {} T {$M1} 367.5 -233.75 0 0 0.2 0.2 {} T {D} 385 -267.5 0 0 0.15 0.15 {} @@ -510,7 +512,7 @@ T {$Z} 426.25 -316.25 0 1 0.2 0.2 {} T {$0} 387.5 -248.125 0 0 0.33 0.33 {} T {$VDD} 387.5 -368.125 0 0 0.33 0.33 {} T {$X1} 430 -855 0 1 0.2 0.2 {} -T {cmos_inv.sch} 426.25 -535 0 1 0.2 0.2 {} +T {cmos_inv} 426.25 -535 0 1 0.2 0.2 {} T {$WN_FB\\/$3u\\/$1} 362.5 -638.75 0 1 0.2 0.2 {} T {$M1} 362.5 -613.75 0 1 0.2 0.2 {} T {D} 345 -647.5 0 1 0.15 0.15 {}