8000 Some random improvements by rfuest · Pull Request #404 · gtkwave/gtkwave · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Some random improvements #404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ of these features.
- Migrated from autotools to meson.
- Changed the fallback text editor from gedit to the default editor that is associated with the source filetype.
- Changed file dialog to use the native dialog on all platforms.
- Changed regular expressions to use PCRE instead of POSIX syntax.

### Added

Expand Down
43 changes: 42 additions & 1 deletion lib/libgtkwave/src/gw-dump-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ GwEnumFilterList *gw_dump_file_get_enum_filters(GwDumpFile *self)
}

/**
* gw_dump_file_get_enum_filters:
* gw_dump_file_get_enum_filters_for_node:
* @self: A #GwDumpFile.
* @node: The #GwNode.
*
Expand Down Expand Up @@ -807,6 +807,7 @@ static GwSymbol *symfind_2(GwDumpFile *self, const char *s)
/**
* gw_dump_file_lookup_symbol:
* @self: A #GwDumpFile.
* @name: The symbol name to look up.
*
* Looks up the symbol with the given name.
*
Expand Down Expand Up @@ -834,3 +835,43 @@ GwSymbol *gw_dump_file_lookup_symbol(GwDumpFile *self, const gchar *name)

return symfind_2(self, name2);
}

/**
* gw_dump_file_find_symbols:
* @self: A #GwDumpFile.
* @pattern: The regular expression to search.
* @error: Return location for a #GErro or %NULL.
*
* Searches for all symbols that match the given regular expression.
*
* Returns: (transfer container) (element-type GwSymbol): A #GPtrArray of #GwSymbol or %NULL in case
* of an error.
*/
GPtrArray *gw_dump_file_find_symbols(GwDumpFile *self, const gchar *pattern, GError **error)
{
g_return_val_if_fail(GW_IS_DUMP_FILE(self), NULL);
g_return_val_if_fail(pattern != NULL, NULL);
g_return_val_if_fail(error == NULL || *error == NULL, NULL);

GRegex *regex = g_regex_new(pattern, G_REGEX_CASELESS, 0, error);
if (regex == NULL) {
return NULL;
}

GPtrArray *symbols = g_ptr_array_new();

GwFacs *facs = gw_dump_file_get_facs(self);
guint facs_count = gw_facs_get_length(facs);

for (guint i = 0; i < facs_count; i++) {
GwSymbol *fac = gw_facs_get(facs, i);

if (g_regex_match(regex, fac->name, 0, NULL)) {
g_ptr_array_add(symbols, fac);
}
}

g_regex_unref(regex);

return symbols;
}
1 change: 1 addition & 0 deletions lib/libgtkwave/src/gw-dump-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ gboolean gw_dump_file_has_escaped_names(GwDumpFile *self);
gboolean gw_dump_file_get_uses_vhdl_component_format(GwDumpFile *self);

GwSymbol *gw_dump_file_lookup_symbol(GwDumpFile *self, const gchar *name);
GPtrArray *gw_dump_file_find_symbols(GwDumpFile *self, const gchar *pattern, GError **error);

G_END_DECLS
242 changes: 242 additions & 0 deletions lib/libgtkwave/src/gw-node.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
#include <stdio.h>
#include "gw-node.h"
#include "gw-bit.h"

void gw_expand_info_free(GwExpandInfo *self) {
g_return_if_fail(self != NULL);

g_free(self->narray);
g_free(self);
}

