• Bug#1060407: gtkwave update for {bookworm,bullseye,buster}-security (2/

    From Adrian Bunk@21:1/5 to All on Fri Mar 29 00:10:01 2024
    [continued from previous message]

    ++ for (j = 0; j < rec->nbr_fields; j++)
    ++ {
    ++ rec->els[j].name = ghw_read_strid (h);
    ++ rec->els[j].type = ghw_read_typeid (h);
    ++ if (nbr_scalars != -1)
    ++ {
    ++ int field_nbr_scalars = get_nbr_elements (rec->els[j].type);
    ++ if (field_nbr_scalars == -1)
    ++ nbr_scalars = -1;
    ++ else
    ++ nbr_scalars += field_nbr_scalars;
    ++ }
    ++ }
    ++ rec->nbr_scalars = nbr_scalars;
    ++ if (h->flag_verbose > 1)
    ++ printf ("record type: %s (nbr_scalars=%d)\n",
    ++ rec->name, rec->nbr_scalars);
    ++ h->types[i] = (union ghw_type *)rec;
    ++ break;
    ++ err_record:
    ++ free (rec->els);
    ++ free (rec);
    ++ return -1;
    ++ }
    ++ break;
    ++ case ghdl_rtik_subtype_record:
    ++ {
    ++ struct ghw_subtype_record *sr;
    ++ const char *name;
    ++ struct ghw_type_record *base;
    ++
    ++ name = ghw_read_strid (h);
    ++ base = (struct ghw_type_record *)ghw_read_typeid (h);
    ++
    ++ sr = ghw_read_record_subtype (h, base);
    ++ sr->name = name;
    ++ h->types[i] = (union ghw_type *)sr;
    ++ if (h->flag_verbose > 1)
    ++ printf ("subtype record: %s (nbr_scalars=%d)\n",
    ++ sr->name, sr->nbr_scalars);
    ++ }
    ++ break;
    ++ default:
    ++ fprintf (stderr, "ghw_read_type: unknown type %d\n", t);
    ++ return -1;
    ++ }
    ++ }
    ++ if (fgetc (h->stream) != 0)
    ++ return -1;
    ++ return 0;
    ++}
    ++
    ++int
    ++ghw_read_wk_types (struct ghw_handler *h)
    ++{
    ++ char hdr[4];
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0)
    ++ return -1;
    ++
    ++ while (1)
    ++ {
    ++ int t;
    ++ union ghw_type *tid;
    ++
    ++ t = fgetc (h->stream);
    ++ if (t == EOF)
    ++ return -1;
    ++ else if (t == 0)
    ++ break;
    ++
    ++ tid = ghw_read_typeid (h);
    ++ if (tid->kind == ghdl_rtik_type_b2
    ++ || tid->kind == ghdl_rtik_type_e8)
    ++ {
    ++ if (h->flag_verbose > 0)
    ++ printf ("%s: wkt=%d\n", tid->en.name, t);
    ++ tid->en.wkt = t;
    ++ }
    ++ }
    ++ return 0;
    ++}
    ++
    ++void
    ++ghw_disp_typename (struct ghw_handler *h, union ghw_type *t)
    ++{
    ++ (void)h;
    ++ printf ("%s", t->common.name);
    ++}
    ++
    ++/* Read a signal composed of severals elements.
    ++ Return 0 for success. */
    ++int
    ++ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t)
    ++{
    ++ switch (t->kind)
    ++ {
    ++ case ghdl_rtik_type_b2:
    ++ case ghdl_rtik_type_e8:
    ++ case ghdl_rtik_type_e32:
    ++ case ghdl_rtik_subtype_scalar:
    ++ {
    ++ unsigned int sig_el;
    ++
    ++ if (ghw_read_uleb128 (h, &sig_el) < 0)
    ++ return -1;
    ++ *sigs = sig_el;
    ++ if (sig_el == 0 || sig_el >= h->nbr_sigs)
    ++ return -1;
    ++ if (h->sigs[sig_el].type == NULL)
    ++ h->sigs[sig_el].type = ghw_get_base_type (t);
    ++ }
    ++ return 0;
    ++ case ghdl_rtik_subtype_array:
    ++ {
    ++ int i;
    ++ int stride;
    ++ int len;
    ++
    ++ len = t->sa.nbr_scalars;
    ++ stride = get_nbr_elements (t->sa.base->el);
    ++
    ++ for (i = 0; i < len; i += stride)
    ++ if (ghw_read_signal (h, &sigs[i], t->sa.base->el) < 0)
    ++ return -1;
    ++ }
    ++ return 0;
    ++ case ghdl_rtik_type_record:
    ++ {
    ++ struct ghw_type_record *r = &t->rec;
    ++ int nbr_fields = r->nbr_fields;
    ++ int i;
    ++ int off;
    ++
    ++ off = 0;
    ++ for (i = 0; i < nbr_fields; i++)
    ++ {
    ++ if (ghw_read_signal (h, &sigs[off], r->els[i].type) < 0)
    ++ return -1;
    ++ off += get_nbr_elements (r->els[i].type);
    ++ }
    ++ }
    ++ return 0;
    ++ case ghdl_rtik_subtype_record:
    ++ {
    ++ struct ghw_subtype_record *sr = &t->sr;
    ++ int nbr_fields = sr->base->nbr_fields;
    ++ int i;
    ++ int off;
    ++
    ++ off = 0;
    ++ for (i = 0; i < nbr_fields; i++)
    ++ {
    ++ if (ghw_read_signal (h, &sigs[off], sr->els[i].type) < 0)
    ++ return -1;
    ++ off += get_nbr_elements (sr->els[i].type);
    ++ }
    ++ }
    ++ return 0;
    ++ default:
    ++ fprintf (stderr, "ghw_read_signal: type kind %d unhandled\n", t->kind); ++ abort ();
    ++ }
    ++}
    ++
    ++
    ++int
    ++ghw_read_value (struct ghw_handler *h,
    ++ union ghw_val *val, union ghw_type *type)
    ++{
    ++ switch (ghw_get_base_type (type)->kind)
    ++ {
    ++ case ghdl_rtik_type_b2:
    ++ {
    ++ int v;
    ++ v = fgetc (h->stream);
    ++ if (v == EOF)
    ++ return -1;
    ++ val->b2 = v;
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_e8:
    ++ {
    ++ int v;
    ++ v = fgetc (h->stream);
    ++ if (v == EOF)
    ++ return -1;
    ++ val->e8 = v;
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_i32:
    ++ case ghdl_rtik_type_p32:
    ++ {
    ++ int32_t v;
    ++ if (ghw_read_sleb128 (h, &v) < 0)
    ++ return -1;
    ++ val->i32 = v;
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_f64:
    ++ {
    ++ double v;
    ++ if (ghw_read_f64 (h, &v) < 0)
    ++ return -1;
    ++ val->f64 = v;
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_p64:
    ++ {
    ++ int64_t v;
    ++ if (ghw_read_lsleb128 (h, &v) < 0)
    ++ return -1;
    ++ val->i64 = v;
    ++ }
    ++ break;
    ++ default:
    ++ fprintf (stderr, "read_value: cannot handle format %d\n", type->kind); ++ abort ();
    ++ }
    ++ return 0;
    ++}
    ++
    ++int
    ++ghw_read_hie (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[16];
    ++ int nbr_scopes;
    ++ int nbr_sigs;
    ++ unsigned i;
    ++ struct ghw_hie *blk;
    ++ struct ghw_hie **last;
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0)
    ++ return -1;
    ++ nbr_scopes = ghw_get_i32 (h, &hdr[4]);
    ++ /* Number of declared signals (which may be composite). */
    ++ nbr_sigs = ghw_get_i32 (h, &hdr[8]);
    ++ /* Number of basic signals. */
    ++ h->nbr_sigs = ghw_get_i32 (h, &hdr[12]);
    ++
    ++ if (h->flag_verbose)
    ++ printf ("%u scopes, %u signals, %u signal elements\n",
    ++ nbr_scopes, nbr_sigs, h->nbr_sigs);
    ++
    ++ blk = (struct ghw_hie *)malloc (sizeof (struct ghw_hie));
    ++ blk->kind = ghw_hie_design;
    ++ blk->name = NULL;
    ++ blk->parent = NULL;
    ++ blk->brother = NULL;
    ++ blk->u.blk.child = NULL;
    ++
    ++ last = &blk->u.blk.child;
    ++ h->hie = blk;
    ++
    ++ h->nbr_sigs++;
    ++ h->skip_sigs = NULL;
    ++ h->flag_full_names = 0;
    ++ h->sigs = (struct ghw_sig *) malloc (h->nbr_sigs * sizeof (struct ghw_sig));
    ++ memset (h->sigs, 0, h->nbr_sigs * sizeof (struct ghw_sig));
    ++
    ++ while (1)
    ++ {
    ++ int t;
    ++ struct ghw_hie *el;
    ++ unsigned int str;
    ++
    ++ t = fgetc (h->stream);
    ++ if (t == EOF)
    ++ return -1;
    ++ if (t == 0)
    ++ break;
    ++
    ++ if (t == ghw_hie_eos)
    ++ {
    ++ blk = blk->parent;
    ++ if (blk->u.blk.child == NULL)
    ++ last = &blk->u.blk.child;
    ++ else
    ++ {
    ++ struct ghw_hie *l = blk->u.blk.child;
    ++ while (l->brother != NULL)
    ++ l = l->brother;
    ++ last = &l->brother;
    ++ }
    ++
    ++ continue;
    ++ }
    ++
    ++ el = (struct ghw_hie *) malloc (sizeof (struct ghw_hie));
    ++ el->kind = t;
    ++ el->parent = blk;
    ++ el->brother = NULL;
    ++
    ++ /* Link. */
    ++ *last = el;
    ++ last = &el->brother;
    ++
    ++ /* Read name. */
    ++ if (ghw_read_uleb128 (h, &str) != 0)
    ++ return -1;
    ++ el->name = h->str_table[str];
    ++
    ++ switch (t)
    ++ {
    ++ case ghw_hie_eoh:
    ++ case ghw_hie_design:
    ++ case ghw_hie_eos:
    ++ /* Should not be here. */
    ++ abort ();
    ++ case ghw_hie_process:
    ++ break;
    ++ case ghw_hie_block:
    ++ case ghw_hie_generate_if:
    ++ case ghw_hie_generate_for:
    ++ case ghw_hie_instance:
    ++ case ghw_hie_generic:
    ++ case ghw_hie_package:
    ++ /* Create a block. */
    ++ el->u.blk.child = NULL;
    ++
    ++ if (t == ghw_hie_generate_for)
    ++ {
    ++ el->u.blk.iter_type = ghw_read_typeid (h);
    ++ el->u.blk.iter_value = malloc (sizeof (union ghw_val));
    ++ if (ghw_read_value (h, el->u.blk.iter_value,
    ++ el->u.blk.iter_type) < 0)
    ++ return -1;
    ++ }
    ++ blk = el;
    ++ last = &el->u.blk.child;
    ++ break;
    ++ case ghw_hie_signal:
    ++ case ghw_hie_port_in:
    ++ case ghw_hie_port_out:
    ++ case ghw_hie_port_inout:
    ++ case ghw_hie_port_buffer:
    ++ case ghw_hie_port_linkage:
    ++ /* For a signal, read type. */
    ++ {
    ++ int nbr_el;
    ++ unsigned int *sigs;
    ++
    ++ el->u.sig.type = ghw_read_typeid (h);
    ++ nbr_el = get_nbr_elements (el->u.sig.type);
    ++ if (nbr_el < 0)
    ++ return -1;
    ++ sigs = (unsigned int *) malloc
    ++ ((nbr_el + 1) * sizeof (unsigned int));
    ++ el->u.sig.sigs = sigs;
    ++ /* Last element is NULL. */
    ++ sigs[nbr_el] = 0;
    ++
    ++ if (h->flag_verbose > 1)
    ++ printf ("signal %s: %d el [", el->name, nbr_el);
    ++ if (ghw_read_signal (h, sigs, el->u.sig.type) < 0)
    ++ return -1;
    ++ if (h->flag_verbose > 1)
    ++ {
    ++ int j;
    ++ for (j = 0; j < nbr_el; j++)
    ++ printf (" #%u", sigs[j]);
    ++ printf ("]\n");
    ++ }
    ++ }
    ++ break;
    ++ default:
    ++ fprintf (stderr, "ghw_read_hie: unhandled kind %d\n", t);
    ++ abort ();
    ++ }
    ++ }
    ++
    ++ /* Allocate values. */
    ++ for (i = 0; i < h->nbr_sigs; i++)
    ++ if (h->sigs[i].type != NULL)
    ++ h->sigs[i].val = (union ghw_val *) malloc (sizeof (union ghw_val));
    ++ return 0;
    ++}
    ++
    ++const char *
    ++ghw_get_hie_name (struct ghw_hie *h)
    ++{
    ++ switch (h->kind)
    ++ {
    ++ case ghw_hie_eoh:
    ++ return "eoh";
    ++ case ghw_hie_design:
    ++ return "design";
    ++ case ghw_hie_block:
    ++ return "block";
    ++ case ghw_hie_generate_if:
    ++ return "generate-if";
    ++ case ghw_hie_generate_for:
    ++ return "generate-for";
    ++ case ghw_hie_instance:
    ++ return "instance";
    ++ case ghw_hie_package:
    ++ return "package";
    ++ case ghw_hie_process:
    ++ return "process";
    ++ case ghw_hie_generic:
    ++ return "generic";
    ++ case ghw_hie_eos:
    ++ return "eos";
    ++ case ghw_hie_signal:
    ++ return "signal";
    ++ case ghw_hie_port_in:
    ++ return "port-in";
    ++ case ghw_hie_port_out:
    ++ return "port-out";
    ++ case ghw_hie_port_inout:
    ++ return "port-inout";
    ++ case ghw_hie_port_buffer:
    ++ return "port-buffer";
    ++ case ghw_hie_port_linkage:
    ++ return "port-linkage";
    ++ default:
    ++ return "??";
    ++ }
    ++}
    ++
    ++void
    ++ghw_disp_value (union ghw_val *val, union ghw_type *type);
    ++
    ++static void
    ++print_name (struct ghw_hie *hie, int full_names)
    ++{
    ++ int i;
    ++ int depth;
    ++ struct ghw_hie *p;
    ++ struct ghw_hie **buf;
    ++ struct ghw_hie **end;
    ++
    ++ /* HIE must be valid. */
    ++ assert (hie->name != NULL);
    ++
    ++ if (0 == full_names)
    ++ {
    ++ printf (" %s: ", hie->name);
    ++ return;
    ++ }
    ++
    ++ p = hie;
    ++ depth = 0;
    ++ while (p && p->name)
    ++ {
    ++ p = p->parent;
    ++ ++depth;
    ++ }
    ++ buf = (struct ghw_hie **) malloc (depth * sizeof (struct ghw_hie *));
    ++
    ++ p = hie;
    ++ end = depth + buf;
    ++ while (p && p->name)
    ++ {
    ++ *(--end) = p;
    ++ p = p->parent;
    ++ }
    ++
    ++ putchar (' ');
    ++ putchar ('/');
    ++ for (i = 0; i < depth; ++i)
    ++ {
    ++ printf ("%s%s", i ? "/" : "", buf[i]->name);
    ++ if (ghw_hie_generate_for == buf[i]->kind)
    ++ {
    ++ putchar ('(');
    ++ ghw_disp_value (buf[i]->u.blk.iter_value, buf[i]->u.blk.iter_type); ++ putchar (')');
    ++ }
    ++ }
    ++ putchar (':');
    ++ putchar (' ');
    ++ free (buf);
    ++}
    ++
    ++void
    ++ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top)
    ++{
    ++ int i;
    ++ int indent;
    ++ struct ghw_hie *hie;
    ++ struct ghw_hie *n;
    ++
    ++ hie = top;
    ++ indent = 0;
    ++
    ++ while (1)
    ++ {
    ++ if (0 == h->flag_full_names)
    ++ for (i = 0; i < indent; i++)
    ++ fputc (' ', stdout);
    ++ printf ("%s", ghw_get_hie_name (hie));
    ++
    ++ switch (hie->kind)
    ++ {
    ++ case ghw_hie_design:
    ++ case ghw_hie_block:
    ++ case ghw_hie_generate_if:
    ++ case ghw_hie_generate_for:
    ++ case ghw_hie_instance:
    ++ case ghw_hie_process:
    ++ case ghw_hie_package:
    ++ if (hie->name)
    ++ print_name (hie, h->flag_full_names);
    ++ if (hie->kind == ghw_hie_generate_for)
    ++ {
    ++ printf ("(");
    ++ ghw_disp_value (hie->u.blk.iter_value, hie->u.blk.iter_type);
    ++ printf (")");
    ++ }
    ++ n = hie->u.blk.child;
    ++ if (n == NULL)
    ++ n = hie->brother;
    ++ else
    ++ indent++;
    ++ break;
    ++ case ghw_hie_generic:
    ++ case ghw_hie_eos:
    ++ abort ();
    ++ case ghw_hie_signal:
    ++ case ghw_hie_port_in:
    ++ case ghw_hie_port_out:
    ++ case ghw_hie_port_inout:
    ++ case ghw_hie_port_buffer:
    ++ case ghw_hie_port_linkage:
    ++ {
    ++ unsigned int *sigs = hie->u.sig.sigs;
    ++ unsigned int k, num;
    ++
    ++ print_name (hie, h->flag_full_names);
    ++ ghw_disp_subtype_indication (h, hie->u.sig.type);
    ++ printf (":");
    ++ k = 0;
    ++ assert (sigs[0] != GHW_NO_SIG);
    ++ while (1)
    ++ {
    ++ /* First signal of the range. */
    ++ printf (" #%u", sigs[k]);
    ++ for (num = 1; sigs[k + num] != GHW_NO_SIG; num++)
    ++ if (sigs[k + num] != sigs[k + num - 1] + 1)
    ++ break;
    ++ if (num > 1)
    ++ printf ("-#%u", sigs[k + num - 1]);
    ++ k += num;
    ++ /* End of signals ? */
    ++ if (sigs[k] == GHW_NO_SIG)
    ++ break;
    ++ }
    ++ n = hie->brother;
    ++ }
    ++ break;
    ++ default:
    ++ abort ();
    ++ }
    ++ printf ("\n");
    ++
    ++ while (n == NULL)
    ++ {
    ++ if (hie->parent == NULL)
    ++ return;
    ++ hie = hie->parent;
    ++ indent--;
    ++ n = hie->brother;
    ++ }
    ++ hie = n;
    ++ }
    ++}
    ++
    ++int
    ++ghw_read_eoh (struct ghw_handler *h)
    ++{
    ++ (void)h;
    ++ return 0;
    ++}
    ++
    ++int
    ++ghw_read_base (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[4];
    ++ int res;
    ++
    ++ while (1)
    ++ {
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++ if (memcmp (hdr, "STR", 4) == 0)
    ++ res = ghw_read_str (h);
    ++ else if (memcmp (hdr, "HIE", 4) == 0)
    ++ res = ghw_read_hie (h);
    ++ else if (memcmp (hdr, "TYP", 4) == 0)
    ++ res = ghw_read_type (h);
    ++ else if (memcmp (hdr, "WKT", 4) == 0)
    ++ res = ghw_read_wk_types (h);
    ++ else if (memcmp (hdr, "EOH", 4) == 0)
    ++ return 0;
    ++ else
    ++ {
    ++ fprintf (stderr, "ghw_read_base: unknown GHW section %c%c%c%c\n",
    ++ hdr[0], hdr[1], hdr[2], hdr[3]);
    ++ return -1;
    ++ }
    ++ if (res != 0)
    ++ {
    ++ fprintf (stderr, "ghw_read_base: error in section %s\n", hdr);
    ++ return res;
    ++ }
    ++ }
    ++}
    ++
    ++int
    ++ghw_read_signal_value (struct ghw_handler *h, struct ghw_sig *s)
    ++{
    ++ return ghw_read_value (h, s->val, s->type);
    ++}
    ++
    ++int
    ++ghw_read_snapshot (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[12];
    ++ unsigned i;
    ++ struct ghw_sig *s;
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0)
    ++ return -1;
    ++ h->snap_time = ghw_get_i64 (h, &hdr[4]);
    ++ if (h->flag_verbose > 1)
    ++ printf ("Time is " GHWPRI64 " fs\n", h->snap_time);
    ++
    ++ for (i = 0; i < h->nbr_sigs; i++)
    ++ {
    ++ s = &h->sigs[i];
    ++ if (s->type != NULL)
    ++ {
    ++ if (h->flag_verbose > 1)
    ++ printf ("read type %d for sig %u\n", s->type->kind, i);
    ++ if (ghw_read_signal_value (h, s) < 0)
    ++ return -1;
    ++ }
    ++ }
    ++ if (fread (hdr, 4, 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ if (memcmp (hdr, "ESN", 4))
    ++ return -1;
    ++
    ++ return 0;
    ++}
    ++
    ++void ghw_disp_values (struct ghw_handler *h);
    ++
    ++int
    ++ghw_read_cycle_start (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[8];
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ h->snap_time = ghw_get_i64 (h, hdr);
    ++ return 0;
    ++}
    ++
    ++int
    ++ghw_read_cycle_cont (struct ghw_handler *h, int *list)
    ++{
    ++ int i;
    ++ int *list_p;
    ++
    ++ i = 0;
    ++ list_p = list;
    ++ while (1)
    ++ {
    ++ uint32_t d;
    ++
    ++ /* Read delta to next signal. */
    ++ if (ghw_read_uleb128 (h, &d) < 0)
    ++ return -1;
    ++ if (d == 0)
    ++ {
    ++ /* Last signal reached. */
    ++ break;
    ++ }
    ++
    ++ /* Find next signal. */
    ++ while (d > 0)
    ++ {
    ++ i++;
    ++ if (h->sigs[i].type != NULL)
    ++ d--;
    ++ }
    ++
    ++ if (ghw_read_signal_value (h, &h->sigs[i]) < 0)
    ++ return -1;
    ++ if (list_p)
    ++ *list_p++ = i;
    ++ }
    ++
    ++ if (list_p)
    ++ *list_p = 0;
    ++ return 0;
    ++}
    ++
    ++int
    ++ghw_read_cycle_next (struct ghw_handler *h)
    ++{
    ++ int64_t d_time;
    ++
    ++ if (ghw_read_lsleb128 (h, &d_time) < 0)
    ++ return -1;
    ++ if (d_time == -1)
    ++ return 0;
    ++ h->snap_time += d_time;
    ++ return 1;
    ++}
    ++
    ++
    ++int
    ++ghw_read_cycle_end (struct ghw_handler *h)
    ++{
    ++ char hdr[4];
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++ if (memcmp (hdr, "ECY", 4))
    ++ return -1;
    ++
    ++ return 0;
    ++}
    ++
    ++static const char *
    ++ghw_get_lit (union ghw_type *type, unsigned e)
    ++{
    ++ if (e >= type->en.nbr)
    ++ return "??";
    ++ else
    ++ return type->en.lits[e];
    ++}
    ++
    ++static void
    ++ghw_disp_lit (union ghw_type *type, unsigned e)
    ++{
    ++ printf ("%s (%u)", ghw_get_lit (type, e), e);
    ++}
    ++
    ++void
    ++ghw_disp_value (union ghw_val *val, union ghw_type *type)
    ++{
    ++ switch (ghw_get_base_type (type)->kind)
    ++ {
    ++ case ghdl_rtik_type_b2:
    ++ ghw_disp_lit (type, val->b2);
    ++ break;
    ++ case ghdl_rtik_type_e8:
    ++ ghw_disp_lit (type, val->e8);
    ++ break;
    ++ case ghdl_rtik_type_i32:
    ++ printf (GHWPRI32, val->i32);
    ++ break;
    ++ case ghdl_rtik_type_p64:
    ++ printf (GHWPRI64, val->i64);
    ++ break;
    ++ case ghdl_rtik_type_f64:
    ++ printf ("%g", val->f64);
    ++ break;
    ++ default:
    ++ fprintf (stderr, "ghw_disp_value: cannot handle type %d\n",
    ++ type->kind);
    ++ abort ();
    ++ }
    ++}
    ++
    ++/* Put the ASCII representation of VAL into BUF, whose size if LEN.
    ++ A NUL is always written to BUF.
    ++*/
    ++void
    ++ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type) ++{
    ++ union ghw_type *base = ghw_get_base_type (type);
    ++
    ++ switch (base->kind)
    ++ {
    ++ case ghdl_rtik_type_b2:
    ++ if (val->b2 <= 1)
    ++ {
    ++ strncpy (buf, base->en.lits[val->b2], len - 1);
    ++ buf[len - 1] = 0;
    ++ }
    ++ else
    ++ {
    ++ snprintf (buf, len, "?%d", val->b2);
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_e8:
    ++ if (val->b2 <= base->en.nbr)
    ++ {
    ++ strncpy (buf, base->en.lits[val->e8], len - 1);
    ++ buf[len - 1] = 0;
    ++ }
    ++ else
    ++ {
    ++ snprintf (buf, len, "?%d", val->e8);
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_i32:
    ++ snprintf (buf, len, GHWPRI32, val->i32);
    ++ break;
    ++ case ghdl_rtik_type_p64:
    ++ snprintf (buf, len, GHWPRI64, val->i64);
    ++ break;
    ++ case ghdl_rtik_type_f64:
    ++ snprintf (buf, len, "%g", val->f64);
    ++ break;
    ++ default:
    ++ snprintf (buf, len, "?bad type %d?", type->kind);
    ++ }
    ++}
    ++
    ++static char
    ++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_signals (struct ghw_handler *h,
    ++ int *signals_to_keep, int nb_signals_to_keep)
    ++{
    ++ unsigned i;
    ++
    ++ if (0 < nb_signals_to_keep && 0 != signals_to_keep)
    ++ {
    ++ if (0 == h->skip_sigs)
    ++ {
    ++ h->skip_sigs = (char *) malloc (sizeof (char) * h->nbr_sigs);
    ++ }
    ++ for (i = 0; i < h->nbr_sigs; ++i)
    ++ {
    ++ h->skip_sigs[i] = is_skip_signal (signals_to_keep,
    ++ nb_signals_to_keep, i);
    ++ }
    ++ }
    ++ else
    ++ {
    ++ if (0 != h->skip_sigs)
    ++ {
    ++ free (h->skip_sigs);
    ++ h->skip_sigs = 0;
    ++ }
    ++ }
    ++}
    ++
    ++void
    ++ghw_disp_values (struct ghw_handler *h)
    ++{
    ++ unsigned i;
    ++ for (i = 0; i < h->nbr_sigs; i++)
    ++ {
    ++ struct ghw_sig *s = &h->sigs[i];
    ++ int skip = (0 != h->skip_sigs && (0 != h->skip_sigs[i]));
    ++ if (s->type != NULL && !skip)
    ++ {
    ++ printf ("#%u: ", i);
    ++ ghw_disp_value (s->val, s->type);
    ++ printf ("\n");
    ++ }
    ++ }
    ++}
    ++int
    ++ghw_read_directory (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[8];
    ++ int nbr_entries;
    ++ int i;
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ nbr_entries = ghw_get_i32 (h, &hdr[4]);
    ++
    ++ if (h->flag_verbose)
    ++ printf ("Directory (%d entries):\n", nbr_entries);
    ++
    ++ for (i = 0; i < nbr_entries; i++)
    ++ {
    ++ unsigned char ent[8];
    ++ int pos;
    ++
    ++ if (fread (ent, sizeof (ent), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ pos = ghw_get_i32 (h, &ent[4]);
    ++ if (h->flag_verbose)
    ++ printf (" %s at %d\n", ent, pos);
    ++ }
    ++
    ++ if (fread (hdr, 4, 1, h->stream) != 1)
    ++ return -1;
    ++ if (memcmp (hdr, "EOD", 4))
    ++ return -1;
    ++ return 0;
    ++}
    ++
    ++int
    ++ghw_read_tailer (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[8];
    ++ int pos;
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ return -1;
    ++
    ++ pos = ghw_get_i32 (h, &hdr[4]);
    ++
    ++ if (h->flag_verbose)
    ++ printf ("Tailer: directory at %d\n", pos);
    ++ return 0;
    ++}
    ++
    ++enum ghw_res
    ++ghw_read_sm_hdr (struct ghw_handler *h, int *list)
    ++{
    ++ unsigned char hdr[4];
    ++ int res;
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ {
    ++ if (feof (h->stream))
    ++ return ghw_res_eof;
    ++ else
    ++ return ghw_res_error;
    ++ }
    ++ if (memcmp (hdr, "SNP", 4) == 0)
    ++ {
    ++ res = ghw_read_snapshot (h);
    ++ if (res < 0)
    ++ return res;
    ++ return ghw_res_snapshot;
    ++ }
    ++ else if (memcmp (hdr, "CYC", 4) == 0)
    ++ {
    ++ res = ghw_read_cycle_start (h);
    ++ if (res < 0)
    ++ return res;
    ++ res = ghw_read_cycle_cont (h, list);
    ++ if (res < 0)
    ++ return res;
    ++
    ++ return ghw_res_cycle;
    ++ }
    ++ else if (memcmp (hdr, "DIR", 4) == 0)
    ++ {
    ++ res = ghw_read_directory (h);
    ++ }
    ++ else if (memcmp (hdr, "TAI", 4) == 0)
    ++ {
    ++ res = ghw_read_tailer (h);
    ++ }
    ++ else
    ++ {
    ++ fprintf (stderr, "unknown GHW section %c%c%c%c\n",
    ++ hdr[0], hdr[1], hdr[2], hdr[3]);
    ++ return -1;
    ++ }
    ++ if (res != 0)
    ++ return res;
    ++ return ghw_res_other;
    ++}
    ++
    ++int
    ++ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm)
    ++{
    ++ int res;
    ++
    ++ while (1)
    ++ {
    ++ /* printf ("sm: state = %d\n", *sm); */
    ++ switch (*sm)
    ++ {
    ++ case ghw_sm_init:
    ++ case ghw_sm_sect:
    ++ res = ghw_read_sm_hdr (h, NULL);
    ++ switch (res)
    ++ {
    ++ case ghw_res_other:
    ++ break;
    ++ case ghw_res_snapshot:
    ++ *sm = ghw_sm_sect;
    ++ return res;
    ++ case ghw_res_cycle:
    ++ *sm = ghw_sm_cycle;
    ++ return res;
    ++ default:
    ++ return res;
    ++ }
    ++ break;
    ++ case ghw_sm_cycle:
    ++ if (0)
    ++ printf ("Time is " GHWPRI64 " fs\n", h->snap_time);
    ++ if (0)
    ++ ghw_disp_values (h);
    ++
    ++ res = ghw_read_cycle_next (h);
    ++ if (res < 0)
    ++ return res;
    ++ if (res == 1)
    ++ {
    ++ res = ghw_read_cycle_cont (h, NULL);
    ++ if (res < 0)
    ++ return res;
    ++ return ghw_res_cycle;
    ++ }
    ++ res = ghw_read_cycle_end (h);
    ++ if (res < 0)
    ++ return res;
    ++ *sm = ghw_sm_sect;
    ++ break;
    ++ }
    ++ }
    ++}
    ++
    ++int
    ++ghw_read_cycle (struct ghw_handler *h)
    ++{
    ++ int res;
    ++
    ++ res = ghw_read_cycle_start (h);
    ++ if (res < 0)
    ++ return res;
    ++ while (1)
    ++ {
    ++ res = ghw_read_cycle_cont (h, NULL);
    ++ if (res < 0)
    ++ return res;
    ++
    ++ if (0)
    ++ printf ("Time is " GHWPRI64 " fs\n", h->snap_time);
    ++ if (0)
    ++ ghw_disp_values (h);
    ++
    ++
    ++ res = ghw_read_cycle_next (h);
    ++ if (res < 0)
    ++ return res;
    ++ if (res == 0)
    ++ break;
    ++ }
    ++ res = ghw_read_cycle_end (h);
    ++ return res;
    ++}
    ++
    ++int
    ++ghw_read_dump (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[4];
    ++ int res;
    ++
    ++ while (1)
    ++ {
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ {
    ++ if (feof (h->stream))
    ++ return 0;
    ++ else
    ++ return -1;
    ++ }
    ++ if (memcmp (hdr, "SNP", 4) == 0)
    ++ {
    ++ res = ghw_read_snapshot (h);
    ++ if (0 && res >= 0)
    ++ ghw_disp_values (h);
    ++ }
    ++ else if (memcmp (hdr, "CYC", 4) == 0)
    ++ {
    ++ res = ghw_read_cycle (h);
    ++ }
    ++ else if (memcmp (hdr, "DIR", 4) == 0)
    ++ {
    ++ res = ghw_read_directory (h);
    ++ }
    ++ else if (memcmp (hdr, "TAI", 4) == 0)
    ++ {
    ++ res = ghw_read_tailer (h);
    ++ }
    ++ else
    ++ {
    ++ fprintf (stderr, "unknown GHW section %c%c%c%c\n",
    ++ hdr[0], hdr[1], hdr[2], hdr[3]);
    ++ return -1;
    ++ }
    ++ if (res != 0)
    ++ return res;
    ++ }
    ++}
    ++
    ++struct ghw_section ghw_sections[] = {
    ++ { "\0\0\0", NULL },
    ++ { "STR", ghw_read_str },
    ++ { "HIE", ghw_read_hie },
    ++ { "TYP", ghw_read_type },
    ++ { "WKT", ghw_read_wk_types },
    ++ { "EOH", ghw_read_eoh },
    ++ { "SNP", ghw_read_snapshot },
    ++ { "CYC", ghw_read_cycle },
    ++ { "DIR", ghw_read_directory },
    ++ { "TAI", ghw_read_tailer }
    ++};
    ++
    ++int
    ++ghw_read_section (struct ghw_handler *h)
    ++{
    ++ unsigned char hdr[4];
    ++ unsigned i;
    ++
    ++ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
    ++ {
    ++ if (feof (h->stream))
    ++ return -2;
    ++ else
    ++ return -1;
    ++ }
    ++
    ++ for (i = 1; i < sizeof (ghw_sections) / sizeof (*ghw_sections); i++)
    ++ if (memcmp (hdr, ghw_sections[i].name, 4) == 0)
    ++ return i;
    ++
    ++ fprintf (stderr, "ghw_read_section: unknown GHW section %c%c%c%c\n",
    ++ hdr[0], hdr[1], hdr[2], hdr[3]);
    ++ return 0;
    ++}
    ++
    ++void
    ++ghw_close (struct ghw_handler *h)
    ++{
    ++ if (h->stream)
    ++ {
    ++ if (h->stream_ispipe)
    ++ pclose (h->stream);
    ++ else
    ++ fclose (h->stream);
    ++
    ++ h->stream = NULL;
    ++ }
    ++}
    ++
    ++const char *
    ++ghw_get_dir (int is_downto)
    ++{
    ++ return is_downto ? "downto" : "to";
    ++}
    ++
    ++void
    ++ghw_disp_range (union ghw_type *type, union ghw_range *rng)
    ++{
    ++ switch (rng->kind)
    ++ {
    ++ case ghdl_rtik_type_b2:
    ++ printf ("%s %s %s", ghw_get_lit (type, rng->b2.left),
    ++ ghw_get_dir (rng->b2.dir), ghw_get_lit (type, rng->b2.right));
    ++ break;
    ++ case ghdl_rtik_type_e8:
    ++ printf ("%s %s %s", ghw_get_lit (type, rng->e8.left),
    ++ ghw_get_dir (rng->e8.dir), ghw_get_lit (type, rng->e8.right));
    ++ break;
    ++ case ghdl_rtik_type_i32:
    ++ case ghdl_rtik_type_p32:
    ++ printf (GHWPRI32 " %s " GHWPRI32,
    ++ rng->i32.left, ghw_get_dir (rng->i32.dir), rng->i32.right);
    ++ break;
    ++ case ghdl_rtik_type_i64:
    ++ case ghdl_rtik_type_p64:
    ++ printf (GHWPRI64 " %s " GHWPRI64,
    ++ rng->i64.left, ghw_get_dir (rng->i64.dir), rng->i64.right);
    ++ break;
    ++ case ghdl_rtik_type_f64:
    ++ printf ("%g %s %g",
    ++ rng->f64.left, ghw_get_dir (rng->f64.dir), rng->f64.right);
    ++ break;
    ++ default:
    ++ printf ("?(%d)", rng->kind);
    ++ }
    ++}
    ++
    ++static void
    ++ghw_disp_array_subtype_bounds (struct ghw_subtype_array *a)
    ++{
    ++ unsigned i;
    ++
    ++ printf (" (");
    ++ for (i = 0; i < a->base->nbr_dim; i++)
    ++ {
    ++ if (i != 0)
    ++ printf (", ");
    ++ ghw_disp_range (a->base->dims[i], a->rngs[i]);
    ++ }
    ++ printf (")");
    ++}
    ++
    ++static void
    ++ghw_disp_record_subtype_bounds (struct ghw_subtype_record *sr)
    ++{
    ++ struct ghw_type_record *base = sr->base;
    ++ int is_first = 1;
    ++ unsigned i;
    ++
    ++ for (i = 0; i < base->nbr_fields; i++)
    ++ {
    ++ if (sr->els[i].type != base->els[i].type)
    ++ {
    ++ if (is_first)
    ++ {
    ++ printf ("(");
    ++ is_first = 0;
    ++ }
    ++ else
    ++ printf (", ");
    ++ printf ("%s", base->els[i].name);
    ++ switch (sr->els[i].type->kind)
    ++ {
    ++ case ghdl_rtik_subtype_array:
    ++ ghw_disp_array_subtype_bounds (&sr->els[i].type->sa);
    ++ break;
    ++ case ghdl_rtik_subtype_record:
    ++ ghw_disp_record_subtype_bounds (&sr->els[i].type->sr);
    ++ break;
    ++ default:
    ++ printf ("??? (%d)", sr->els[i].type->kind);
    ++ }
    ++ }
    ++ }
    ++ if (!is_first)
    ++ printf (")");
    ++}
    ++
    ++static void
    ++ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t)
    ++{
    ++ switch (t->kind)
    ++ {
    ++ case ghdl_rtik_subtype_scalar:
    ++ {
    ++ struct ghw_subtype_scalar *s = &t->ss;
    ++ ghw_disp_typename (h, s->base);
    ++ printf (" range ");
    ++ ghw_disp_range (s->base, s->rng);
    ++ }
    ++ break;
    ++ case ghdl_rtik_subtype_array:
    ++ {
    ++ struct ghw_subtype_array *a = &t->sa;
    ++
    ++ ghw_disp_typename (h, (union ghw_type *)a->base);
    ++ ghw_disp_array_subtype_bounds (a);
    ++ }
    ++ break;
    ++ case ghdl_rtik_subtype_record:
    ++ {
    ++ struct ghw_subtype_record *sr = &t->sr;
    ++
    ++ ghw_disp_typename (h, (union ghw_type *)sr->base);
    ++ ghw_disp_record_subtype_bounds (sr);
    ++ }
    ++ break;
    ++ default:
    ++ printf ("ghw_disp_subtype_definition: unhandled type kind %d\n",
    ++ t->kind);
    ++ }
    ++}
    ++
    ++static int
    ++ghw_is_anonymous_type (struct ghw_handler *h, union ghw_type *t)
    ++{
    ++ return t->common.name == h->str_table[0];
    ++}
    ++
    ++void
    ++ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t)
    ++{
    ++ if (ghw_is_anonymous_type (h, t))
    ++ {
    ++ /* Anonymous subtype. */
    ++ ghw_disp_subtype_definition (h, t);
    ++ }
    ++ else
    ++ ghw_disp_typename (h, t);
    ++}
    ++
    ++void
    ++ghw_disp_type (struct ghw_handler *h, union ghw_type *t)
    ++{
    ++ switch (t->kind)
    ++ {
    ++ case ghdl_rtik_type_b2:
    ++ case ghdl_rtik_type_e8:
    ++ {
    ++ struct ghw_type_enum *e = &t->en;
    ++ unsigned i;
    ++
    ++ printf ("type %s is (", e->name);
    ++ for (i = 0; i < e->nbr; i++)
    ++ {
    ++ if (i != 0)
    ++ printf (", ");
    ++ printf ("%s", e->lits[i]);
    ++ }
    ++ printf (");");
    ++ if (e->wkt != ghw_wkt_unknown)
    ++ printf (" -- WKT:%d", e->wkt);
    ++ printf ("\n");
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_i32:
    ++ case ghdl_rtik_type_f64:
    ++ {
    ++ struct ghw_type_scalar *s = &t->sc;
    ++ printf ("type %s is range <>;\n", s->name);
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_p32:
    ++ case ghdl_rtik_type_p64:
    ++ {
    ++ unsigned i;
    ++
    ++ struct ghw_type_physical *p = &t->ph;
    ++ printf ("type %s is range <> units\n", p->name);
    ++ for (i = 0; i < p->nbr_units; i++)
    ++ {
    ++ struct ghw_unit *u = &p->units[i];
    ++ printf (" %s = " GHWPRI64 " %s;\n",
    ++ u->name, u->val, p->units[0].name);
    ++ }
    ++ printf ("end units\n");
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_array:
    ++ {
    ++ struct ghw_type_array *a = &t->ar;
    ++ unsigned i;
    ++
    ++ printf ("type %s is array (", a->name);
    ++ for (i = 0; i < a->nbr_dim; i++)
    ++ {
    ++ if (i != 0)
    ++ printf (", ");
    ++ ghw_disp_typename (h, a->dims[i]);
    ++ printf (" range <>");
    ++ }
    ++ printf (") of ");
    ++ ghw_disp_subtype_indication (h, a->el);
    ++ printf (";\n");
    ++ }
    ++ break;
    ++ case ghdl_rtik_type_record:
    ++ {
    ++ struct ghw_type_record *r = &t->rec;
    ++ unsigned i;
    ++
    ++ printf ("type %s is record\n", r->name);
    ++ for (i = 0; i < r->nbr_fields; i++)
    ++ {
    ++ printf (" %s: ", r->els[i].name);
    ++ ghw_disp_subtype_indication (h, r->els[i].type);
    ++ printf (";\n");
    ++ }
    ++ printf ("end record;\n");
    ++ }
    ++ break;
    ++ case ghdl_rtik_subtype_array:
    ++ case ghdl_rtik_subtype_scalar:
    ++ case ghdl_rtik_subtype_record:
    ++ {
    ++ struct ghw_type_common *c = &t->common;
    ++ printf ("subtype %s is ", c->name);
    ++ ghw_disp_subtype_definition (h, t);
    ++ printf (";\n");
    ++ }
    ++ break;
    ++ default:
    ++ printf ("ghw_disp_type: unhandled type kind %d\n", t->kind);
    ++ }
    ++}
    ++
    ++void
    ++ghw_disp_types (struct ghw_handler *h)
    ++{
    ++ unsigned i;
    ++
    ++ for (i = 0; i < h->nbr_types; i++)
    ++ if (h->flag_verbose || !ghw_is_anonymous_type (h, h->types[i]))
    ++ ghw_disp_type (h, h->types[i]);
    ++}
    +--- /dev/null
    ++++ gtkwave-3.3.104+really3.3.118/src/ghwlib.h
    +@@ -0,0 +1,445 @@
    ++/* GHDL Wavefile reader library.
    ++ Copyright (C) 2005-2017 Tristan Gingold
    ++
    ++ GHDL is free software; you can redistribute it and/or modify it under
    ++ the terms of the GNU General Public License as published by the Free
    ++ Software Foundation; either version 2, or (at your option) any later
    ++ version.
    ++
    ++ GHDL is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)