diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | doc/groff.texinfo | 24 | ||||
-rw-r--r-- | man/groff.man | 8 | ||||
-rw-r--r-- | man/groff_diff.man | 9 | ||||
-rw-r--r-- | src/roff/troff/input.cpp | 90 | ||||
-rw-r--r-- | src/roff/troff/input.h | 4 | ||||
-rw-r--r-- | tmac/trace.tmac | 89 |
8 files changed, 203 insertions, 50 deletions
@@ -1,3 +1,26 @@ +2006-10-26 Werner LEMBERG <wl@gnu.org> + + Add `\%^' escape to handle the parameters to a macro as a string + argument. + + * src/roff/troff/input.h (DOUBLE_QUOTE): New special character. + + * src/roff/troff/input.cpp (input_iterator, input_stack, + macro_iterator): Add `space_follows_arg' member function. + (macro_iterator::add_arg): Add parameter to set the `space_follows' + flag. + (arg_list): Add member `space_follows'. + Update constructor and all callers. + (decode_args): Store discarded double quotes. + (interpolate_args): Handle DOUBLE_QUOTE. + Add `\%^' escape. + (get_copy, token::next, composite_glyph_name): Handle DOUBLE_QUOTE. + + * tmac/trace.tmac: Trace .nr, .ds, .ds1, .as, .as1. + + * docs/groff.texinfo (Parameters), man/groff.man, + man/groff_diff.man, NEWS: Document it. + 2006-10-24 Bernd Warken * Makefile.in (NOMAKEDIRS): Add groffer subdirectories. @@ -57,6 +57,10 @@ o A new debugging request, `pev', has been added to print all of the current environment, then iterates through all of the known environments, printing each except the one that is current. +o A new escape `\$^' has been added. It represents the parameters of a + macro as if they were an argument to the `ds' request. This is used by + `trace.tmac'. + Pic --- @@ -75,7 +79,6 @@ Afmtodit o New option `-c' to output more font information as comments. - Macro Packages -------------- @@ -83,6 +86,7 @@ o A new macro `Dx' has been added to the mdoc package which identifies the DragonFly OS. o -mtrace now shows whether a macro has been called as .foo or as 'foo. + It also traces calls to the `nr', `ds', `ds1', `as', and `as1' requests. o The PSPIC macro now works with all devices (producing a hollow rectangle on devices which don't support inclusion of PS images) and diff --git a/doc/groff.texinfo b/doc/groff.texinfo index 8bbaeb28..5f813616 100644 --- a/doc/groff.texinfo +++ b/doc/groff.texinfo @@ -11248,6 +11248,30 @@ spaces. If not in compatibility mode, the input level of double quotes is preserved (see @ref{Request and Macro Arguments}). @endDefesc +@Defesc {\\$^, , , } +Handle the parameters of a macro as if they were an argument to the +@code{ds} or similar requests. + +@Example +.de foo +. tm $1=`\\$1' +. tm $2=`\\$2' +. tm $*=`\\$*' +. tm $@@=`\\$@@' +. tm $^=`\\$^' +.. +.foo " This is a "test" + @result{} $1=` This is a ' + @result{} $2=`test"' + @result{} $*=` This is a test"' + @result{} $@@=`" This is a " "test""' + @result{} $^=`" This is a "test"' +@endExample + +This escape is useful mainly for macro packages like @file{trace.tmac} which +redefines some requests and macros for debugging purposes. +@endDefesc + @Defesc {\\$0, , , } @cindex macro name register (@code{\$0}) @cindex @code{als} request, and @code{\$0} diff --git a/man/groff.man b/man/groff.man index 56243762..d562a17f 100644 --- a/man/groff.man +++ b/man/groff.man @@ -2,7 +2,7 @@ .ig groff.man -Last update: 1 Sep 2006 +Last update: 26 Oct 2006 This file is part of groff, the GNU roff type-setting system. @@ -2516,6 +2516,12 @@ by spaces. In a macro or string, the concatenation of all the arguments with each surrounded by double quotes, and separated by spaces. . +.ESC $^ +In a macro, the representation of all parameters as if they were an +argument to the +.request ds +request. +. .\" --------- escaped characters --------- . .ESC \[rs] diff --git a/man/groff_diff.man b/man/groff_diff.man index c1cad547..e3e95c65 100644 --- a/man/groff_diff.man +++ b/man/groff_diff.man @@ -3,7 +3,7 @@ .ig groff_diff.man -Last update : 1 Sep 2006 +Last update : 26 Oct 2006 This file is part of groff, the GNU roff type-setting system. It is the source of the man-page groff_diff(7). @@ -697,6 +697,13 @@ In a macro or string, the concatenation of all the arguments with each surrounded by double quotes, and separated by spaces. . .TP +.B \[rs]$^ +In a macro, the representation of all parameters as if they were an +argument to the +.B ds +request. +. +.TP .BI \[rs]$( nn .TQ .BI \[rs]$[ nnn ] diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 8e820902..2c24df15 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -217,6 +217,7 @@ private: virtual int has_args() { return 0; } virtual int nargs() { return 0; } virtual input_iterator *get_arg(int) { return 0; } + virtual int space_follows_arg(int) { return 0; } virtual int get_break_flag() { return 0; } virtual int get_location(int, const char **, int *) { return 0; } virtual void backtrace() {} @@ -417,6 +418,7 @@ public: static int peek(); static void push(input_iterator *); static input_iterator *get_arg(int); + static int space_follows_arg(int); static int get_break_flag(); static int nargs(); static int get_location(int, const char **, int *); @@ -624,6 +626,15 @@ input_iterator *input_stack::get_arg(int i) return 0; } +int input_stack::space_follows_arg(int i) +{ + input_iterator *p; + for (p = top; p != 0; p = p->next) + if (p->has_args()) + return p->space_follows_arg(i); + return 0; +} + int input_stack::get_break_flag() { return top->get_break_flag(); @@ -872,7 +883,7 @@ static symbol read_long_escape_name(read_mode mode) if (buf == abuf) { if (i == 0) { if (mode != ALLOW_EMPTY) - copy_mode_error("empty escape name"); + copy_mode_error("empty escape name"); return EMPTY_SYMBOL; } return symbol(abuf); @@ -955,6 +966,8 @@ static int get_copy(node **nd, int defining) input_stack::decrease_level(); continue; } + if (c == DOUBLE_QUOTE) + continue; if (c == ESCAPE_NEWLINE) { if (defining) return c; @@ -1707,6 +1720,8 @@ void token::next() case END_QUOTE: input_stack::decrease_level(); continue; + case DOUBLE_QUOTE: + continue; case EOF: type = TOKEN_EOF; return; @@ -3577,12 +3592,13 @@ input_iterator *make_temp_iterator(const char *s) struct arg_list { macro mac; + int space_follows; arg_list *next; - arg_list(const macro &); + arg_list(const macro &, int); ~arg_list(); }; -arg_list::arg_list(const macro &m) : mac(m), next(0) +arg_list::arg_list(const macro &m, int s) : mac(m), space_follows(s), next(0) { } @@ -3599,11 +3615,12 @@ public: macro_iterator(); ~macro_iterator(); int has_args() { return 1; } - input_iterator *get_arg(int i); + input_iterator *get_arg(int); + int space_follows_arg(int); int get_break_flag() { return with_break; } int nargs() { return argc; } - void add_arg(const macro &m); - void shift(int n); + void add_arg(const macro &, int); + void shift(int); int is_macro() { return 1; } int is_diversion(); }; @@ -3624,12 +3641,26 @@ input_iterator *macro_iterator::get_arg(int i) return 0; } -void macro_iterator::add_arg(const macro &m) +int macro_iterator::space_follows_arg(int i) +{ + if (i > 0 && i <= argc) { + arg_list *p = args; + for (int j = 1; j < i; j++) { + assert(p != 0); + p = p->next; + } + return p->space_follows; + } + else + return 0; +} + +void macro_iterator::add_arg(const macro &m, int s) { arg_list **p; for (p = &args; *p; p = &((*p)->next)) ; - *p = new arg_list(m); + *p = new arg_list(m, s); ++argc; } @@ -3729,15 +3760,18 @@ static void decode_args(macro_iterator *mi) macro arg; int quote_input_level = 0; int done_tab_warning = 0; + arg.append(compatible_flag ? PUSH_COMP_MODE : PUSH_GROFF_MODE); + // we store discarded double quotes for \$^ if (c == '"') { + arg.append(DOUBLE_QUOTE); quote_input_level = input_stack::get_level(); c = get_copy(&n); } - arg.append(compatible_flag ? PUSH_COMP_MODE : PUSH_GROFF_MODE); while (c != EOF && c != '\n' && !(c == ' ' && quote_input_level == 0)) { if (quote_input_level > 0 && c == '"' && (compatible_flag || input_stack::get_level() == quote_input_level)) { + arg.append(DOUBLE_QUOTE); c = get_copy(&n); if (c == '"') { arg.append(c); @@ -3760,7 +3794,7 @@ static void decode_args(macro_iterator *mi) } } arg.append(POP_GROFFCOMP_MODE); - mi->add_arg(arg); + mi->add_arg(arg, (c == ' ')); } } } @@ -3811,7 +3845,7 @@ static void decode_string_args(macro_iterator *mi) c = get_copy(&n); } } - mi->add_arg(arg); + mi->add_arg(arg, (c == ' ')); } } @@ -3917,7 +3951,8 @@ static symbol composite_glyph_name(symbol nm) gl.clear(); int c; while ((c = p->get(0)) != EOF) - gl += c; + if (c != DOUBLE_QUOTE) + gl += c; gl += '\0'; const char *u = glyph_name_to_unicode(gl.contents()); if (!u) { @@ -4233,7 +4268,8 @@ static void interpolate_arg(symbol nm) input_iterator *p = input_stack::get_arg(i); int c; while ((c = p->get(0)) != EOF) - args += c; + if (c != DOUBLE_QUOTE) + args += c; if (i != limit) args += ' '; } @@ -4251,7 +4287,8 @@ static void interpolate_arg(symbol nm) input_iterator *p = input_stack::get_arg(i); int c; while ((c = p->get(0)) != EOF) - args += c; + if (c != DOUBLE_QUOTE) + args += c; args += END_QUOTE; args += '"'; if (i != limit) @@ -4262,6 +4299,25 @@ static void interpolate_arg(symbol nm) input_stack::push(make_temp_iterator(args.contents())); } } + else if (s[0] == '^' && s[1] == '\0') { + int limit = input_stack::nargs(); + string args; + int c = input_stack::peek(); + for (int i = 1; i <= limit; i++) { + input_iterator *p = input_stack::get_arg(i); + while ((c = p->get(0)) != EOF) { + if (c == DOUBLE_QUOTE) + c = '"'; + args += c; + } + if (input_stack::space_follows_arg(i)) + args += ' '; + } + if (limit > 0) { + args += '\0'; + input_stack::push(make_temp_iterator(args.contents())); + } + } else { const char *p; for (p = s; *p && csdigit(*p); p++) @@ -4555,12 +4611,12 @@ void chop_macro() // there due to empty am1 requests. for (;;) { if (m->get(m->len - 1) != POP_GROFFCOMP_MODE) - break; + break; have_restore = 1; m->len -= 1; if (m->get(m->len - 1) != PUSH_GROFF_MODE && m->get(m->len - 1) != PUSH_COMP_MODE) - break; + break; have_restore = 0; m->len -= 1; if (m->len == 0) @@ -6935,7 +6991,7 @@ void pipe_output() pipe_command = s; } else - pipe_command = pc; + pipe_command = pc; } #endif /* not POPEN_MISSING */ } diff --git a/src/roff/troff/input.h b/src/roff/troff/input.h index ba6e2e13..7a194c44 100644 --- a/src/roff/troff/input.h +++ b/src/roff/troff/input.h @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2001, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. @@ -59,6 +59,7 @@ const int PUSH_COMP_MODE = 0212; const int POP_GROFFCOMP_MODE = 0213; const int BEGIN_QUOTE = 0214; const int END_QUOTE = 0215; +const int DOUBLE_QUOTE = 0216; #else /* IS_EBCDIC_HOST */ @@ -98,6 +99,7 @@ const int PUSH_COMP_MODE = 072; const int POP_GROFFCOMP_MODE = 073; const int BEGIN_QUOTE = 074; const int END_QUOTE = 075; +const int DOUBLE_QUOTE = 076; #endif /* IS_EBCDIC_HOST */ diff --git a/tmac/trace.tmac b/tmac/trace.tmac index 6ab3fdc3..0c8d7410 100644 --- a/tmac/trace.tmac +++ b/tmac/trace.tmac @@ -9,30 +9,61 @@ . .eo . +.rn nr !!nr +. +.de nr +. do tm1 "\*[!!!sp]*** .nr \$* +. !!nr \$* +.. +. +.rn ds !!ds +.rn ds1 !!ds1 +.rn as !!as +.rn as1 !!as1 +. +.de ds +. do tm1 "\*[!!!sp]*** .ds \$^ +. do !!ds \$^\" +.. +. +.de ds1 +. do tm1 "\*[!!!sp]*** .ds1 \$^ +. do !!ds1 \$^\" +.. +. +.de as +. do tm1 "\*[!!!sp]*** .as \$^ +. do !!as \$^\" +.. +. +.de as1 +. do tm1 "\*[!!!sp]*** .as1 \$^ +. do !!as1 \$^\" +.. +. .rn de !!de .rn de1 !!de1 . -. .!!de de . do ecs . ec . do !!de \$1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** de trace enter: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** de trace enter \$1: \\*[!!!br]\\$0 \\$@ -. do as !!!sp " \" +. do !!as !!!sp " \" . do ie \\n[.br] .do !!\$1 \\$@ . el 'do !!\$1 \\$@ . do substring !!!sp 1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** trace exit: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** trace exit \$1: \\*[!!!br]\\$0 \\$@ \.. . -. do ds !!d1 !!\$1 -. do ds !!d2 \$2 +. do !!ds !!d1 !!\$1 +. do !!ds !!d2 \$2 . . do ecr . do dei !!d1 !!d2 @@ -42,22 +73,22 @@ . do ecs . ec . do !!de \$1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** de1 trace enter: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** de1 trace enter \$1: \\*[!!!br]\\$0 \\$@ -. do as !!!sp " \" +. do !!as !!!sp " \" . do ie \\n[.br] .do !!\$1 \\$@ . el 'do !!\$1 \\$@ . do substring !!!sp 1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** trace exit: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** trace exit \$1: \\*[!!!br]\\$0 \\$@ \.. . -. do ds !!d1 !!\$1 -. do ds !!d2 \$2 +. do !!ds !!d1 !!\$1 +. do !!ds !!d2 \$2 . . do ecr . do dei1 !!d1 !!d2 @@ -70,22 +101,22 @@ . do ecs . ec . do !!de \$1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** am trace enter: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** am trace enter \$1: \\*[!!!br]\\$0 \\$@ -. do as !!!sp " \" +. do !!as !!!sp " \" . do ie \\n[.br] .do !!\$1 \\$@ . el 'do !!\$1 \\$@ . do substring !!!sp 1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** trace exit: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** trace exit \$1: \\*[!!!br]\\$0 \\$@ \.. . -. do ds !!a1 !!\$1 -. do ds !!a2 \$2 +. do !!ds !!a1 !!\$1 +. do !!ds !!a2 \$2 . . do ecr . do ami !!a1 !!a2 @@ -95,22 +126,22 @@ . do ecs . ec . do !!de \$1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** am1 trace enter: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** am1 trace enter \$1: \\*[!!!br]\\$0 \\$@ -. do as !!!sp " \" +. do !!as !!!sp " \" . do ie \\n[.br] .do !!\$1 \\$@ . el 'do !!\$1 \\$@ . do substring !!!sp 1 -. do ie \\n[.br] .ds !!!br .\" -. el .do ds !!!br '\" +. do ie \\n[.br] .!!ds !!!br .\" +. el .do !!ds !!!br '\" . ie "\$1"\\$0" .do tm1 "\\*[!!!sp]*** trace exit: \\*[!!!br]\\$0 \\$@ . el .do tm1 "\\*[!!!sp]*** trace exit \$1: \\*[!!!br]\\$0 \\$@ \.. . -. do ds !!a1 !!\$1 -. do ds !!a2 \$2 +. do !!ds !!a1 !!\$1 +. do !!ds !!a2 \$2 . . do ecr . do ami1 !!a1 !!a2 |