GwExpandInfo *gw_node_expand(GwNode *self)
{
g_return_val_if_fail(self != NULL, NULL);

if (!self->extvals) {
// DEBUG(fprintf(stderr, "Nothing to expand\n"));
return NULL;
}

gint msb = self->msi;
gint lsb = self->lsi;
gint width = ABS(msb - lsb) + 1;
gint delta = msb > lsb ? -1 : 1;
gint actual = msb;

GwNode **narray = g_new0(GwNode *, width);

GwExpandInfo *rc = g_new0(GwExpandInfo, 1);
rc->narray = narray;
rc->msb = msb;
rc->lsb = lsb;
rc->width = width;

char *namex = self->nname;

gint offset = strlen(namex);
gint i;
for (i = offset - 1; i >= 0; i--) {
if (namex[i] == '[')
break;
}
if (i > -1) {
offset = i;
}

gboolean is_2d = FALSE;
gint curr_row = 0;
gint curr_bit = 0;
gint row_delta = 0;
gint bit_delta = 0;
gint new_msi = 0;
gint new_lsi = 0;

if (i > 3) {
if (namex[i - 1] == ']') {
gboolean colon_seen = FALSE;
gint j = i - 2;
for (; j >= 0; j--) {
if (namex[j] == '[') {
break;
} else if (namex[j] == ':') {
colon_seen = TRUE;
}
}

if (j > -1 && colon_seen) {
gint row_hi = 0;
gint row_lo = 0;
int items =
sscanf(namex + j, "[%d:%d][%d:%d]", &row_hi, &row_lo, &new_msi, &new_lsi);
if (items == 4) {
/* printf(">> %d %d %d %d (items = %d)\n", row_hi, row_lo, new_msi, new_lsi,
* items); */

row_delta = (row_hi > row_lo) ? -1 : 1;
bit_delta = (new_msi > new_lsi) ? -1 : 1;

curr_row = row_hi;
curr_bit = new_msi;

is_2d = (((row_lo - row_hi) * row_delta) + 1) *
(((new_lsi - new_msi) * bit_delta) + 1) ==
width;
if (is_2d) {
offset = j;
}
}
}
}
}

gchar *nam = (char *)g_alloca(offset + 20 + 30);
memcpy(nam, namex, offset);

// make quick array lookup for aet display--normally this is done in addnode
if (self->harray == NULL) {
GwHistEnt *histpnt = &(self->head);
int histcount = 0;

while (histpnt) {
histcount++;
histpnt = histpnt->next;
}

self->numhist = histcount;

GwHistEnt **harray = g_new(GwHistEnt *, histcount);
self->harray = harray;

histpnt = &(self->head);
for (i = 0; i < histcount; i++) {
*harray = histpnt;
harray++;
histpnt = histpnt->next;
}
}

GwHistEnt *h = &(self->head);
while (h) {
if (h->flags & (GW_HIST_ENT_FLAG_REAL | GW_HIST_ENT_FLAG_STRING)) {
return NULL;
}
h = h->next;
}

// DEBUG(fprintf(stderr,
// "Expanding: (%d to %d) for %d bits over %d entries.\n",
// msb,
// lsb,
// width,
// n->numhist));

for (i = 0; i < width; i++) {
narray[i] = g_new0(GwNode, 1);
if (!is_2d) {
sprintf(nam + offset, "[%d]", actual);
} else {
sprintf(nam + offset, "[%d][%d]", curr_row, curr_bit);
if (curr_bit == new_lsi) {
curr_bit = new_msi;
curr_row += row_delta;
} else {
curr_bit += bit_delta;
}
}

gint len = offset + strlen(nam + offset);
narray[i]->nname = (char *)g_malloc(len + 1);
strcpy(narray[i]->nname, nam);

GwExpandReferences *exp1 = g_new0(GwExpandReferences, 1);
exp1->parent = self; /* point to parent */
exp1->parentbit = i;
exp1->actual = actual;
actual += delta;
narray[i]->expansion = exp1; /* can be safely deleted if expansion set like here */
}

for (i = 0; i < self->numhist; i++) {
h = self->harray[i];
if (h->time < 0 || h->time >= GW_TIME_MAX - 1) {
for (gint j = 0; j < width; j++) {
if (narray[j]->curr) {
GwHistEnt *htemp = g_new0(GwHistEnt, 1);
htemp->v.h_val = GW_BIT_X; /* 'x' */
htemp->time = h->time;
narray[j]->curr->next = htemp;
narray[j]->curr = htemp;
} else {
narray[j]->head.v.h_val = GW_BIT_X; /* 'x' */
narray[j]->head.time = h->time;
narray[j]->curr = &(narray[j]->head);
}

narray[j]->numhist++;
}
} else {
for (gint j = 0; j < width; j++) {
unsigned char val = h->v.h_vector[j];
switch (val) {
case '0':
val = GW_BIT_0;
break;
case '1':
val = GW_BIT_1;
break;
case 'x':
case 'X':
val = GW_BIT_X;
break;
case 'z':
case 'Z':
val = GW_BIT_Z;
break;
case 'h':
case 'H':
val = GW_BIT_H;
break;
case 'l':
case 'L':
val = GW_BIT_L;
break;
case 'u':
case 'U':
val = GW_BIT_U;
break;
case 'w':
case 'W':
val = GW_BIT_W;
break;
case '-':
val = GW_BIT_DASH;
break;
default:
break; /* leave val alone as it's been converted already.. */
}

// curr will have been established already by 'x' at time: -1
if (narray[j]->curr->v.h_val != val) {
GwHistEnt *htemp = g_new0(GwHistEnt, 1);
htemp->v.h_val = val;
htemp->time = h->time;
narray[j]->curr->next = htemp;
narray[j]->curr = htemp;
narray[j]->numhist++;
}
}
}
}

for (i = 0; i < width; i++) {
narray[i]->harray = g_new0(GwHistEnt *, narray[i]->numhist);
GwHistEnt *htemp = &(narray[i]->head);
for (gint j = 0; j < narray[i]->numhist; j++) {
narray[i]->harray[j] = htemp;
htemp = htemp->next;
}
}

return rc;
}
15 changes: 13 additions & 2 deletions lib/libgtkwave/src/gw-node.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@
#define WAVE_VARDIR_WIDTH (3)
#define WAVE_VARTYPE_WIDTH (6)

