WAD In console, tabs are rendered with non-uniform tab-stop spacing

Mar 18, 2010
46
0
#1
Consider this screen scrape, taken from a TCC 23.00.24 x64 session:
> type seetabs.pl
printf("%s\n%s\n", ('1234567890' x 16), ("\t|" x 20) );

> seetabs
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
| | | | | | | | | | | | | | | | | | | |

Notice that the 1st-12th pipe characters are separated by 7 spaces. Likewise for the 14th-20th. But the 12th-14th pipe characters are separated by 3 spaces. This with menu:Options/button:TCC.../tab:Advanced/pane:Tabs/tbox:Width: set to 8. (This value has no effect on how tab-containing text is rendered on the console window, even after restarting TakeCommand. Maybe that is another bug.)

For what it's worth, CMD.exe does the same thing (when I enter: perl seetabs.pl).
 

rconn

Administrator
Staff member
May 14, 2008
10,788
97
#2
The "Tabs" directive in OPTION / Advanced only affects the tab width used by the LIST command.

TCC (and CMD) have nothing to do with the tab spacing in console windows; that's handled by Windows (conhost.exe if you're running Windows 10).

And I don't see any problem here (either in a TCC console or a TCMD tab window); the pipe chars are all separated by 7 spaces.
 
Mar 18, 2010
46
0
#3
Apparently, I left out a necessary reproduction condition. (I discovered this while trying to figure out why you could not see the misbehavior. I had been using a window wide enough to not wrap that seetabs.pl output.)

To exhibit the problem, the window size has to have a width of 105 or more. Then, its WCI. (Working Contrary to Intent)

This same width threshold applies when running CMD.exe (using the same conhost.exe.)
 
Mar 18, 2010
46
0
#4
BTW,Rex, I noticed something exceedingly strange when looking at this thread this morning. Last night, when I made the first post, the line of space separated pipes showed non-uniform spaces. (This supported my subsequent comment, "Notice that the 1st-12th pipe characters are separated by 7 spaces. Likewise for the 14th-20th. But the 12th-14th pipe characters are separated by 3 spaces.") Yet now, as I type this, looking at the thread with your post included, the pipe characters are all separated by 1 space. I distinctly remember being careful to verify that, in my post while composing it, the separations were as I asserted. Did the content of my recorded post change?
 
Mar 18, 2010
46
0
#7
I don't think Perl has anything to do with it. For the '|' containing output, it is putting altnernating tab and '|' characters into stdout. If you redirect this output to a file or pipe it into TCC's list, this can be confirmed. (And I doubt that Perl has any knowledge whatsoever as to what is being done with that output. Also, it is a remarkably well-behaved program, especially considering its complexity.)

FWIW, I tried your (Vince's) code, repeated 20 times. Also, in groups of 5 separated by sleep(1). None of this made any difference in the emitted (to stdout) content or how it is rendered on the console.
 
Mar 18, 2010
46
0
#8
And here is the output, as rendered to the console and screen-scraped, bounded by tags as Charles so helpfully shows:
Code:
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |   |   |       |       |       |       |       |       |
 
Mar 18, 2010
46
0
#9
And, (to confirm what was sent to the console for rendering),
Code:
> seetabs | od -c --width=27
0000000   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7
0000033   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4
0000066   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1
0000121   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8
0000154   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
0000207   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0  \r  \n
0000242  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t
0000275   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \r  \n
0000314
Note the perfect alternation, from offset 0242 onward, of tab and '|' bytes.
 
#10
Now I don't know who to blame it on. You can take perl right out of the question by using a file. The file is not rendered properly by TCC's TYPE or CMD's TYPE. It is rendered properly by TCSH's built-in cat, an ancient CAT.EXE from Thompson Toolkit, and by Gnu's CAT.EXE.

1531239015318.png
 
#11
And, in my own EXE, with the contents of that file in buf (with the newline, NUL-terminated, dwRead = 42) all three of these render it WRONGLY (exactly as seen in several previous posts).
Code:
    printf("%s", buf);
    wprintf(L"%S", buf);
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), buf, dwRead, &dwWritten, NULL);
 
#12
Thanks, Vince, for making some progress on this mystery and providing a work-around.
Here is an interesting console session screenscrape:
Code:
> seetabs | cat - > con
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |   |   |       |       |       |       |       |       |

> seetabs | cat -
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |

> seetabs | cat - | od -c --width=27
0000000   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7
0000033   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4
0000066   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1
0000121   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8
0000154   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
0000207   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0  \r  \n
0000242  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t
0000275   |  \t   |  \t   |  \t   |  \t   |  \t   |  \t   |  \r  \n
0000314
Note the difference between the results from "cat -" with and without output redirection.

It appears that how the console is reached is what matters. Maybe this is related to how standard handles are being manipulated in the course of redirection.
 
Jan 19, 2011
581
10
Norman, OK
#13
I don't know if I've changed my CMD display settings in the past, but my current CMD window defaults to 100 characters wide. Interestingly the hiccup occurs right after that 100 character mark even after changing the console to 200 characters wide.
 
Jan 19, 2011
581
10
Norman, OK
#14
Made my CMD console window "Screen Buffer Size" really wide (width=4000). Looks like it happens every 100 characters (although it's not apparent at multiples of 200 which are multiples of 8).
 

rconn

Administrator
Staff member
May 14, 2008
10,788
97
#16
While this is moderately entertaining, it still has nothing to do with TCC, which doesn't differentiate between a tab and any other character when it's writing output. Unless you have ANSI enabled, TCC just calls WriteConsole to output the string, tabs and all.

How Windows handles it depends on whether ENABLE_PROCESSED_OUTPUT is set (in SetConsoleMode). In TCC and CMD, it is. If you don't like the results, only Microsoft can do anything about it.

Jf you DO have ANSI enabled, the results depend on whether you're running Windows 10. In that case, the built-in ANSI in the Windows 10 console handles the output. If you are running Win 7 or 8, TCC handles the ANSI output itself, but it does *not* affect any external apps, like CMD or Perl.
 
#17
Yes, on the evidence above you can fairly blame Windows for messing up under some conditions. But the same body of evidence is showing that the console can render tabs correctly past column 96 under some conditions. (See the direct cat outputs below, for example.) And, to preclude the venture that cat is doing something special with its given stdout, see the output piped through what should be transparent TPIPE invocations.

Are you not curious as to what is done to console output handle during the interval between when TCC starts the cat process and when TCC is again writing to the console? Considering the below results of my attempt to make TPIPE a simple pass-through, why is 'cat -' a better do-nothing pipe than 'TPIPE /eol=2,2,2'?

Here is a screen scrape, edited only to remove precisely one line (showing the working directory) that is part of my prompt:
Code:
> seetabs.pl > st.txt

> type st.txt
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |   |   |       |       |       |       |       |       |

> cat st.txt
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |

> cat st.txt | tpipe /eol=2,2,2
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |   |   |       |       |       |       |       |       |

> type seetabs.pl
printf("%s\n%s\n", ('1234567890' x 16), ("\t|" x 20) );

> seetabs | tpipe /eol=2,2,2
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |   |   |       |       |       |       |       |       |

> seetabs.pl | cat -
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |

> grep -v -e Elmo st.txt
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
        |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |

>