At 2020-04-14T20:52:26+1000, John Gardner wrote: > Uh, I think the -C switch might be broken... > > λ GNU-Groff (master): printf '\\n(.C\n' | ./test-groff -Tutf8 | head -n1 > 0 > λ GNU-Groff (master): printf '\\n(.C\n' | ./test-groff -C -Tutf8 | head -n1 > 0
Not exactly. -C is not broken; some of our macro files are broken. This is another manifestation of the issue you originally reported. Note that the problem does not happen with the ps driver: $ ./build/test-groff -C .tm \n(.C 1 The culprit is register-clobbering. Behold: $ ./build/test-groff -Tutf8 -C hi, I'm /<path elided>/../tmac/tty.tmac and I saved 1 in register _C hi, I'm /<path elided>/../tmac/unicode.tmac and I saved 0 in register _C .tm \n(.C 0 $ git diff tmac diff --git a/tmac/tty.tmac b/tmac/tty.tmac index 471fb8bc..d14ebafe 100644 --- a/tmac/tty.tmac +++ b/tmac/tty.tmac @@ -2,6 +2,7 @@ .\" .nr _C \n(.C .cp 0 +.tm hi, I'm \n(.F and I saved \n(_C in register _C . .nroff .ta T 0.8i diff --git a/tmac/unicode.tmac b/tmac/unicode.tmac index 5bda095b..72f24202 100644 --- a/tmac/unicode.tmac +++ b/tmac/unicode.tmac @@ -2,6 +2,7 @@ .\" .nr _C \n(.C .cp 0 +.tm hi, I'm \n(.F and I saved \n(_C in register _C .char - \[hy] .char ` \[oq] .char ' \[cq] There's no nested lexical scope here. It's all one big happy(?) global namespace. > As for the `.cp` register... I guess it's a necessary compromise. After I wrote that patch I took my first long look at how the f**k .do really works and for a little while I thought that you could get an equivalent effect by defining a macro to stash the compatibility state in a register. (You could pop it out straightforwardly, as we currently do, because at the time we need to do that we're in a .cp 0 context.) But that doesn't work because you'd need to define the macro with .de1 to be able to use a long register name. And inside he .de1 body, _compatibility mode will be off again_. Here's how that works. $ ./build/test-groff -Tutf8 -C hi, I'm /<path elided>/../tmac/tty.tmac and I saved 0 in my register hi, I'm /<path elided>/../tmac/unicode.tmac and I saved 0 in my register .tm \n(.C 0 So, not well. Also, the "de1" approach is longer, uglier, and eats more namespace: diff --git a/tmac/tty.tmac b/tmac/tty.tmac index 471fb8bc..8b2f63be 100644 --- a/tmac/tty.tmac +++ b/tmac/tty.tmac @@ -1,7 +1,11 @@ .\" tty.tmac .\" -.nr _C \n(.C +.do de1 savereg +. nr _groff_tty_C \\n(.C +.. +.do savereg .cp 0 +.tm hi, I'm \n(.F and I saved \n[_groff_tty_C] in my register . .nroff .ta T 0.8i @@ -81,7 +85,7 @@ .defcolor cyan rgb #00ffff .defcolor white rgb #ffffff . -.cp \n[_C] +.cp \n[_groff_tty_C] . .ie '\*(.T'cp1047' \ . do mso cp1047.tmac diff --git a/tmac/unicode.tmac b/tmac/unicode.tmac index 5bda095b..072f3a5c 100644 --- a/tmac/unicode.tmac +++ b/tmac/unicode.tmac @@ -1,11 +1,15 @@ .\" unicode.tmac .\" -.nr _C \n(.C +.do de1 savereg +. nr _groff_unicode_C \\n(.C +.. +.do savereg .cp 0 +.tm hi, I'm \n(.F and I saved \n[_groff_unicode_C] in my register .char - \[hy] .char ` \[oq] .char ' \[cq] -.cp \n[_C] +.cp \n[_groff_unicode_C] .\" .\" Local Variables: .\" mode: nroff So there's just no way around it, as far as I can see. On the other hand, I would not bet real money that Tadziu could not devise a black magic incantation to achieve it. :D But I want a solution that is (1) short, (2) easy to cargo-cult, and (3) as easy as possible to understand under the convoluted circumstances. Recall that thanks to Solaris we have to do this dance in all of our man pages if we want to use _any_ non-compatibility mode features. Nobody likes gratuitous feature growth--well, almost nobody--but I'd much rather have people reading one new read-only register than defining macros to work around the elaborate semantics of of .do in man pages. Nobody's screamed bloody murder yet--must still be digesting Easter candy. :P Regards, Branden
signature.asc
Description: PGP signature