// used when expanding atomic vectors
typedef struct
{
GwNode **narray;
int msb, lsb;
int width;
} GwExpandInfo;

void gw_expand_info_free(GwExpandInfo *self);

struct _GwExpandReferences
{
GwNode *parent; /* which atomic vec we expanded from */
Expand Down Expand Up @@ -39,7 +49,6 @@ struct _GwNode
GwFac *mvlfac; /* for use with mvlsim aets */
GwVlist *mvlfac_vlist;
GwVlistWriter *mvlfac_vlist_writer;
char *value; /* for use when unrolling ae2 values */
} mv; /* anon union is a gcc extension so use mv instead. using this union avoids crazy casting
warnings */

Expand All @@ -58,4 +67,6 @@ struct _GwNode

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(pop)
#endif
#endif

GwExpandInfo *gw_node_expand(GwNode *self);
1 change: 1 addition & 0 deletions lib/libgtkwave/src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ libgtkwave_public_sources = [
'gw-loader.c',
'gw-marker.c',
'gw-named-markers.c',
'gw-node.c',
'gw-project.c',
'gw-stems.c',
'gw-string-table.c',
Expand Down
5 changes: 4 additions & 1 deletion lib/libgtkwave/test/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ libgtkwave_tests = [
'test-gw-ghw-loader',
'test-gw-marker',
'test-gw-named-markers',
'test-gw-node',
'test-gw-project',
'test-gw-stems',
'test-gw-string-table',
Expand Down Expand Up @@ -80,8 +81,10 @@ foreach test : dumpfile_tests
command: [dump_executable, '@INPUT@'],
output: test + '.dump',
capture: true,
build_always_stale: true,
env: ['G_DEBUG=fatal-warnings'],
# Without this explicit dependency the generated file isn't update when
# libgtkwave changes.
depends: libgtkwave,
)

test(
Expand Down
Loading
Loading
0