aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/grt/ghwdump.c111
-rw-r--r--src/grt/ghwlib.c27
-rw-r--r--src/grt/ghwlib.h3
3 files changed, 138 insertions, 3 deletions
diff --git a/src/grt/ghwdump.c b/src/grt/ghwdump.c
index 00e1f683d..3c399cf92 100644
--- a/src/grt/ghwdump.c
+++ b/src/grt/ghwdump.c
@@ -18,6 +18,7 @@
*/
#include <stdio.h>
+#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
@@ -35,10 +36,100 @@ usage (void)
" -h display hierarchy\n"
" -T display time\n"
" -s display signals (and time)\n"
+ " -f <lst> list of signals to display (default: all, example: -f 1,3,5-7,21-33)\n"
" -l display list of sections\n"
" -v verbose\n");
}
+static void add_single_signal(
+ int **signalSet,
+ int *nbSignals,
+ int signal
+) {
+ assert(NULL!=signalSet);
+ assert(NULL!=nbSignals);
+ assert(0<=nbSignals[0]);
+ assert(0<=signal);
+
+ int newSize = (1 + nbSignals[0]);
+ /*printf("adding signal %6d set of signals to display\n", signal);*/
+ signalSet[0] = (int*)realloc(signalSet[0], newSize*sizeof(int));
+ signalSet[0][nbSignals[0]] = signal;
+ nbSignals[0] = newSize;
+}
+
+static void add_signal_range(
+ int **signalSet,
+ int *nbSignals,
+ const char *s,
+ const char *e
+) {
+
+ int i;
+ int rangeSize;
+ int rangeEnd = -1;
+ int rangeStart = -1;
+ int bytesMatched = -1;
+ int expected = ((e - s) - 1);
+ int itemsMatched =sscanf(
+ s,
+ "%d-%d%n",
+ &rangeStart,
+ &rangeEnd,
+ &bytesMatched
+ );
+ if(2==itemsMatched && expected==bytesMatched) {
+ if(rangeEnd<rangeStart) {
+ int t = rangeEnd;
+ rangeEnd = rangeStart;
+ rangeStart = t;
+ }
+ } else {
+ itemsMatched = sscanf(
+ s,
+ "%d%n",
+ &rangeStart,
+ &bytesMatched
+ );
+ if(1==itemsMatched && expected==bytesMatched) {
+ if(0<=rangeStart) {
+ rangeEnd = rangeStart;
+ }
+ }
+ }
+
+ rangeSize = (rangeEnd - rangeStart);
+ if(rangeEnd<0 || rangeStart<0 || rangeSize<0) {
+ fprintf(
+ stderr,
+ "incorrect signal range specification\"%s\" found in command line, aborting\n",
+ s
+ );
+ exit(1);
+ }
+
+ for(i=rangeStart; i<=rangeEnd; ++i) {
+ add_single_signal(signalSet, nbSignals, i);
+ }
+}
+
+static void add_signals(
+ int **signalSet,
+ int *nbSignals,
+ const char *arg
+) {
+ int c = -1;
+ const char *e;
+ const char *s = e = arg;
+ while(0!=c) {
+ c = *(e++);
+ if(','==c || 0==c) {
+ add_signal_range(signalSet, nbSignals, s, e);
+ s = e;
+ }
+ }
+}
+
int
main (int argc, char **argv)
{
@@ -49,6 +140,9 @@ main (int argc, char **argv)
int flag_disp_signals;
int flag_list;
int flag_verbose;
+ int nb_signals;
+ int *signal_set;
+ int filter_done;
int eof;
enum ghw_sm_type sm;
@@ -59,12 +153,15 @@ main (int argc, char **argv)
flag_disp_signals = 0;
flag_list = 0;
flag_verbose = 0;
+ nb_signals = 0;
+ signal_set = NULL;
+ filter_done = 0;
while (1)
{
int c;
- c = getopt (argc, argv, "thTslv");
+ c = getopt (argc, argv, "thTslvf:");
if (c == -1)
break;
switch (c)
@@ -82,6 +179,9 @@ main (int argc, char **argv)
flag_disp_signals = 1;
flag_disp_time = 1;
break;
+ case 'f':
+ add_signals(&signal_set, &nb_signals, optarg);
+ break;
case 'l':
flag_list = 1;
break;
@@ -171,7 +271,14 @@ main (int argc, char **argv)
if (flag_disp_time)
printf ("Time is %lld fs\n", hp->snap_time);
if (flag_disp_signals)
- ghw_disp_values (hp);
+ {
+ if (!filter_done)
+ {
+ ghw_filter_values (hp, signal_set, nb_signals);
+ filter_done = 1;
+ }
+ ghw_disp_values (hp);
+ }
break;
case ghw_res_eof:
eof = 1;
diff --git a/src/grt/ghwlib.c b/src/grt/ghwlib.c
index 996057ff6..4ac721ee0 100644
--- a/src/grt/ghwlib.c
+++ b/src/grt/ghwlib.c
@@ -1345,6 +1345,31 @@ ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type)
}
}
+static int
+is_skip_signal (int *signals_to_keep, int nb_signals_to_keep, int signal)
+{
+ int i;
+
+ for (i = 0; i < nb_signals_to_keep; ++i)
+ {
+ if (signal==signals_to_keep[i])
+ return 0;
+ }
+ return 1;
+}
+
+void
+ghw_filter_values (struct ghw_handler *h, int *signals_to_keep, int nb_signals_to_keep)
+{
+ int i;
+
+ for (i = 0; i < h->nbr_sigs; ++i)
+ {
+ struct ghw_sig *s = &(h->sigs[i]);
+ s->skip = is_skip_signal (signals_to_keep, nb_signals_to_keep, i);
+ }
+}
+
void
ghw_disp_values (struct ghw_handler *h)
{
@@ -1353,7 +1378,7 @@ ghw_disp_values (struct ghw_handler *h)
for (i = 0; i < h->nbr_sigs; i++)
{
struct ghw_sig *s = &h->sigs[i];
- if (s->type != NULL)
+ if (s->type != NULL && !(s->skip))
{
printf ("#%d: ", i);
ghw_disp_value (s->val, s->type);
diff --git a/src/grt/ghwlib.h b/src/grt/ghwlib.h
index 7e51376af..145e6c2dd 100644
--- a/src/grt/ghwlib.h
+++ b/src/grt/ghwlib.h
@@ -256,6 +256,7 @@ struct ghw_sig
{
union ghw_type *type;
union ghw_val *val;
+ int skip;
};
enum ghw_hie_kind {
@@ -358,6 +359,8 @@ void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top);
int ghw_read_base (struct ghw_handler *h);
+void ghw_filter_values (struct ghw_handler *h, int *signals_to_keep, int nb_signals_to_keep);
+
void ghw_disp_values (struct ghw_handler *h);
int ghw_read_cycle_start (struct ghw_handler *h);