From 6795d15c7bed7568853eb92c5334fb628b8110e2 Mon Sep 17 00:00:00 2001 From: Werner LEMBERG Date: Thu, 25 Sep 2008 07:47:38 +0000 Subject: [PATCH] Fix incompatibility between `.de1' and `.do'. Without this change, the following snippet .de1 xx . tm \\n(.C .. .cp 1 .do xx prints 1 instead of 0. * src/roff/troff/input.cc (do_request): If a macro gets processed, call tok.next(). (interpolate_macro): Add optional argument. Update callers. (request::invoke): Add optional argument. (macro::invoke): Add optional argument to delay call of tok.next(). * src/roff/troff/request.h (request_or_macro): Add argument to `invoke' member. Update all derived classes. * doc/groff.texinfo: Improve documentation of .do request. --- ChangeLog | 24 ++++++++++++++++++++++++ doc/groff.texinfo | 5 ++++- src/roff/troff/input.cpp | 21 ++++++++++++++------- src/roff/troff/request.h | 14 +++++++------- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2f5cfa2a..ed7a8258 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2008-09-24 Werner LEMBERG + + Fix incompatibility between `.de1' and `.do'. Without this change, + the following snippet + + .de1 xx + . tm \\n(.C + .. + .cp 1 + .do xx + + prints 1 instead of 0. + + * src/roff/troff/input.cc (do_request): If a macro gets processed, + call tok.next(). + (interpolate_macro): Add optional argument. Update callers. + (request::invoke): Add optional argument. + (macro::invoke): Add optional argument to delay call of tok.next(). + + * src/roff/troff/request.h (request_or_macro): Add argument to + `invoke' member. Update all derived classes. + + * doc/groff.texinfo: Improve documentation of .do request. + 2008-09-09 Werner LEMBERG * tmac/an-old.tmac (FT): Initialize properly. Reported by Tadziu diff --git a/doc/groff.texinfo b/doc/groff.texinfo index 83bec112..017ea32e 100644 --- a/doc/groff.texinfo +++ b/doc/groff.texinfo @@ -14166,7 +14166,10 @@ Compatibility mode can be also turned on with the @option{-C} command line option. The @code{do} request turns off compatibility mode -while executing its arguments as a @code{gtroff} command. +while executing its arguments as a @code{gtroff} command. However, it +does not turn off compatibility mode while processing the macro itself. +To do that, use the @code{de1} request (or manipulate the @code{.C} +register manually). @xref{Writing Macros}. @Example .do fam T diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index bef9274b..58e576b4 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -139,7 +139,7 @@ static symbol read_escape_name(read_mode = NO_ARGS); static symbol read_long_escape_name(read_mode = NO_ARGS); static void interpolate_string(symbol); static void interpolate_string_with_args(symbol); -static void interpolate_macro(symbol); +static void interpolate_macro(symbol, int = 0); static void interpolate_number_format(symbol); static void interpolate_environment_variable(symbol); @@ -2601,8 +2601,12 @@ void do_request() if (nm.is_null()) skip_line(); else - interpolate_macro(nm); + interpolate_macro(nm, 1); compatible_flag = old_compatible_flag; + request_or_macro *p = lookup_request(nm); + macro *m = p->to_macro(); + if (m) + tok.next(); } inline int possibly_handle_first_page_transition() @@ -3006,7 +3010,7 @@ request::request(REQUEST_FUNCP pp) : p(pp) { } -void request::invoke(symbol) +void request::invoke(symbol, int) { (*p)(); } @@ -3716,7 +3720,7 @@ int operator==(const macro &m1, const macro &m2) return 1; } -static void interpolate_macro(symbol nm) +static void interpolate_macro(symbol nm, int no_next) { request_or_macro *p = (request_or_macro *)request_dictionary.lookup(nm); if (p == 0) { @@ -3745,7 +3749,7 @@ static void interpolate_macro(symbol nm) } } if (p) - p->invoke(nm); + p->invoke(nm, no_next); else { skip_line(); return; @@ -3854,12 +3858,15 @@ static void decode_string_args(macro_iterator *mi) } } -void macro::invoke(symbol nm) +void macro::invoke(symbol nm, int no_next) { macro_iterator *mi = new macro_iterator(nm, *this); decode_args(mi); input_stack::push(mi); - tok.next(); + // we must delay tok.next() in case the function has been called by + // do_request to assure proper handling of compatible_flag + if (!no_next) + tok.next(); } macro *macro::to_macro() diff --git a/src/roff/troff/request.h b/src/roff/troff/request.h index 24d25890..098de7cc 100644 --- a/src/roff/troff/request.h +++ b/src/roff/troff/request.h @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004 +/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004, 2008 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) @@ -26,14 +26,14 @@ class macro; class request_or_macro : public object { public: request_or_macro(); - virtual void invoke(symbol s) = 0; + virtual void invoke(symbol, int) = 0; virtual macro *to_macro(); }; class request : public request_or_macro { REQUEST_FUNCP p; public: - void invoke(symbol); + void invoke(symbol, int); request(REQUEST_FUNCP); }; @@ -59,13 +59,13 @@ public: macro &operator=(const macro &); void append(unsigned char); void append(node *); - void append_unsigned(unsigned int i); - void append_int(int i); + void append_unsigned(unsigned int); + void append_int(int); void append_str(const char *); void set(unsigned char, int); unsigned char get(int); int length(); - void invoke(symbol); + void invoke(symbol, int); macro *to_macro(); void print_size(); int empty(); @@ -83,7 +83,7 @@ extern void init_node_requests(); extern void init_reg_requests(); extern void init_env_requests(); extern void init_hyphen_requests(); -extern void init_request(const char *s, REQUEST_FUNCP f); +extern void init_request(const char *, REQUEST_FUNCP); class charinfo; class environment; -- 2.11.4.GIT