summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--NEWS6
-rw-r--r--doc/groff.texinfo24
-rw-r--r--man/groff.man8
-rw-r--r--man/groff_diff.man9
-rw-r--r--src/roff/troff/input.cpp90
-rw-r--r--src/roff/troff/input.h4
-rw-r--r--tmac/trace.tmac89
8 files changed, 203 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 525817f2..c58fb0db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index 5d8a39a6..c25941df 100644
--- a/NEWS
+++ b/NEWS
@@ -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