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)

This commit is contained in:
stefan schippers 2023-10-03 15:20:30 +02:00
parent d441ba6966
commit 5c7abfa048
4 changed files with 59 additions and 25 deletions

View File

@ -125,6 +125,8 @@ name="mchanged_name" model=\"nmos\" w="20u" l="3u" m="10"
symbols. </p>
<li><kbd>hide</kbd></li>
<p> A <kbd>hide=true</kbd> attribute will only display the symbol bounding box.</p>
<li><kbd>hide_texts</kbd></li>
<p> A <kbd>hide_texts=true</kbd> attribute will hide all symbol texts.</p>
<li><kbd>highlight</kbd></li>
<p>If set to <kbd>true</kbd> the symbol will be highlighted when one of the nets attached to its pins are highlighted.</p>
<li><kbd>net_name</kbd></li>

View File

@ -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 */

View File

@ -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);

View File

@ -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