signal values that are multi-line strings are not displayed correctly
I tried the following .vcd file:
$timescale 1 ps $end
$scope module phantom_const $end
$scope struct out $end
$var string 1 ! \[0] $end
$var string 1 " \[1] $end
$upscope $end
$upscope $end
$enddefinitions $end
$dumpvars
sPhantomConst(\n\x20\x20\x20\x20[\"a\",\"b\"],\n) !
sPhantomConst(\n\x20\x20\x20\x20[\"a\",\"b\"],\n) "
$end
#1000000
I'm using: GTKWave Analyzer v3.3.118 (w)1999-2023 BSI Installed from the Debian Bookworm package.
That's not the expected use case for strings, and they never were intended to go over a single line. IIRC, the original use case for strings was a VCD hack so enum symbolic names could be emitted into traces.
I have to admit you found a new one. :-) If you want to do that, insert blank lines so it's readable, but that won't always work because it's going to throw off the string length in pixels routines for formatting when the "+" occurs for cases where a string is longer than the area it can render in. Value strings like that are best handled in external logs.
This is the fix I'd put into the C code.
543:/home/bybell/gtkwave/code/gtkwave3-gtk3/src> diff -cNb baseconvert.c.1 baseconvert.c
*** baseconvert.c.1 2025-11-06 15:17:12.565468766 -0500
--- baseconvert.c 2025-11-06 15:28:07.417906276 -0500
***************
*** 1125,1136 ****
char *convert_ascii_string(char *s)
{
! char *rv;
if(s)
{
! rv=(char *)malloc_2(strlen(s)+1);
! strcpy(rv, s);
}
else
{
--- 1125,1142 ----
char *convert_ascii_string(char *s)
{
! char *rv, *d;
if(s)
{
! d=rv=(char *)malloc_2(strlen(s)+1);
! while(*s)
! {
! *d = iscntrl(*s) ? '.' : *s;
! s++;
! d++;
! }
! *d=0;
}
else
{
Preliminary fix is in bbb4593..6d03e3a lts -> lts
I still need to test it thoroughly before I bless it for the next release version.
can you at least convert control characters to the unicode control pictures block? that way you can see what is actually there instead of seeing a bunch of . and not being able to distinguish from the actual ..
suggested code (I tried to match the formatting style but tbh I don't like the style):
char *convert_ascii_string(char *s)
{
char *rv, *dst, *src;
size_t new_len;
if(s)
{
new_len = 0;
for(src = s; *src; src++)
{
if((unsigned char)*src < 0x20 || *src == '\x7F')
new_len += 3; /* UTF-8 length of unicode control picture U+24xx */
else
new_len++;
}
dst = rv = (char *)malloc_2(new_len + 1);
for(src = s; *src; src++)
{
switch(*src)
{
case '\n':
*dst++ = '\xE2'; /* U+2424  in UTF-8 */
*dst++ = '\x90';
*dst++ = '\xA4';
break;
case '\x7F':
*dst++ = '\xE2'; /* U+2421 ␡ in UTF-8 */
*dst++ = '\x90';
*dst++ = '\xA1';
break;
default:
if((unsigned char)*src < 0x20)
{
/* UTF-8 of unicode control picture U+2400-241F */
*dst++ = '\xE2';
*dst++ = '\x90';
*dst++ = '\x80' + *src;
}
else
*dst++ = *src;
}
}
*dst = '\0';
}
else
{
rv=(char *)malloc_2(6);
strcpy(rv, "UNDEF");
}
return(rv);
}
What created your VCD file? If this is a simulator or writer of your own, why don't you simply process strings before encoding then dumping them to do this on your own? Look, for example in convert_ascii_vec_2() used elsewhere:
if (val > 0x7f || !isprint(val)) *pnt++ = '.'; else *pnt++ = val;
I'd prefer not having inconsistent behavior across routines and really should make the previous change conform to this, so special unicode rendering should really be out. I didn't try it, but my guess is that for the fixed space mode, Chinese characters will only allocate half as much space as they should and that's already wrong.
The rewritten drawing code, that will end up in GTKWave 4, uses a Pango feature to make sure the text never wraps:
(Ignore the stray bracket and parenthesis in the left column, because that still uses old code)
I haven't looked at the old drawing code for a long time, but if it uses Pango it should only require this additional setting: pango_layout_set_single_paragraph_mode(layout, TRUE);
For GTKWave 4 I wouldn't mind supporting multi line string values. The drawing code already supports this, but there would need to be an additional per trace setting to enable this.
A problem with supporting multi-line constants is it can get nasty with respect to enforcing variable wrap or truncation individually per line of text. Even if (I suppose) pango might be able to render text into a given block of x-y dimensions, what does a given user want? It's going to vary. (i.e., chop each line off at the end versus wrap overflow text into the next line like some text editors do.)
Earlier versions of the viewer support non-pango fonts, so I don't plan on going down a multi-line text rendering rabbithole with the LTS version. It was definitely an interesting find, so thanks for reporting the rendering bug.
A problem with supporting multi-line constants is it can get nasty with respect to enforcing variable wrap or truncation individually per line of text. Even if (I suppose) pango might be able to render text into a given block of x-y dimensions, what does a given user want? It's going to vary. (i.e., chop each line off at the end versus wrap overflow text into the next line like some text editors do.)
It does, the example file just didn't show it:
Earlier versions of the viewer support non-pango fonts, so I don't plan on going down a multi-line text rendering rabbithole with the LTS version.
The pango function I mentioned was not intended for adding multi line support, but to ensure that there is always only a single line and provide feedback to the user by automatically inserting the newline markers.
I didn't expect you to add multi line support to LTS. It wouldn't make any sense to add this without variable trace heights for digital traces and adding both would be a massive change for a niche use case.
I noticed one possible issue with replacing all control characters with dots. Tab is also a control character and some users might use tabs as whitespace in strings. Maybe it would be better to leave tabs unchanged, so that the fix for one issue doesn't inadvertently cause another.
I know you don't expect multi line support in LTS and mentioned a switch that makes Pango more well-behaved: it's that there are old X11 vs Pango function calls depending on font used and I'd prefer not to "peel the onion" so to speak where one problem fixed opens up two more in another code path, so laziness might just prevail for me here. :-) I'm sure X11 fonts will render differently from Pango for UTF+8, and it's a certainty for anything outside ASCII text space. I haven't exhaustively tested this, but common sense says there will be multiple issues there. I'll mess with it, but my primary goal at the moment is not having the text rendering jump out of the space allocated for it. I need to sit down one evening soon and attempt to explore the state space of strings with my main goal being to break function and fix what's discovered to be broken. Thanks for the observation on tab.
As a general comment, the easiest implementation of multi line text I can envision would involve something similar to mouseover popups because that's a whole new dynamic window available and it can do pretty much anything outside the main visualization without disturbing the status quo for surrounding text rendering. Once users have to go to some specific zoom level to read text fully, they will get annoyed quickly--at least I would--and my solution in the moment would be to enable mouseovers or whatever the mechanism is similar to that.