From 5c7abfa0485ca39454bf1294c5626fb12fd71192 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 3 Oct 2023 15:20:30 +0200 Subject: [PATCH] optimization for new_prop_string() done. doc updates for instance hide_texts=true attribute, align strboolcmp() to tcl allowed boolean values (1, true, on, yes) --- doc/xschem_man/component_property_syntax.html | 2 + src/editprop.c | 23 ++++++--- src/token.c | 49 +++++++++++++------ src/track_memory.awk | 10 +++- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/doc/xschem_man/component_property_syntax.html b/doc/xschem_man/component_property_syntax.html index 9c2dafd2..0e5dbfee 100644 --- a/doc/xschem_man/component_property_syntax.html +++ b/doc/xschem_man/component_property_syntax.html @@ -125,6 +125,8 @@ name="mchanged_name" model=\"nmos\" w="20u" l="3u" m="10" symbols.

  • hide
  • A hide=true attribute will only display the symbol bounding box.

    +
  • hide_texts
  • +

    A hide_texts=true attribute will hide all symbol texts.

  • highlight
  • If set to true the symbol will be highlighted when one of the nets attached to its pins are highlighted.

  • net_name
  • diff --git a/src/editprop.c b/src/editprop.c index 936f6222..7e5960ad 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -79,16 +79,23 @@ int my_strncasecmp(const char *s1, const char *s2, size_t n) return tolower(*s1) - tolower(*s2); } -/* same as strcmp(), but allow "1" for "true" and "0" for "false" */ + +/* same as case insensitive strcmp(), but allow '1, true, on, yes' for true value + * both in str and boolean */ int strboolcmp(const char *str, const char *boolean) { - if(!my_strcasecmp(boolean, "true")) { - return (my_strcasecmp(str, "true") != 0 && strcmp(str,"1") != 0); - } else if(!my_strcasecmp(boolean, "false")) { - return (my_strcasecmp(str, "false") != 0 && strcmp(str,"0") != 0); - } else { - return strcmp(str, boolean); - } + int s = 0, b = 0; + if(!my_strcasecmp(boolean, "true") || + !my_strcasecmp(boolean, "1") || + !my_strcasecmp(boolean, "on") || + !my_strcasecmp(boolean, "yes")) b = 1; + + if(!my_strcasecmp(str, "true") || + !my_strcasecmp(str, "1") || + !my_strcasecmp(str, "on") || + !my_strcasecmp(str, "yes")) s = 1; + + return (s != b); } /* return lenght of line and skip */ diff --git a/src/token.c b/src/token.c index 5cc459d0..d61a6057 100644 --- a/src/token.c +++ b/src/token.c @@ -635,9 +635,17 @@ static char *get_pin_attr_from_inst(int inst, int pin, const char *attr) return pin_attr_value; /* caller is responsible for freeing up storage for pin_attr_value */ } -int get_last_used_index(const char *old_name_base, const char *brkt) +int get_last_used_index(const char *old_basename, const char *brkt) { - return 1; + int retval = 1; + Int_hashentry *entry; + size_t size = strlen(old_basename) + strlen(brkt)+40; + char *refname = my_malloc(_ALLOC_ID_, size); + my_snprintf(refname, size, "_@%s@%s", old_basename, brkt); + entry = int_hash_lookup(&xctx->inst_name_table, refname, 0, XLOOKUP); + if(entry) retval = entry->value; + my_free(_ALLOC_ID_, &refname); + return retval; } /* if inst == -1 hash all instance names, else do only given instance @@ -678,8 +686,14 @@ void hash_names(int inst, int action) if(upinst) my_free(_ALLOC_ID_, &upinst); } -/* return -1 if name is not used, else return first instance number with same name found */ -static int name_is_used(char *name, int q) +/* return -1 if name is not used, else return first instance number with same name found + * old_basename: base name (without [...]) of instance name the new 'name' was built from + * brkt: pointer to '[...]' part of instance name (or empty string if no [...] found) + * q: integer number added to 'name' when trying an unused instance name + * (name = old_basename + q + bracket) + * or -1 if only testing for unique 'name'. + */ +static int name_is_used(char *name, const char *old_basename, const char *brkt, int q) { int mult, used = -1; char *upinst = NULL; @@ -698,6 +712,14 @@ static int name_is_used(char *name, int q) } my_free(_ALLOC_ID_, &upinst); dbg(1, "name_is_used(%s): return inst %d\n", name, used); + + if(q != -1 && used == -1) { + size_t size = strlen(old_basename) + strlen(brkt)+40; + char *refname = my_malloc(_ALLOC_ID_, size); + my_snprintf(refname, size, "_@%s@%s", old_basename, brkt); + int_hash_lookup(&xctx->inst_name_table, refname, q, XINSERT); + my_free(_ALLOC_ID_, &refname); + } return used; } @@ -732,7 +754,7 @@ void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names) } /* don't change old_prop if name does not conflict. */ /* if no hash_names() is done and inst_table uninitialized --> use old_prop */ - is_used = name_is_used(old_name, -1); + is_used = name_is_used(old_name, "", "", -1); if(dis_uniq_names || is_used == -1 || is_used == i) { my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, old_prop); my_free(_ALLOC_ID_, &old_name); @@ -741,18 +763,15 @@ void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names) /* old_name is not unique. Find another unique name */ old_name_base = my_malloc(_ALLOC_ID_, old_name_len+1); n = sscanf(old_name, "%[^[0-9]",old_name_base); - brkt=find_bracket(old_name); - my_realloc(_ALLOC_ID_, &new_name, old_name_len + 40); /* strlen(old_name)+40); */ + if(!n) old_name_base[0] = '\0'; /* there is no basename (like in "[3:0]" or "12"), set to empty string */ + brkt=find_bracket(old_name); /* if no bracket found will point to end of string ('\0') */ + my_realloc(_ALLOC_ID_, &new_name, old_name_len + 40); qq = get_last_used_index(old_name_base, brkt); /* */ - for(q = qq ;; ++q) { - if(n) { - my_snprintf(new_name, old_name_len + 40, "%s%d%s", old_name_base, q, brkt); - } else { /* goes here if weird name set for example to name=[3:0] or name=12 */ - my_snprintf(new_name, old_name_len + 40, "%d%s", q, brkt); - } - is_used = name_is_used(new_name, q); + for(q = qq;; ++q) { + my_snprintf(new_name, old_name_len + 40, "%s%d%s", old_name_base, q, brkt); + is_used = name_is_used(new_name, old_name_base, brkt, q); if(is_used == -1 ) break; } my_free(_ALLOC_ID_, &old_name_base); @@ -790,7 +809,7 @@ void check_unique_names(int rename) if(xctx->inst[i].instname && xctx->inst[i].instname[0]) { if(xctx->inst[i].ptr == -1) continue; if(!(xctx->inst[i].ptr+ xctx->sym)->type) continue; - used = name_is_used(xctx->inst[i].instname, -1); + used = name_is_used(xctx->inst[i].instname,"", "", -1); hash_names(i, XINSERT_NOREPLACE); if( used != -1 && used != i) { dbg(0, "check_unique_names(): found duplicate: i=%d name=%s\n", i, xctx->inst[i].instname); diff --git a/src/track_memory.awk b/src/track_memory.awk index 17c6ed2f..f43f9f56 100755 --- a/src/track_memory.awk +++ b/src/track_memory.awk @@ -1,9 +1,9 @@ #!/usr/bin/awk -f # memory leak analyzer. Run xschem with options "-d 3 -l log", do some operations you want to check # then *from this directory* launch: -# ./track_memory.awk /path/to/log +# ./track_memory.awk /path/to/log [nosource] # it will print the amount of leaked memory (total, leak) -# and the allocation that was not freed, with the source code line. +# and the allocation that was not freed, with the source code line (if 'nosource' not given) # total and leak should indicate same amount of bytes, it is a cross check for the script. BEGIN{ show_source = 1 @@ -12,6 +12,12 @@ BEGIN{ malloc = 0 free = 0 realloc = 0 + if(ARGC == 3) { + if(ARGV[2] == "nosource") { + show_source = 0 + } + ARGC-- + } } # my_malloc(234,): allocating 1a01ff0 , 10 bytes