Fix a variety of bugs in vpi_handle_by_name.
This function was apparently not well tested, because any use of acc_handle_object() triggered a use of vpi_handle_by_name that was buggy. The implementation was awkwardly written, to parts of it were redone.
This commit is contained in:
parent
3a77537ed8
commit
fdcb073c14
105
vvp/vpi_priv.cc
105
vvp/vpi_priv.cc
|
|
@ -23,6 +23,7 @@
|
||||||
#ifdef CHECK_WITH_VALGRIND
|
#ifdef CHECK_WITH_VALGRIND
|
||||||
# include "vvp_cleanup.h"
|
# include "vvp_cleanup.h"
|
||||||
#endif
|
#endif
|
||||||
|
# include <vector>
|
||||||
# include <cstdio>
|
# include <cstdio>
|
||||||
# include <cstdarg>
|
# include <cstdarg>
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
|
|
@ -31,6 +32,7 @@
|
||||||
# include <cmath>
|
# include <cmath>
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
vpi_mode_t vpi_mode_flag = VPI_MODE_NONE;
|
vpi_mode_t vpi_mode_flag = VPI_MODE_NONE;
|
||||||
FILE*vpi_trace = 0;
|
FILE*vpi_trace = 0;
|
||||||
|
|
||||||
|
|
@ -1262,22 +1264,30 @@ static vpiHandle find_name(const char *name, vpiHandle handle)
|
||||||
|
|
||||||
static vpiHandle find_scope(const char *name, vpiHandle handle, int depth)
|
static vpiHandle find_scope(const char *name, vpiHandle handle, int depth)
|
||||||
{
|
{
|
||||||
vpiHandle iter, hand, rtn = 0;
|
|
||||||
|
|
||||||
iter = !handle ? vpi_iterate(vpiModule, NULL) :
|
vpiHandle iter = handle==0
|
||||||
vpi_iterate(vpiInternalScope, handle);
|
? vpi_iterate(vpiModule, NULL)
|
||||||
|
: vpi_iterate(vpiInternalScope, handle);
|
||||||
|
|
||||||
|
vector<char> name_buf (strlen(name)+1);
|
||||||
|
strcpy(&name_buf[0], name);
|
||||||
|
char*nm_first = &name_buf[0];
|
||||||
|
char*nm_rest = strchr(nm_first, '.');
|
||||||
|
if (nm_rest) {
|
||||||
|
*nm_rest++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle rtn = 0;
|
||||||
|
vpiHandle hand;
|
||||||
while (iter && (hand = vpi_scan(iter))) {
|
while (iter && (hand = vpi_scan(iter))) {
|
||||||
char *nm = vpi_get_str(vpiName, hand);
|
char *nm = vpi_get_str(vpiName, hand);
|
||||||
int len = strlen(nm);
|
|
||||||
const char *cp = name + len; /* hier separator */
|
|
||||||
|
|
||||||
if (!handle && !strcmp(name, nm)) {
|
if (strcmp(nm_first,nm)==0) {
|
||||||
/* root module */
|
if (nm_rest)
|
||||||
rtn = hand;
|
rtn=find_scope(nm_rest, hand, depth+1);
|
||||||
} else if (!strncmp(name, nm, len) && *(cp) == '.')
|
else
|
||||||
/* recurse deeper */
|
rtn = hand;
|
||||||
rtn = find_scope(cp+1, hand, depth + 1);
|
}
|
||||||
|
|
||||||
/* found it yet ? */
|
/* found it yet ? */
|
||||||
if (rtn) {
|
if (rtn) {
|
||||||
|
|
@ -1286,9 +1296,6 @@ static vpiHandle find_scope(const char *name, vpiHandle handle, int depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* matched up to here */
|
|
||||||
if (!rtn) rtn = handle;
|
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1301,6 +1308,20 @@ vpiHandle vpi_handle_by_name(const char *name, vpiHandle scope)
|
||||||
name, scope);
|
name, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chop the name into path and base. For example, if the name
|
||||||
|
// is "a.b.c", then nm_path becomes "a.b" and nm_base becomes
|
||||||
|
// "c". If the name is "c" then nm_path is nil and nm_base is "c".
|
||||||
|
vector<char> name_buf (strlen(name)+1);
|
||||||
|
strcpy(&name_buf[0], name);
|
||||||
|
char*nm_path = &name_buf[0];
|
||||||
|
char*nm_base = strrchr(nm_path, '.');
|
||||||
|
if (nm_base) {
|
||||||
|
*nm_base++ = 0;
|
||||||
|
} else {
|
||||||
|
nm_base = nm_path;
|
||||||
|
nm_path = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If scope provided, look in corresponding module; otherwise
|
/* If scope provided, look in corresponding module; otherwise
|
||||||
* traverse the hierarchy specified in name to find the leaf module
|
* traverse the hierarchy specified in name to find the leaf module
|
||||||
* and try finding it there.
|
* and try finding it there.
|
||||||
|
|
@ -1315,26 +1336,60 @@ vpiHandle vpi_handle_by_name(const char *name, vpiHandle scope)
|
||||||
hand = scope;
|
hand = scope;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (vpi_trace) {
|
||||||
|
fprintf(vpi_trace, "vpi_handle_by_name: "
|
||||||
|
"Scope is not a vpiScope or vpiModule\n");
|
||||||
|
}
|
||||||
// Use vpi_chk_error() here when it is implemented.
|
// Use vpi_chk_error() here when it is implemented.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (nm_path) {
|
||||||
|
// The name has a path, and no other scope handle was
|
||||||
|
// passed in. That suggests we are looking for "a.b.c"
|
||||||
|
// in the root scope. So convert "a.b" to a scope and
|
||||||
|
// start there to look for "c".
|
||||||
|
hand = find_scope(nm_path, NULL, 0);
|
||||||
|
nm_path = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
hand = find_scope(name, NULL, 0);
|
// Special case: scope==<nil>, meaning we are looking in
|
||||||
|
// the root, and there is no path to the name, i.e. the
|
||||||
|
// string is "c" instead of "top.c". Try to find "c" as
|
||||||
|
// a scope and return that.
|
||||||
|
hand = find_scope(nm_base, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hand) {
|
if (hand == 0) {
|
||||||
/* remove hierarchical portion of name */
|
if (vpi_trace) {
|
||||||
const char *nm = vpi_get_str(vpiFullName, hand);
|
fprintf(vpi_trace, "vpi_handle_by_name: "
|
||||||
int len = strlen(nm);
|
"Scope does not exist. Giving up.\n");
|
||||||
const char *cp = name + len;
|
}
|
||||||
if (!strncmp(name, nm, len) && *cp == '.') name = cp + 1;
|
|
||||||
|
|
||||||
/* Ok, time to burn some cycles */
|
return 0;
|
||||||
vpiHandle out = find_name(name, hand);
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
// If there is a path part, then use it to find the
|
||||||
|
// scope. For example, if the full name is a.b.c, then
|
||||||
|
// the nm_path string is a.b and we search for that
|
||||||
|
// scope. If we find it, then set hand to that scope.
|
||||||
|
if (nm_path) {
|
||||||
|
vpiHandle tmp = find_scope(nm_path, hand, 0);
|
||||||
|
while (tmp == 0 && hand != 0) {
|
||||||
|
hand = vpi_handle(vpiScope, hand);
|
||||||
|
tmp = find_scope(nm_path, hand, 0);
|
||||||
|
}
|
||||||
|
hand = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we have the correct scope, look for the item.
|
||||||
|
vpiHandle out = find_name(nm_base, hand);
|
||||||
|
|
||||||
|
if (vpi_trace) {
|
||||||
|
fprintf(vpi_trace, "vpi_handle_by_name: DONE\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue