summaryrefslogtreecommitdiffstats
path: root/contrib/groff/src/roff/troff
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2005-10-20 10:45:19 +0000
committerru <ru@FreeBSD.org>2005-10-20 10:45:19 +0000
commit353ac0b339df3493d1950b6527988b77b76bd197 (patch)
tree8a188846a3f5bd2f2b8cb869cba64e3c470a2b26 /contrib/groff/src/roff/troff
parentc40093b1f1b43dc237b9d272697cdd0842ec64ec (diff)
downloadFreeBSD-src-353ac0b339df3493d1950b6527988b77b76bd197.zip
FreeBSD-src-353ac0b339df3493d1950b6527988b77b76bd197.tar.gz
Virgin import of FSF groff v1.19.2
Diffstat (limited to 'contrib/groff/src/roff/troff')
-rw-r--r--contrib/groff/src/roff/troff/Makefile.sub21
-rw-r--r--contrib/groff/src/roff/troff/charinfo.h2
-rw-r--r--contrib/groff/src/roff/troff/column.cpp4
-rw-r--r--contrib/groff/src/roff/troff/dictionary.cpp7
-rw-r--r--contrib/groff/src/roff/troff/dictionary.h2
-rw-r--r--contrib/groff/src/roff/troff/div.cpp66
-rw-r--r--contrib/groff/src/roff/troff/div.h21
-rw-r--r--contrib/groff/src/roff/troff/env.cpp449
-rw-r--r--contrib/groff/src/roff/troff/env.h111
-rw-r--r--contrib/groff/src/roff/troff/hvunits.h2
-rw-r--r--contrib/groff/src/roff/troff/input.cpp599
-rw-r--r--contrib/groff/src/roff/troff/input.h21
-rw-r--r--contrib/groff/src/roff/troff/mtsm.cpp632
-rw-r--r--contrib/groff/src/roff/troff/mtsm.h164
-rw-r--r--contrib/groff/src/roff/troff/node.cpp795
-rw-r--r--contrib/groff/src/roff/troff/node.h171
-rw-r--r--contrib/groff/src/roff/troff/number.cpp7
-rw-r--r--contrib/groff/src/roff/troff/reg.cpp5
-rw-r--r--contrib/groff/src/roff/troff/reg.h2
-rw-r--r--contrib/groff/src/roff/troff/request.h11
-rw-r--r--contrib/groff/src/roff/troff/token.h10
-rw-r--r--contrib/groff/src/roff/troff/troff.h8
-rw-r--r--contrib/groff/src/roff/troff/troff.man22
23 files changed, 2498 insertions, 634 deletions
diff --git a/contrib/groff/src/roff/troff/Makefile.sub b/contrib/groff/src/roff/troff/Makefile.sub
index 7fa8024..82c727d 100644
--- a/contrib/groff/src/roff/troff/Makefile.sub
+++ b/contrib/groff/src/roff/troff/Makefile.sub
@@ -6,30 +6,22 @@ OBJS=\
dictionary.$(OBJEXT) \
div.$(OBJEXT) \
env.$(OBJEXT) \
- glyphuni.$(OBJEXT) \
input.$(OBJEXT) \
majorminor.$(OBJEXT) \
+ mtsm.$(OBJEXT) \
node.$(OBJEXT) \
number.$(OBJEXT) \
- reg.$(OBJEXT) \
- symbol.$(OBJEXT) \
- unicode.$(OBJEXT) \
- uniglyph.$(OBJEXT) \
- uniuni.$(OBJEXT)
+ reg.$(OBJEXT)
CCSRCS=\
$(srcdir)/dictionary.cpp \
$(srcdir)/div.cpp \
$(srcdir)/env.cpp \
- $(srcdir)/glyphuni.cpp \
$(srcdir)/input.cpp \
majorminor.cpp \
+ $(srcdir)/mtsm.cpp \
$(srcdir)/node.cpp \
$(srcdir)/number.cpp \
- $(srcdir)/reg.cpp \
- $(srcdir)/symbol.cpp \
- $(srcdir)/unicode.cpp \
- $(srcdir)/uniglyph.cpp \
- $(srcdir)/uniuni.cpp
+ $(srcdir)/reg.cpp
HDRS=\
$(srcdir)/charinfo.h \
$(srcdir)/dictionary.h \
@@ -37,13 +29,12 @@ HDRS=\
$(srcdir)/env.h \
$(srcdir)/hvunits.h \
$(srcdir)/input.h \
+ $(srcdir)/mtsm.h \
$(srcdir)/node.h \
$(srcdir)/reg.h \
$(srcdir)/request.h \
- $(srcdir)/symbol.h \
$(srcdir)/token.h \
- $(srcdir)/troff.h \
- $(srcdir)/unicode.h
+ $(srcdir)/troff.h
GENSRCS=majorminor.cpp
NAMEPREFIX=$(g)
diff --git a/contrib/groff/src/roff/troff/charinfo.h b/contrib/groff/src/roff/troff/charinfo.h
index 4123fba..42190fd 100644
--- a/contrib/groff/src/roff/troff/charinfo.h
+++ b/contrib/groff/src/roff/troff/charinfo.h
@@ -17,7 +17,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
class macro;
diff --git a/contrib/groff/src/roff/troff/column.cpp b/contrib/groff/src/roff/troff/column.cpp
index 8d6a6eb..060b088 100644
--- a/contrib/groff/src/roff/troff/column.cpp
+++ b/contrib/groff/src/roff/troff/column.cpp
@@ -16,7 +16,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef COLUMN
@@ -666,7 +666,7 @@ vjustify_node::vjustify_node(symbol t)
node *vjustify_node::copy()
{
- return new vjustify_node(typ);
+ return new vjustify_node(typ, div_nest_level);
}
const char *vjustify_node::type()
diff --git a/contrib/groff/src/roff/troff/dictionary.cpp b/contrib/groff/src/roff/troff/dictionary.cpp
index a70ebb0..37084b6 100644
--- a/contrib/groff/src/roff/troff/dictionary.cpp
+++ b/contrib/groff/src/roff/troff/dictionary.cpp
@@ -1,5 +1,6 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2004
+ Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
This file is part of groff.
@@ -16,11 +17,10 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "troff.h"
-#include "symbol.h"
#include "dictionary.h"
// is `p' a good size for a hash table
@@ -209,4 +209,3 @@ int object_dictionary::alias(symbol newnm, symbol oldnm)
}
return 0;
}
-
diff --git a/contrib/groff/src/roff/troff/dictionary.h b/contrib/groff/src/roff/troff/dictionary.h
index 4f319be..2baab0a 100644
--- a/contrib/groff/src/roff/troff/dictionary.h
+++ b/contrib/groff/src/roff/troff/dictionary.h
@@ -16,7 +16,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
diff --git a/contrib/groff/src/roff/troff/div.cpp b/contrib/groff/src/roff/troff/div.cpp
index 1bbbe45..4cacd8d 100644
--- a/contrib/groff/src/roff/troff/div.cpp
+++ b/contrib/groff/src/roff/troff/div.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,15 +17,16 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
// diversions
#include "troff.h"
-#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
+#include "stringclass.h"
+#include "mtsm.h"
#include "env.h"
#include "request.h"
#include "node.h"
@@ -33,6 +34,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "div.h"
#include "reg.h"
+#include "nonposix.h"
+
int exit_started = 0; // the exit process has started
int done_end_macro = 0; // the end macro (if any) has finished
int seen_last_page_ejector = 0; // seen the LAST_PAGE_EJECTOR cookie
@@ -50,7 +53,9 @@ static vunits needed_space;
diversion::diversion(symbol s)
: prev(0), nm(s), vertical_position(V0), high_water_mark(V0),
- no_space_mode(0), marked_place(V0)
+ any_chars_added(0), no_space_mode(0), needs_push(0), saved_seen_break(0),
+ saved_seen_space(0), saved_seen_eol(0), saved_suppress_next_eol(0),
+ marked_place(V0)
{
}
@@ -96,6 +101,10 @@ void do_divert(int append, int boxing)
symbol nm = get_name();
if (nm.is_null()) {
if (curdiv->prev) {
+ curenv->seen_break = curdiv->saved_seen_break;
+ curenv->seen_space = curdiv->saved_seen_space;
+ curenv->seen_eol = curdiv->saved_seen_eol;
+ curenv->suppress_next_eol = curdiv->saved_suppress_next_eol;
if (boxing) {
curenv->line = curdiv->saved_line;
curenv->width_total = curdiv->saved_width_total;
@@ -115,6 +124,13 @@ void do_divert(int append, int boxing)
macro_diversion *md = new macro_diversion(nm, append);
md->prev = curdiv;
curdiv = md;
+ curdiv->saved_seen_break = curenv->seen_break;
+ curdiv->saved_seen_space = curenv->seen_space;
+ curdiv->saved_seen_eol = curenv->seen_eol;
+ curdiv->saved_suppress_next_eol = curenv->suppress_next_eol;
+ curenv->seen_break = 0;
+ curenv->seen_space = 0;
+ curenv->seen_eol = 0;
if (boxing) {
curdiv->saved_line = curenv->line;
curdiv->saved_width_total = curenv->width_total;
@@ -201,7 +217,7 @@ macro_diversion::macro_diversion(symbol s, int append)
// We can now catch the situation described above by comparing
// the length of the charlist in the macro_header with the length
// stored in the macro. When we detect this, we copy the contents.
- mac = new macro;
+ mac = new macro(1);
if (append) {
request_or_macro *rm
= (request_or_macro *)request_dictionary.lookup(s);
@@ -256,9 +272,8 @@ void macro_diversion::output(node *nd, int retain_size,
nd->set_vertical_size(&v);
node *temp = nd;
nd = nd->next;
- if (temp->interpret(mac)) {
+ if (temp->interpret(mac))
delete temp;
- }
else {
#if 1
temp->freeze_space();
@@ -444,6 +459,9 @@ void top_level_diversion::space(vunits n, int forced)
vunits next_trap_pos;
trap *next_trap = find_next_trap(&next_trap_pos);
vunits y = vertical_position + n;
+ if (curenv->get_vertical_spacing().to_units())
+ curenv->seen_space += n.to_units()
+ / curenv->get_vertical_spacing().to_units();
if (vertical_position_traps_flag && next_trap != 0 && y >= next_trap_pos) {
vertical_position = next_trap_pos;
nl_reg_contents = vertical_position.to_units();
@@ -467,7 +485,7 @@ trap::trap(symbol s, vunits n, trap *p)
{
}
-void top_level_diversion::add_trap(symbol nm, vunits pos)
+void top_level_diversion::add_trap(symbol nam, vunits pos)
{
trap *first_free_slot = 0;
trap **p;
@@ -477,22 +495,22 @@ void top_level_diversion::add_trap(symbol nm, vunits pos)
first_free_slot = *p;
}
else if ((*p)->position == pos) {
- (*p)->nm = nm;
+ (*p)->nm = nam;
return;
}
}
if (first_free_slot) {
- first_free_slot->nm = nm;
+ first_free_slot->nm = nam;
first_free_slot->position = pos;
}
else
- *p = new trap(nm, pos, 0);
+ *p = new trap(nam, pos, 0);
}
-void top_level_diversion::remove_trap(symbol nm)
+void top_level_diversion::remove_trap(symbol nam)
{
for (trap *p = page_trap_list; p; p = p->next)
- if (p->nm == nm) {
+ if (p->nm == nam) {
p->nm = NULL_SYMBOL;
return;
}
@@ -507,10 +525,10 @@ void top_level_diversion::remove_trap_at(vunits pos)
}
}
-void top_level_diversion::change_trap(symbol nm, vunits pos)
+void top_level_diversion::change_trap(symbol nam, vunits pos)
{
for (trap *p = page_trap_list; p; p = p->next)
- if (p->nm == nm) {
+ if (p->nm == nam) {
p->position = pos;
return;
}
@@ -543,6 +561,7 @@ void cleanup_and_exit(int exit_code)
the_output->trailer(topdiv->get_page_length());
delete the_output;
}
+ FLUSH_INPUT_PIPE(STDIN_FILENO);
exit(exit_code);
}
@@ -637,7 +656,7 @@ void page_offset()
n = topdiv->prev_page_offset;
topdiv->prev_page_offset = topdiv->page_offset;
topdiv->page_offset = n;
- curenv->add_html_tag(0, ".po", n.to_units());
+ topdiv->modified_tag.incl(MTSM_PO);
skip_line();
}
@@ -667,7 +686,7 @@ void when_request()
void begin_page()
{
int got_arg = 0;
- int n;
+ int n = 0; /* pacify compiler */
if (has_arg() && get_integer(&n, topdiv->get_page_number()))
got_arg = 1;
while (!tok.newline() && !tok.eof())
@@ -730,11 +749,11 @@ void restore_spacing()
skip_line();
}
-/* It is necessary to generate a break before before reading the argument,
-because otherwise arguments using | will be wrong. But if we just
+/* It is necessary to generate a break before reading the argument,
+because otherwise arguments using | will be wrong. But if we just
generate a break as usual, then the line forced out may spring a trap
and thus push a macro onto the input stack before we have had a chance
-to read the argument to the sp request. We resolve this dilemma by
+to read the argument to the sp request. We resolve this dilemma by
setting, before generating the break, a flag which will postpone the
actual pushing of the macro associated with the trap sprung by the
outputting of the line forced out by the break till after we have read
@@ -756,17 +775,15 @@ void space_request()
else
// The line might have had line spacing that was truncated.
truncated_space += n;
- curenv->add_html_tag(1, ".sp", n.to_units());
+
tok.next();
}
void blank_line()
{
curenv->do_break();
- if (!trap_sprung_flag && !curdiv->no_space_mode) {
+ if (!trap_sprung_flag && !curdiv->no_space_mode)
curdiv->space(curenv->get_vertical_spacing());
- curenv->add_html_tag(1, ".sp", 1);
- }
else
truncated_space += curenv->get_vertical_spacing();
}
@@ -830,7 +847,6 @@ void flush_output()
curenv->do_break();
if (the_output)
the_output->flush();
- curenv->add_html_tag(1, ".fl");
tok.next();
}
diff --git a/contrib/groff/src/roff/troff/div.h b/contrib/groff/src/roff/troff/div.h
index bde41a8..c9ff9b4 100644
--- a/contrib/groff/src/roff/troff/div.h
+++ b/contrib/groff/src/roff/troff/div.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2004, 2005
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,7 +17,11 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+void do_divert(int append, int boxing);
+void end_diversions();
+void page_offset();
class diversion {
friend void do_divert(int append, int boxing);
@@ -34,7 +38,14 @@ protected:
vunits vertical_position;
vunits high_water_mark;
public:
+ int any_chars_added;
int no_space_mode;
+ int needs_push;
+ int saved_seen_break;
+ int saved_seen_space;
+ int saved_seen_eol;
+ int saved_suppress_next_eol;
+ state_set modified_tag;
vunits marked_place;
diversion(symbol s = NULL_SYMBOL);
virtual ~diversion();
@@ -54,6 +65,7 @@ public:
virtual void set_diversion_trap(symbol, vunits) = 0;
virtual void clear_diversion_trap() = 0;
virtual void copy_file(const char *filename) = 0;
+ virtual int is_diversion() = 0;
};
class macro;
@@ -78,6 +90,7 @@ public:
void set_diversion_trap(symbol, vunits);
void clear_diversion_trap();
void copy_file(const char *filename);
+ int is_diversion() { return 1; }
};
struct trap {
@@ -87,7 +100,7 @@ struct trap {
trap(symbol, vunits, trap *);
};
-struct output_file;
+class output_file;
class top_level_diversion : public diversion {
int page_number;
@@ -134,6 +147,7 @@ public:
void set_diversion_trap(symbol, vunits);
void clear_diversion_trap();
void set_last_page() { last_page_count = page_count; }
+ int is_diversion() { return 0; }
};
extern top_level_diversion *topdiv;
@@ -154,6 +168,5 @@ void continue_page_eject();
void handle_first_page_transition();
void blank_line();
void begin_page();
-void end_diversions();
extern void cleanup_and_exit(int);
diff --git a/contrib/groff/src/roff/troff/env.cpp b/contrib/groff/src/roff/troff/env.cpp
index 264b441..9de9a46 100644
--- a/contrib/groff/src/roff/troff/env.cpp
+++ b/contrib/groff/src/roff/troff/env.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,12 +17,13 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "troff.h"
-#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
+#include "stringclass.h"
+#include "mtsm.h"
#include "env.h"
#include "request.h"
#include "node.h"
@@ -52,6 +53,8 @@ environment *env_table[NENVIRONMENTS];
dictionary env_dictionary(10);
environment *curenv;
static int next_line_number = 0;
+extern int suppress_push;
+extern statem *get_diversion_state();
charinfo *field_delimiter_char;
charinfo *padding_indicator_char;
@@ -61,6 +64,7 @@ int translate_space_to_dummy = 0;
class pending_output_line {
node *nd;
int no_fill;
+ int was_centered;
vunits vs;
vunits post_vs;
hunits width;
@@ -70,20 +74,21 @@ class pending_output_line {
public:
pending_output_line *next;
- pending_output_line(node *, int, vunits, vunits, hunits,
+ pending_output_line(node *, int, vunits, vunits, hunits, int,
pending_output_line * = 0);
~pending_output_line();
int output();
#ifdef WIDOW_CONTROL
friend void environment::mark_last_line();
- friend void environment::output(node *, int, vunits, vunits, hunits);
+ friend void environment::output(node *, int, vunits, vunits, hunits, int);
#endif /* WIDOW_CONTROL */
};
pending_output_line::pending_output_line(node *n, int nf, vunits v, vunits pv,
- hunits w, pending_output_line *p)
-: nd(n), no_fill(nf), vs(v), post_vs(pv), width(w),
+ hunits w, int ce,
+ pending_output_line *p)
+: nd(n), no_fill(nf), was_centered(ce), vs(v), post_vs(pv), width(w),
#ifdef WIDOW_CONTROL
last_line(0),
#endif /* WIDOW_CONTROL */
@@ -109,13 +114,15 @@ int pending_output_line::output()
}
}
#endif
+ curenv->construct_format_state(nd, was_centered, !no_fill);
curdiv->output(nd, no_fill, vs, post_vs, width);
nd = 0;
return 1;
}
-void environment::output(node *nd, int no_fill, vunits vs, vunits post_vs,
- hunits width)
+void environment::output(node *nd, int no_fill_flag,
+ vunits vs, vunits post_vs,
+ hunits width, int was_centered)
{
#ifdef WIDOW_CONTROL
while (pending_lines) {
@@ -132,29 +139,31 @@ void environment::output(node *nd, int no_fill, vunits vs, vunits post_vs,
#endif /* WIDOW_CONTROL */
if (!trap_sprung_flag && !pending_lines
#ifdef WIDOW_CONTROL
- && (!widow_control || no_fill)
+ && (!widow_control || no_fill_flag)
#endif /* WIDOW_CONTROL */
) {
- curdiv->output(nd, no_fill, vs, post_vs, width);
- emitted_node = 1;
+ curenv->construct_format_state(nd, was_centered, !no_fill_flag);
+ curdiv->output(nd, no_fill_flag, vs, post_vs, width);
} else {
pending_output_line **p;
for (p = &pending_lines; *p; p = &(*p)->next)
;
- *p = new pending_output_line(nd, no_fill, vs, post_vs, width);
+ *p = new pending_output_line(nd, no_fill_flag, vs, post_vs, width,
+ was_centered);
}
}
// a line from .tl goes at the head of the queue
-void environment::output_title(node *nd, int no_fill, vunits vs,
- vunits post_vs, hunits width)
+void environment::output_title(node *nd, int no_fill_flag,
+ vunits vs, vunits post_vs,
+ hunits width)
{
if (!trap_sprung_flag)
- curdiv->output(nd, no_fill, vs, post_vs, width);
+ curdiv->output(nd, no_fill_flag, vs, post_vs, width);
else
- pending_lines = new pending_output_line(nd, no_fill, vs, post_vs, width,
- pending_lines);
+ pending_lines = new pending_output_line(nd, no_fill_flag, vs, post_vs,
+ width, 0, pending_lines);
}
void environment::output_pending_lines()
@@ -172,7 +181,8 @@ void environment::mark_last_line()
{
if (!widow_control || !pending_lines)
return;
- for (pending_output_line *p = pending_lines; p->next; p = p->next)
+ pending_output_line *p;
+ for (p = pending_lines; p->next; p = p->next)
;
if (!p->no_fill)
p->last_line = 1;
@@ -264,6 +274,7 @@ void leader_character()
void environment::add_char(charinfo *ci)
{
int s;
+ node *gc_np = 0;
if (interrupted)
;
// don't allow fields in dummy environments
@@ -279,18 +290,40 @@ void environment::add_char(charinfo *ci)
if (tab_contents == 0)
tab_contents = new line_start_node;
if (ci != hyphen_indicator_char)
- tab_contents = tab_contents->add_char(ci, this, &tab_width, &s);
+ tab_contents = tab_contents->add_char(ci, this, &tab_width, &s, &gc_np);
else
tab_contents = tab_contents->add_discretionary_hyphen();
}
else {
if (line == 0)
start_line();
+#if 0
+ fprintf(stderr, "current line is\n");
+ line->debug_node_list();
+#endif
if (ci != hyphen_indicator_char)
- line = line->add_char(ci, this, &width_total, &space_total);
+ line = line->add_char(ci, this, &width_total, &space_total, &gc_np);
else
line = line->add_discretionary_hyphen();
}
+#if 0
+ fprintf(stderr, "now after we have added character the line is\n");
+ line->debug_node_list();
+#endif
+ if ((!suppress_push) && gc_np) {
+ if (gc_np && (gc_np->state == 0)) {
+ gc_np->state = construct_state(0);
+ gc_np->push_state = get_diversion_state();
+ }
+ else if (line && (line->state == 0)) {
+ line->state = construct_state(0);
+ line->push_state = get_diversion_state();
+ }
+ }
+#if 0
+ fprintf(stderr, "now we have possibly added the state the line is\n");
+ line->debug_node_list();
+#endif
}
node *environment::make_char_node(charinfo *ci)
@@ -302,6 +335,12 @@ void environment::add_node(node *n)
{
if (n == 0)
return;
+ if (!suppress_push) {
+ if (n->is_special && n->state == NULL)
+ n->state = construct_state(0);
+ n->push_state = get_diversion_state();
+ }
+
if (current_tab || current_field)
n->freeze_space();
if (interrupted) {
@@ -325,10 +364,10 @@ void environment::add_node(node *n)
space_total += n->nspaces();
n->next = line;
line = n;
+ construct_new_line_state(line);
}
}
-
void environment::add_hyphen_indicator()
{
if (current_tab || interrupted || current_field
@@ -612,7 +651,6 @@ environment::environment(symbol nm)
width_total(0),
space_total(0),
input_line_start(0),
- tabs(units_per_inch/2, TAB_LEFT),
line_tabs(0),
current_tab(TAB_NONE),
leader_node(0),
@@ -639,12 +677,15 @@ environment::environment(symbol nm)
#ifdef WIDOW_CONTROL
widow_control(0),
#endif /* WIDOW_CONTROL */
- ignore_next_eol(0),
- emitted_node(0),
glyph_color(&default_color),
prev_glyph_color(&default_color),
fill_color(&default_color),
prev_fill_color(&default_color),
+ seen_space(0),
+ seen_eol(0),
+ suppress_next_eol(0),
+ seen_break(0),
+ tabs(units_per_inch/2, TAB_LEFT),
name(nm),
control_char('.'),
no_break_control_char('\''),
@@ -702,7 +743,6 @@ environment::environment(const environment *e)
width_total(0),
space_total(0),
input_line_start(0),
- tabs(e->tabs),
line_tabs(e->line_tabs),
current_tab(TAB_NONE),
leader_node(0),
@@ -729,12 +769,15 @@ environment::environment(const environment *e)
#ifdef WIDOW_CONTROL
widow_control(e->widow_control),
#endif /* WIDOW_CONTROL */
- ignore_next_eol(0),
- emitted_node(0),
glyph_color(e->glyph_color),
prev_glyph_color(e->prev_glyph_color),
fill_color(e->fill_color),
prev_fill_color(e->prev_fill_color),
+ seen_space(e->seen_space),
+ seen_eol(e->seen_eol),
+ suppress_next_eol(e->suppress_next_eol),
+ seen_break(e->seen_break),
+ tabs(e->tabs),
name(e->name), // so that eg `.if "\n[.ev]"0"' works
control_char(e->control_char),
no_break_control_char(e->no_break_control_char),
@@ -816,8 +859,6 @@ void environment::copy(const environment *e)
hyphenation_space = e->hyphenation_space;
hyphenation_margin = e->hyphenation_margin;
composite = 0;
- ignore_next_eol = e->ignore_next_eol;
- emitted_node = e->emitted_node;
glyph_color= e->glyph_color;
prev_glyph_color = e->prev_glyph_color;
fill_color = e->fill_color;
@@ -1089,7 +1130,13 @@ void environment_switch()
error("environment stack underflow");
}
else {
+ int seen_space = curenv->seen_space;
+ int seen_eol = curenv->seen_eol;
+ int suppress_next_eol = curenv->suppress_next_eol;
curenv = env_stack->env;
+ curenv->seen_space = seen_space;
+ curenv->seen_eol = seen_eol;
+ curenv->suppress_next_eol = suppress_next_eol;
env_list *tem = env_stack;
env_stack = env_stack->next;
delete tem;
@@ -1126,6 +1173,26 @@ void environment_copy()
skip_line();
}
+void fill_color_change()
+{
+ symbol s = get_name();
+ if (s.is_null())
+ curenv->set_fill_color(curenv->get_prev_fill_color());
+ else
+ do_fill_color(s);
+ skip_line();
+}
+
+void glyph_color_change()
+{
+ symbol s = get_name();
+ if (s.is_null())
+ curenv->set_glyph_color(curenv->get_prev_glyph_color());
+ else
+ do_glyph_color(s);
+ skip_line();
+}
+
static symbol P_symbol("P");
void font_change()
@@ -1164,7 +1231,6 @@ void point_size()
if (n <= 0)
n = 1;
curenv->set_size(n);
- curenv->add_html_tag(0, ".ps", n);
}
else
curenv->set_size(0);
@@ -1232,8 +1298,6 @@ void fill()
if (break_flag)
curenv->do_break();
curenv->fill = 1;
- curenv->add_html_tag(1, ".fi");
- curenv->add_html_tag(0, ".br");
tok.next();
}
@@ -1244,9 +1308,7 @@ void no_fill()
if (break_flag)
curenv->do_break();
curenv->fill = 0;
- curenv->add_html_tag(1, ".nf");
- curenv->add_html_tag(0, ".br");
- curenv->add_html_tag(0, ".po", topdiv->get_page_offset().to_units());
+ curenv->suppress_next_eol = 1;
tok.next();
}
@@ -1263,7 +1325,7 @@ void center()
curenv->do_break();
curenv->right_justify_lines = 0;
curenv->center_lines = n;
- curenv->add_html_tag(1, ".ce", n);
+ curdiv->modified_tag.incl(MTSM_CE);
tok.next();
}
@@ -1280,7 +1342,7 @@ void right_justify()
curenv->do_break();
curenv->center_lines = 0;
curenv->right_justify_lines = n;
- curenv->add_html_tag(1, ".rj", n);
+ curdiv->modified_tag.incl(MTSM_RJ);
tok.next();
}
@@ -1297,7 +1359,7 @@ void line_length()
temp = curenv->prev_line_length;
curenv->prev_line_length = curenv->line_length;
curenv->line_length = temp;
- curenv->add_html_tag(1, ".ll", temp.to_units());
+ curdiv->modified_tag.incl(MTSM_LL);
skip_line();
}
@@ -1384,8 +1446,7 @@ void indent()
curenv->have_temporary_indent = 0;
curenv->prev_indent = curenv->indent;
curenv->indent = temp;
- if (break_flag)
- curenv->add_html_tag(1, ".in", temp.to_units());
+ curdiv->modified_tag.incl(MTSM_IN);
tok.next();
}
@@ -1406,7 +1467,7 @@ void temporary_indent()
if (!err) {
curenv->temporary_indent = temp;
curenv->have_temporary_indent = 1;
- curenv->add_html_tag(1, ".ti", temp.to_units());
+ curdiv->modified_tag.incl(MTSM_TI);
}
tok.next();
}
@@ -1623,6 +1684,7 @@ void environment::interrupt()
void environment::newline()
{
+ int was_centered = 0;
if (underline_lines > 0) {
if (--underline_lines == 0) {
prev_fontno = fontno;
@@ -1661,11 +1723,7 @@ void environment::newline()
if (x > H0)
saved_indent += x/2;
to_be_output = line;
- if (is_html) {
- node *n = make_html_tag("eol.ce");
- n->next = to_be_output;
- to_be_output = n;
- }
+ was_centered = 1;
to_be_output_width = width_total;
line = 0;
}
@@ -1688,14 +1746,14 @@ void environment::newline()
input_line_start = line == 0 ? H0 : width_total;
if (to_be_output) {
if (is_html && !fill) {
- if (curdiv == topdiv) {
- node *n = make_html_tag("eol");
-
- n->next = to_be_output;
- to_be_output = n;
- }
+ curdiv->modified_tag.incl(MTSM_EOL);
+ if (suppress_next_eol)
+ suppress_next_eol = 0;
+ else
+ seen_eol = 1;
}
- output_line(to_be_output, to_be_output_width);
+
+ output_line(to_be_output, to_be_output_width, was_centered);
hyphen_line_count = 0;
}
if (input_trap_count > 0) {
@@ -1705,7 +1763,7 @@ void environment::newline()
}
}
-void environment::output_line(node *n, hunits width)
+void environment::output_line(node *n, hunits width, int was_centered)
{
prev_text_length = width;
if (margin_character_flags) {
@@ -1764,7 +1822,8 @@ void environment::output_line(node *n, hunits width)
width += w;
++next_line_number;
}
- output(nn, !fill, vertical_spacing, total_post_vertical_spacing(), width);
+ output(nn, !fill, vertical_spacing, total_post_vertical_spacing(), width,
+ was_centered);
}
void environment::start_line()
@@ -2012,6 +2071,7 @@ static void distribute_space(node *n, int nspaces, hunits desired_space,
void environment::possibly_break_line(int start_here, int forced)
{
+ int was_centered = center_lines > 0;
if (!fill || current_tab || current_field || dummy)
return;
while (line != 0
@@ -2041,6 +2101,7 @@ void environment::possibly_break_line(int start_here, int forced)
break;
case ADJUST_CENTER:
saved_indent += (target_text_length - bp->width)/2;
+ was_centered = 1;
break;
case ADJUST_RIGHT:
saved_indent += target_text_length - bp->width;
@@ -2078,7 +2139,7 @@ void environment::possibly_break_line(int start_here, int forced)
}
// Do output_line() here so that line will be 0 iff the
// the environment will be empty.
- output_line(pre, output_width);
+ output_line(pre, output_width, was_centered);
while (to_be_discarded != 0) {
tem = to_be_discarded;
to_be_discarded = to_be_discarded->next;
@@ -2141,16 +2202,8 @@ void environment::final_break()
do_break();
}
-/*
- * add_html_tag - emits a special html-tag: to help post-grohtml understand
- * the key troff commands
- */
-
-void environment::add_html_tag(int force, const char *name)
+node *environment::make_tag(const char *nm, int i)
{
- if (!force && (curdiv != topdiv))
- return;
-
if (is_html) {
/*
* need to emit tag for post-grohtml
@@ -2159,132 +2212,119 @@ void environment::add_html_tag(int force, const char *name)
if (curdiv == topdiv && topdiv->before_first_page)
topdiv->begin_page();
macro *m = new macro;
- m->append_str("html-tag:");
- for (const char *p = name; *p; p++)
- if (!invalid_input_char((unsigned char)*p))
- m->append(*p);
- curdiv->output(new special_node(*m), 1, 0, 0, 0);
- if (strcmp(name, ".nf") == 0)
- curenv->ignore_next_eol = 1;
- }
-}
-
-/*
- * add_html_tag - emits a special html-tag: to help post-grohtml understand
- * the key troff commands, it appends a string representation
- * of i.
- */
-
-void environment::add_html_tag(int force, const char *name, int i)
-{
- if (!force && (curdiv != topdiv))
- return;
-
- if (is_html) {
- /*
- * need to emit tag for post-grohtml
- * but we check to see whether we can emit specials
- */
- if (curdiv == topdiv && topdiv->before_first_page)
- topdiv->begin_page();
- macro *m = new macro;
- m->append_str("html-tag:");
- for (const char *p = name; *p; p++)
+ m->append_str("devtag:");
+ for (const char *p = nm; *p; p++)
if (!invalid_input_char((unsigned char)*p))
m->append(*p);
m->append(' ');
m->append_int(i);
- node *n = new special_node(*m);
- curdiv->output(n, 1, 0, 0, 0);
+ return new special_node(*m);
}
+ return 0;
}
-/*
- * add_html_tag_tabs - emits the tab settings for post-grohtml
- */
-
-void environment::add_html_tag_tabs(int force)
+void environment::dump_troff_state()
{
- if (!force && (curdiv != topdiv))
- return;
+#define SPACES " "
+ fprintf(stderr, SPACES "register `in' = %d\n", curenv->indent.to_units());
+ if (curenv->have_temporary_indent)
+ fprintf(stderr, SPACES "register `ti' = %d\n",
+ curenv->temporary_indent.to_units());
+ fprintf(stderr, SPACES "centered lines `ce' = %d\n", curenv->center_lines);
+ fprintf(stderr, SPACES "register `ll' = %d\n",
+ curenv->line_length.to_units());
+ fprintf(stderr, SPACES "fill `fi=1/nf=0' = %d\n", curenv->fill);
+ fprintf(stderr, SPACES "page offset `po' = %d\n",
+ topdiv->get_page_offset().to_units());
+ fprintf(stderr, SPACES "seen_break = %d\n", curenv->seen_break);
+ fprintf(stderr, SPACES "seen_space = %d\n", curenv->seen_space);
+ fflush(stderr);
+#undef SPACES
+}
+statem *environment::construct_state(int only_eol)
+{
if (is_html) {
- /*
- * need to emit tag for post-grohtml
- * but we check to see whether we can emit specials
- */
- if (curdiv == topdiv && topdiv->before_first_page)
- topdiv->begin_page();
- macro *m = new macro;
- hunits d, l;
- enum tab_type t;
- m->append_str("html-tag:.ta ");
- do {
- t = curenv->tabs.distance_to_next_tab(l, &d);
- l += d;
- switch (t) {
- case TAB_LEFT:
- m->append_str(" L ");
- m->append_int(l.to_units());
- break;
- case TAB_CENTER:
- m->append_str(" C ");
- m->append_int(l.to_units());
- break;
- case TAB_RIGHT:
- m->append_str(" R ");
- m->append_int(l.to_units());
- break;
- case TAB_NONE:
- break;
- }
- } while ((t != TAB_NONE) && (l < get_line_length()));
- curdiv->output(new special_node(*m), 1, 0, 0, 0);
+ statem *s = new statem();
+ if (!only_eol) {
+ s->add_tag(MTSM_IN, indent);
+ s->add_tag(MTSM_LL, line_length);
+ s->add_tag(MTSM_PO, topdiv->get_page_offset().to_units());
+ s->add_tag(MTSM_RJ, right_justify_lines);
+ if (have_temporary_indent)
+ s->add_tag(MTSM_TI, temporary_indent);
+ s->add_tag_ta();
+ if (seen_break)
+ s->add_tag(MTSM_BR);
+ if (seen_space != 0)
+ s->add_tag(MTSM_SP, seen_space);
+ seen_break = 0;
+ seen_space = 0;
+ }
+ if (seen_eol) {
+ s->add_tag(MTSM_EOL);
+ s->add_tag(MTSM_CE, center_lines);
+ }
+ seen_eol = 0;
+ return s;
}
+ else
+ return NULL;
}
-node *environment::make_html_tag(const char *name, int i)
+void environment::construct_format_state(node *n, int was_centered,
+ int filling)
{
if (is_html) {
- /*
- * need to emit tag for post-grohtml
- * but we check to see whether we can emit specials
- */
- if (curdiv == topdiv && topdiv->before_first_page)
- topdiv->begin_page();
- macro *m = new macro;
- m->append_str("html-tag:");
- for (const char *p = name; *p; p++)
- if (!invalid_input_char((unsigned char)*p))
- m->append(*p);
- m->append(' ');
- m->append_int(i);
- return new special_node(*m);
+ // find first glyph node which has a state.
+ while (n != 0 && n->state == 0)
+ n = n->next;
+ if (n == 0 || (n->state == 0))
+ return;
+ if (seen_space != 0)
+ n->state->add_tag(MTSM_SP, seen_space);
+ if (seen_eol && topdiv == curdiv)
+ n->state->add_tag(MTSM_EOL);
+ seen_space = 0;
+ seen_eol = 0;
+ if (was_centered)
+ n->state->add_tag(MTSM_CE, center_lines+1);
+ else
+ n->state->add_tag_if_unknown(MTSM_CE, 0);
+ n->state->add_tag_if_unknown(MTSM_FI, filling);
+ n = n->next;
+ while (n != 0) {
+ if (n->state != 0) {
+ n->state->sub_tag_ce();
+ n->state->add_tag_if_unknown(MTSM_FI, filling);
+ }
+ n = n->next;
+ }
}
- return 0;
}
-node *environment::make_html_tag(const char *name)
+void environment::construct_new_line_state(node *n)
{
if (is_html) {
- /*
- * need to emit tag for post-grohtml
- * but we check to see whether we can emit specials
- */
- if (curdiv == topdiv && topdiv->before_first_page)
- topdiv->begin_page();
- macro *m = new macro;
- m->append_str("html-tag:");
- for (const char *p = name; *p; p++)
- if (!invalid_input_char((unsigned char)*p))
- m->append(*p);
- return new special_node(*m);
+ // find first glyph node which has a state.
+ while (n != 0 && n->state == 0)
+ n = n->next;
+ if (n == 0 || n->state == 0)
+ return;
+ if (seen_space != 0)
+ n->state->add_tag(MTSM_SP, seen_space);
+ if (seen_eol && topdiv == curdiv)
+ n->state->add_tag(MTSM_EOL);
+ seen_space = 0;
+ seen_eol = 0;
}
- return 0;
}
-void environment::do_break(int spread)
+extern int global_diverted_space;
+
+void environment::do_break(int do_spread)
{
+ int was_centered = 0;
if (curdiv == topdiv && topdiv->before_first_page) {
topdiv->begin_page();
return;
@@ -2295,7 +2335,7 @@ void environment::do_break(int spread)
// this is so that hyphenation works
line = new space_node(H0, get_fill_color(), line);
space_total++;
- possibly_break_line(0, spread);
+ possibly_break_line(0, do_spread);
}
while (line != 0 && line->discardable()) {
width_total -= line->width();
@@ -2311,6 +2351,7 @@ void environment::do_break(int spread)
switch (adjust_mode) {
case ADJUST_CENTER:
saved_indent += (target_text_length - width_total)/2;
+ was_centered = 1;
break;
case ADJUST_RIGHT:
saved_indent += target_text_length - width_total;
@@ -2319,7 +2360,7 @@ void environment::do_break(int spread)
}
node *tem = line;
line = 0;
- output_line(tem, width_total);
+ output_line(tem, width_total, was_centered);
hyphen_line_count = 0;
}
prev_line_interrupted = 0;
@@ -2327,6 +2368,10 @@ void environment::do_break(int spread)
mark_last_line();
output_pending_lines();
#endif /* WIDOW_CONTROL */
+ if (!global_diverted_space) {
+ curdiv->modified_tag.incl(MTSM_BR);
+ seen_break = 1;
+ }
}
int environment::is_empty()
@@ -2338,10 +2383,8 @@ void do_break_request(int spread)
{
while (!tok.newline() && !tok.eof())
tok.next();
- if (break_flag) {
+ if (break_flag)
curenv->do_break(spread);
- curenv->add_html_tag(0, ".br");
- }
tok.next();
}
@@ -2389,8 +2432,8 @@ void title()
tem->next = n;
n = tem;
}
- hunits title_length(curenv->title_length);
- hunits f = title_length - part_width[1];
+ hunits length_title(curenv->title_length);
+ hunits f = length_title - part_width[1];
hunits f2 = f/2;
n = new hmotion_node(f2 - part_width[2], curenv->get_fill_color(), n);
p = part[1];
@@ -2409,7 +2452,7 @@ void title()
n = tem;
}
curenv->output_title(n, !curenv->fill, curenv->vertical_spacing,
- curenv->total_post_vertical_spacing(), title_length);
+ curenv->total_post_vertical_spacing(), length_title);
curenv->hyphen_line_count = 0;
tok.next();
}
@@ -2748,7 +2791,7 @@ void set_tabs()
}
}
curenv->tabs = tabs;
- curenv->add_html_tag_tabs(1);
+ curdiv->modified_tag.incl(MTSM_TA);
skip_line();
}
@@ -2859,25 +2902,25 @@ node *environment::make_tab_node(hunits d, node *next)
void environment::handle_tab(int is_leader)
{
hunits d;
- hunits abs;
+ hunits absolute;
if (current_tab)
wrap_up_tab();
charinfo *ci = is_leader ? leader_char : tab_char;
delete leader_node;
leader_node = ci ? make_char_node(ci) : 0;
- tab_type t = distance_to_next_tab(&d, &abs);
+ tab_type t = distance_to_next_tab(&d, &absolute);
switch (t) {
case TAB_NONE:
return;
case TAB_LEFT:
+ add_node(make_tag("tab L", absolute.to_units()));
add_node(make_tab_node(d));
- add_node(make_html_tag("tab L", abs.to_units()));
return;
case TAB_RIGHT:
- add_node(make_html_tag("tab R", abs.to_units()));
+ add_node(make_tag("tab R", absolute.to_units()));
break;
case TAB_CENTER:
- add_node(make_html_tag("tab C", abs.to_units()));
+ add_node(make_tag("tab C", absolute.to_units()));
break;
default:
assert(0);
@@ -3091,12 +3134,28 @@ const char *environment::get_font_family_string()
return family->nm.contents();
}
+const char *environment::get_glyph_color_string()
+{
+ return glyph_color->nm.contents();
+}
+
+const char *environment::get_fill_color_string()
+{
+ return fill_color->nm.contents();
+}
+
const char *environment::get_font_name_string()
{
symbol f = get_font_name(fontno, this);
return f.contents();
}
+const char *environment::get_style_name_string()
+{
+ symbol f = get_style_name(fontno);
+ return f.contents();
+}
+
const char *environment::get_name_string()
{
return name.contents();
@@ -3188,7 +3247,9 @@ void init_env_requests()
init_request("fam", family_change);
init_request("fc", field_characters);
init_request("fi", fill);
+ init_request("fcolor", fill_color_change);
init_request("ft", font_change);
+ init_request("gcolor", glyph_color_change);
init_request("hc", hyphen_char);
init_request("hlm", hyphen_line_max_request);
init_request("hy", hyphenate_request);
@@ -3247,6 +3308,8 @@ void init_env_requests()
init_int_env_reg(".L", get_line_spacing);
init_hunits_env_reg(".l", get_line_length);
init_hunits_env_reg(".ll", get_saved_line_length);
+ init_string_env_reg(".M", get_fill_color_string);
+ init_string_env_reg(".m", get_glyph_color_string);
init_hunits_env_reg(".n", get_prev_text_length);
init_int_env_reg(".ps", get_point_size);
init_int_env_reg(".psr", get_requested_point_size);
@@ -3257,6 +3320,7 @@ void init_env_requests()
init_int_env_reg(".ss", get_space_size);
init_int_env_reg(".sss", get_sentence_space_size);
init_string_env_reg(".sr", get_requested_point_size_string);
+ init_string_env_reg(".sty", get_style_name_string);
init_string_env_reg(".tabs", get_tabs);
init_int_env_reg(".u", get_fill);
init_vunits_env_reg(".v", get_vertical_spacing);
@@ -3358,7 +3422,7 @@ static void hyphen_word()
pos[npos++] = i;
}
else {
- int c = ci->get_hyphenation_code();
+ unsigned char c = ci->get_hyphenation_code();
if (c == 0)
break;
buf[i++] = c;
@@ -3661,7 +3725,8 @@ void hyphen_trie::read_patterns_file(const char *name, int append,
c = hpf_getc(fp);
if (c == '{') {
if (have_patterns || have_hyphenation)
- error("`{' not allowed inside of \\patterns or \\hyphenation");
+ error("\\patterns not allowed inside of %1 group",
+ have_patterns ? "\\patterns" : "\\hyphenation");
else {
have_patterns = 1;
have_keyword = 1;
@@ -3675,7 +3740,8 @@ void hyphen_trie::read_patterns_file(const char *name, int append,
c = hpf_getc(fp);
if (c == '{') {
if (have_patterns || have_hyphenation)
- error("`{' not allowed inside of \\patterns or \\hyphenation");
+ error("\\hyphenation not allowed inside of %1 group",
+ have_patterns ? "\\patterns" : "\\hyphenation");
else {
have_hyphenation = 1;
have_keyword = 1;
@@ -3703,8 +3769,17 @@ void hyphen_trie::read_patterns_file(const char *name, int append,
}
c = hpf_getc(fp);
}
- else if (c == '{') // skipped if not starting \patterns
- c = hpf_getc(fp); // or \hyphenation
+ else if (c == '{') {
+ if (have_patterns || have_hyphenation)
+ error("`{' not allowed within %1 group",
+ have_patterns ? "\\patterns" : "\\hyphenation");
+ c = hpf_getc(fp); // skipped if not starting \patterns
+ // or \hyphenation
+ }
+ }
+ else {
+ if (c == '{' || c == '}')
+ c = hpf_getc(fp);
}
if (i > 0) {
if (have_patterns || final_pattern || traditional) {
diff --git a/contrib/groff/src/roff/troff/env.h b/contrib/groff/src/roff/troff/env.h
index 43a4c97..2ee7bdc 100644
--- a/contrib/groff/src/roff/troff/env.h
+++ b/contrib/groff/src/roff/troff/env.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004, 2005
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,7 +17,9 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+class statem;
struct size_range {
int min;
@@ -63,7 +65,7 @@ inline int font_size::to_points()
return p/sizescale;
}
-struct environment;
+class environment;
hunits env_digit_width(environment *);
hunits env_space_width(environment *);
@@ -94,11 +96,52 @@ public:
const unsigned MARGIN_CHARACTER_ON = 1;
const unsigned MARGIN_CHARACTER_NEXT = 2;
-struct charinfo;
+class charinfo;
struct node;
struct breakpoint;
-struct font_family;
-struct pending_output_line;
+class font_family;
+class pending_output_line;
+
+// declarations to avoid friend name injection problems
+void title_length();
+void space_size();
+void fill();
+void no_fill();
+void adjust();
+void no_adjust();
+void center();
+void right_justify();
+void vertical_spacing();
+void post_vertical_spacing();
+void line_spacing();
+void line_length();
+void indent();
+void temporary_indent();
+void do_underline(int);
+void do_input_trap(int);
+void set_tabs();
+void margin_character();
+void no_number();
+void number_lines();
+void leader_character();
+void tab_character();
+void hyphenate_request();
+void no_hyphenate();
+void hyphen_line_max_request();
+void hyphenation_space_request();
+void hyphenation_margin_request();
+void line_width();
+#if 0
+void tabs_save();
+void tabs_restore();
+#endif
+void line_tabs_request();
+void title();
+#ifdef WIDOW_CONTROL
+void widow_control_request();
+#endif /* WIDOW_CONTROL */
+
+void do_divert(int append, int boxing);
class environment {
int dummy; // dummy environment used for \w
@@ -147,7 +190,6 @@ class environment {
hunits width_total;
int space_total;
hunits input_line_start;
- tab_stops tabs;
node *tab_contents;
hunits tab_width;
hunits tab_distance;
@@ -183,8 +225,6 @@ class environment {
#ifdef WIDOW_CONTROL
int widow_control;
#endif /* WIDOW_CONTROL */
- int ignore_next_eol;
- int emitted_node; // have we emitted a node since the last html eol tag?
color *glyph_color;
color *prev_glyph_color;
color *fill_color;
@@ -193,9 +233,9 @@ class environment {
tab_type distance_to_next_tab(hunits *);
tab_type distance_to_next_tab(hunits *distance, hunits *leftpos);
void start_line();
- void output_line(node *, hunits);
+ void output_line(node *, hunits, int);
void output(node *nd, int retain_size, vunits vs, vunits post_vs,
- hunits width);
+ hunits width, int was_centered);
void output_title(node *nd, int retain_size, vunits vs, vunits post_vs,
hunits width);
#ifdef WIDOW_CONTROL
@@ -209,6 +249,11 @@ class environment {
node *make_tab_node(hunits d, node *next = 0);
node *get_prev_char();
public:
+ int seen_space;
+ int seen_eol;
+ int suppress_next_eol;
+ int seen_break;
+ tab_stops tabs;
const symbol name;
unsigned char control_char;
unsigned char no_break_control_char;
@@ -217,14 +262,15 @@ public:
environment(symbol);
environment(const environment *); // for temporary environment
~environment();
+ statem *construct_state(int only_eol);
void copy(const environment *);
int is_dummy() { return dummy; }
int is_empty();
int is_composite() { return composite; }
void set_composite() { composite = 1; }
- vunits get_vertical_spacing(); // .v
- vunits get_post_vertical_spacing(); // .pvs
- int get_line_spacing(); // .L
+ vunits get_vertical_spacing(); // .v
+ vunits get_post_vertical_spacing(); // .pvs
+ int get_line_spacing(); // .L
vunits total_post_vertical_spacing();
int get_point_size() { return size.to_scaled_points(); }
font_size get_font_size() { return size; }
@@ -233,23 +279,23 @@ public:
int get_char_height() { return char_height; }
int get_char_slant() { return char_slant; }
hunits get_digit_width();
- int get_font() { return fontno; }; // .f
+ int get_font() { return fontno; }; // .f
font_family *get_family() { return family; }
- int get_bold(); // .b
- int get_adjust_mode(); // .j
- int get_fill(); // .u
- hunits get_indent(); // .i
+ int get_bold(); // .b
+ int get_adjust_mode(); // .j
+ int get_fill(); // .u
+ hunits get_indent(); // .i
hunits get_temporary_indent();
- hunits get_line_length(); // .l
- hunits get_saved_line_length(); // .ll
- hunits get_saved_indent(); // .in
+ hunits get_line_length(); // .l
+ hunits get_saved_line_length(); // .ll
+ hunits get_saved_indent(); // .in
hunits get_title_length();
- hunits get_prev_char_width(); // .w
+ hunits get_prev_char_width(); // .w
hunits get_prev_char_skew();
vunits get_prev_char_height();
vunits get_prev_char_depth();
- hunits get_text_length(); // .k
- hunits get_prev_text_length(); // .n
+ hunits get_text_length(); // .k
+ hunits get_prev_text_length(); // .n
hunits get_space_width() { return env_space_width(this); }
int get_space_size() { return space_size; } // in ems/36
int get_sentence_space_size() { return sentence_space_size; }
@@ -289,13 +335,9 @@ public:
void possibly_break_line(int start_here = 0, int forced = 0);
void do_break(int spread = 0); // .br
void final_break();
- void add_html_tag(int, const char *);
- void add_html_tag(int, const char *, int);
- void add_html_tag_tabs(int);
- node *make_html_tag(const char *name, int i);
- node *make_html_tag(const char *);
+ node *make_tag(const char *name, int i);
void newline();
- void handle_tab(int is_leader = 0); // do a tab or leader
+ void handle_tab(int is_leader = 0); // do a tab or leader
void add_node(node *);
void add_char(charinfo *);
void add_hyphen_indicator();
@@ -303,12 +345,18 @@ public:
void space();
void space(hunits, hunits);
void space_newline();
+ const char *get_glyph_color_string();
+ const char *get_fill_color_string();
const char *get_font_family_string();
const char *get_font_name_string();
+ const char *get_style_name_string();
const char *get_name_string();
const char *get_point_size_string();
const char *get_requested_point_size_string();
void output_pending_lines();
+ void construct_format_state(node *n, int was_centered, int fill);
+ void construct_new_line_state(node *n);
+ void dump_troff_state();
friend void title_length();
friend void space_size();
@@ -357,7 +405,6 @@ extern void push_env(int);
void init_environments();
void read_hyphen_file(const char *name);
-void title();
extern double spread_limit;
diff --git a/contrib/groff/src/roff/troff/hvunits.h b/contrib/groff/src/roff/troff/hvunits.h
index 8efb5ab..99e6692 100644
--- a/contrib/groff/src/roff/troff/hvunits.h
+++ b/contrib/groff/src/roff/troff/hvunits.h
@@ -16,7 +16,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
class vunits {
diff --git a/contrib/groff/src/roff/troff/input.cpp b/contrib/groff/src/roff/troff/input.cpp
index 55178a2..15077e9 100644
--- a/contrib/groff/src/roff/troff/input.cpp
+++ b/contrib/groff/src/roff/troff/input.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,24 +17,26 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define DEBUGGING
#include "troff.h"
-#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
+#include "stringclass.h"
+#include "mtsm.h"
#include "env.h"
#include "request.h"
#include "node.h"
-#include "reg.h"
#include "token.h"
#include "div.h"
+#include "reg.h"
#include "charinfo.h"
-#include "stringclass.h"
-#include "font.h"
#include "macropath.h"
-#include "defs.h"
#include "input.h"
+#include "defs.h"
+#include "font.h"
#include "unicode.h"
// Needed for getpid() and isatty()
@@ -63,6 +65,7 @@ extern "C" {
// initial size of buffer for reading names; expanded as necessary
#define ABUF_SIZE 16
+extern "C" const char *program_name;
extern "C" const char *Version_string;
#ifdef COLUMN
@@ -71,16 +74,13 @@ void init_column_requests();
static node *read_draw_node();
static void read_color_draw_node(token &);
-void handle_first_page_transition();
static void push_token(const token &);
void copy_file();
#ifdef COLUMN
void vjustify();
#endif /* COLUMN */
void transparent_file();
-void process_input_stack();
-const char *program_name = 0;
token tok;
int break_flag = 0;
int color_flag = 1; // colors are on by default
@@ -105,11 +105,12 @@ static int compatible_flag = 0;
int ascii_output_flag = 0;
int suppress_output_flag = 0;
int is_html = 0;
-int begin_level = 0; // number of nested .begin requests
+int begin_level = 0; // number of nested \O escapes
int have_input = 0; // whether \f, \F, \D'F...', \H, \m, \M,
// \R, \s, or \S has been processed in
// token::next()
+int old_have_input = 0; // value of have_input right before \n
int tcommand_flag = 0;
int safer_flag = 1; // safer by default
@@ -119,9 +120,13 @@ double spread_limit = -3.0 - 1.0; // negative means deactivated
double warn_scale;
char warn_scaling_indicator;
+int debug_state = 0; // turns on debugging of the html troff state
search_path *mac_path = &safer_macro_path;
+// Defaults to the current directory.
+search_path include_search_path(0, 0, 0, 1);
+
static int get_copy(node**, int = 0);
static void copy_mode_error(const char *,
const errarg & = empty_errarg,
@@ -140,19 +145,22 @@ static void interpolate_environment_variable(symbol);
static symbol composite_glyph_name(symbol);
static void interpolate_arg(symbol);
static request_or_macro *lookup_request(symbol);
-static int get_delim_number(units *, int);
-static int get_delim_number(units *, int, units);
+static int get_delim_number(units *, unsigned char);
+static int get_delim_number(units *, unsigned char, units);
static symbol do_get_long_name(int, char);
-static int get_line_arg(units *res, int si, charinfo **cp);
+static int get_line_arg(units *res, unsigned char si, charinfo **cp);
static int read_size(int *);
static symbol get_delim_name();
static void init_registers();
static void trapping_blank_line();
-struct input_iterator;
+class input_iterator;
input_iterator *make_temp_iterator(const char *);
const char *input_char_description(int);
+void process_input_stack();
+void chop_macro(); // declare to avoid friend name injection
+
void set_escape_char()
{
@@ -192,9 +200,12 @@ void restore_escape_char()
class input_iterator {
public:
input_iterator();
+ input_iterator(int is_div);
virtual ~input_iterator() {}
int get(node **);
friend class input_stack;
+ int is_diversion;
+ statem *diversion_state;
protected:
const unsigned char *ptr;
const unsigned char *eptr;
@@ -211,7 +222,6 @@ private:
virtual int next_file(FILE *, const char *) { return 0; }
virtual void shift(int) {}
virtual int is_boundary() {return 0; }
- virtual int internal_level() { return 0; }
virtual int is_file() { return 0; }
virtual int is_macro() { return 0; }
virtual void save_compatible_flag(int) {}
@@ -219,7 +229,12 @@ private:
};
input_iterator::input_iterator()
-: ptr(0), eptr(0)
+: is_diversion(0), ptr(0), eptr(0)
+{
+}
+
+input_iterator::input_iterator(int is_div)
+: is_diversion(is_div), ptr(0), eptr(0)
{
}
@@ -413,16 +428,21 @@ public:
static int is_return_boundary();
static void remove_boundary();
static int get_level();
+ static int get_div_level();
+ static void increase_level();
+ static void decrease_level();
static void clear();
static void pop_macro();
static void save_compatible_flag(int);
static int get_compatible_flag();
-
+ static statem *get_diversion_state();
+ static void check_end_diversion(input_iterator *t);
static int limit;
+ static int div_level;
+ static statem *diversion_state;
private:
static input_iterator *top;
static int level;
-
static int finish_get(node **);
static int finish_peek();
};
@@ -430,17 +450,38 @@ private:
input_iterator *input_stack::top = &nil_iterator;
int input_stack::level = 0;
int input_stack::limit = DEFAULT_INPUT_STACK_LIMIT;
+int input_stack::div_level = 0;
+statem *input_stack::diversion_state = NULL;
+int suppress_push=0;
+
inline int input_stack::get_level()
{
- return level + top->internal_level();
+ return level;
+}
+
+inline void input_stack::increase_level()
+{
+ level++;
+}
+
+inline void input_stack::decrease_level()
+{
+ level--;
+}
+
+inline int input_stack::get_div_level()
+{
+ return div_level;
}
inline int input_stack::get(node **np)
{
int res = (top->ptr < top->eptr) ? *top->ptr++ : finish_get(np);
- if (res == '\n')
+ if (res == '\n') {
+ old_have_input = have_input;
have_input = 0;
+ }
return res;
}
@@ -453,6 +494,13 @@ int input_stack::finish_get(node **np)
if (top == &nil_iterator)
break;
input_iterator *tem = top;
+ check_end_diversion(tem);
+#if defined(DEBUGGING)
+ if (debug_state)
+ if (tem->is_diversion)
+ fprintf(stderr,
+ "in diversion level = %d\n", input_stack::get_div_level());
+#endif
top = top->next;
level--;
delete tem;
@@ -468,6 +516,14 @@ inline int input_stack::peek()
return (top->ptr < top->eptr) ? *top->ptr : finish_peek();
}
+void input_stack::check_end_diversion(input_iterator *t)
+{
+ if (t->is_diversion) {
+ div_level--;
+ diversion_state = t->diversion_state;
+ }
+}
+
int input_stack::finish_peek()
{
for (;;) {
@@ -477,6 +533,7 @@ int input_stack::finish_peek()
if (top == &nil_iterator)
break;
input_iterator *tem = top;
+ check_end_diversion(tem);
top = top->next;
level--;
delete tem;
@@ -506,6 +563,8 @@ void input_stack::remove_boundary()
{
assert(top->is_boundary());
input_iterator *temp = top->next;
+ check_end_diversion(top);
+
delete top;
top = temp;
level--;
@@ -519,6 +578,38 @@ void input_stack::push(input_iterator *in)
fatal("input stack limit exceeded (probable infinite loop)");
in->next = top;
top = in;
+ if (top->is_diversion) {
+ div_level++;
+ in->diversion_state = diversion_state;
+ diversion_state = curenv->construct_state(0);
+#if defined(DEBUGGING)
+ if (debug_state) {
+ curenv->dump_troff_state();
+ fflush(stderr);
+ }
+#endif
+ }
+#if defined(DEBUGGING)
+ if (debug_state)
+ if (top->is_diversion) {
+ fprintf(stderr,
+ "in diversion level = %d\n", input_stack::get_div_level());
+ fflush(stderr);
+ }
+#endif
+}
+
+statem *get_diversion_state()
+{
+ return input_stack::get_diversion_state();
+}
+
+statem *input_stack::get_diversion_state()
+{
+ if (diversion_state == NULL)
+ return NULL;
+ else
+ return new statem(diversion_state);
}
input_iterator *input_stack::get_arg(int i)
@@ -597,6 +688,7 @@ void input_stack::end_file()
for (input_iterator **pp = &top; *pp != &nil_iterator; pp = &(*pp)->next)
if ((*pp)->is_file()) {
input_iterator *tem = *pp;
+ check_end_diversion(tem);
*pp = (*pp)->next;
delete tem;
level--;
@@ -611,6 +703,7 @@ void input_stack::clear()
if (top->is_boundary())
nboundaries++;
input_iterator *tem = top;
+ check_end_diversion(tem);
top = top->next;
level--;
delete tem;
@@ -631,6 +724,7 @@ void input_stack::pop_macro()
nboundaries++;
is_macro = top->is_macro();
input_iterator *tem = top;
+ check_end_diversion(tem);
top = top->next;
level--;
delete tem;
@@ -666,7 +760,7 @@ void next_file()
input_stack::end_file();
else {
errno = 0;
- FILE *fp = fopen(nm.contents(), "r");
+ FILE *fp = include_search_path.open_file_cautious(nm.contents());
if (!fp)
error("can't open `%1': %2", nm.contents(), strerror(errno));
else
@@ -684,7 +778,7 @@ void shift()
skip_line();
}
-static int get_char_for_escape_name(int allow_space = 0)
+static char get_char_for_escape_name(int allow_space = 0)
{
int c = get_copy(0);
switch (c) {
@@ -734,7 +828,7 @@ static symbol read_long_escape_name(read_mode mode)
char *buf = abuf;
int buf_size = ABUF_SIZE;
int i = 0;
- int c;
+ char c;
int have_char = 0;
for (;;) {
c = get_char_for_escape_name(have_char && mode == WITH_ARGS);
@@ -784,7 +878,7 @@ static symbol read_long_escape_name(read_mode mode)
static symbol read_escape_name(read_mode mode)
{
- int c = get_char_for_escape_name();
+ char c = get_char_for_escape_name();
if (c == 0)
return NULL_SYMBOL;
if (c == '(')
@@ -799,7 +893,7 @@ static symbol read_escape_name(read_mode mode)
static symbol read_increment_and_escape_name(int *incp)
{
- int c = get_char_for_escape_name();
+ char c = get_char_for_escape_name();
switch (c) {
case 0:
*incp = 0;
@@ -831,6 +925,28 @@ static int get_copy(node **nd, int defining)
{
for (;;) {
int c = input_stack::get(nd);
+ if (c == PUSH_GROFF_MODE) {
+ input_stack::save_compatible_flag(compatible_flag);
+ compatible_flag = 0;
+ continue;
+ }
+ if (c == PUSH_COMP_MODE) {
+ input_stack::save_compatible_flag(compatible_flag);
+ compatible_flag = 1;
+ continue;
+ }
+ if (c == POP_GROFFCOMP_MODE) {
+ compatible_flag = input_stack::get_compatible_flag();
+ continue;
+ }
+ if (c == BEGIN_QUOTE) {
+ input_stack::increase_level();
+ continue;
+ }
+ if (c == END_QUOTE) {
+ input_stack::decrease_level();
+ continue;
+ }
if (c == ESCAPE_NEWLINE) {
if (defining)
return c;
@@ -993,6 +1109,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
int non_interpreted_char_node::same(node *nd)
@@ -1010,6 +1127,11 @@ int non_interpreted_char_node::force_tprint()
return 0;
}
+int non_interpreted_char_node::is_tag()
+{
+ return 0;
+}
+
non_interpreted_char_node::non_interpreted_char_node(unsigned char n) : c(n)
{
assert(n != 0);
@@ -1033,7 +1155,6 @@ static node *do_suppress(symbol nm);
static void do_register();
dictionary color_dictionary(501);
-static symbol default_symbol("default");
static color *lookup_color(symbol nm)
{
@@ -1057,7 +1178,7 @@ void do_glyph_color(symbol nm)
if (tem)
curenv->set_glyph_color(tem);
else
- (void)color_dictionary.lookup(nm, new color);
+ (void)color_dictionary.lookup(nm, new color(nm));
}
}
@@ -1072,7 +1193,7 @@ void do_fill_color(symbol nm)
if (tem)
curenv->set_fill_color(tem);
else
- (void)color_dictionary.lookup(nm, new color);
+ (void)color_dictionary.lookup(nm, new color(nm));
}
}
@@ -1256,8 +1377,10 @@ static void define_color()
skip_line();
return;
}
- if (col)
+ if (col) {
+ col->nm = color_name;
(void)color_dictionary.lookup(color_name, col);
+ }
skip_line();
}
@@ -1456,6 +1579,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
token_node::token_node(const token &t) : tk(t)
@@ -1487,6 +1611,11 @@ int token_node::force_tprint()
return 0;
}
+int token_node::is_tag()
+{
+ return 0;
+}
+
token::token() : nd(0), type(TOKEN_EMPTY)
{
}
@@ -1548,18 +1677,28 @@ void token::next()
}
units x;
for (;;) {
- node *n;
+ node *n = 0;
int cc = input_stack::get(&n);
if (cc != escape_char || escape_char == 0) {
handle_normal_char:
switch(cc) {
- case COMPATIBLE_SAVE:
+ case PUSH_GROFF_MODE:
input_stack::save_compatible_flag(compatible_flag);
compatible_flag = 0;
continue;
- case COMPATIBLE_RESTORE:
+ case PUSH_COMP_MODE:
+ input_stack::save_compatible_flag(compatible_flag);
+ compatible_flag = 1;
+ continue;
+ case POP_GROFFCOMP_MODE:
compatible_flag = input_stack::get_compatible_flag();
continue;
+ case BEGIN_QUOTE:
+ input_stack::increase_level();
+ continue;
+ case END_QUOTE:
+ input_stack::decrease_level();
+ continue;
case EOF:
type = TOKEN_EOF;
return;
@@ -1710,7 +1849,7 @@ void token::next()
}
else {
handle_escape_char:
- cc = input_stack::get(0);
+ cc = input_stack::get(&n);
switch(cc) {
case '(':
nm = read_two_char_escape_name();
@@ -1904,11 +2043,11 @@ void token::next()
if (s == 0)
s = get_charinfo(cc == 'l' ? "ru" : "br");
type = TOKEN_NODE;
- node *n = curenv->make_char_node(s);
+ node *char_node = curenv->make_char_node(s);
if (cc == 'l')
- nd = new hline_node(x, n);
+ nd = new hline_node(x, char_node);
else
- nd = new vline_node(x, n);
+ nd = new vline_node(x, char_node);
return;
}
case 'm':
@@ -2398,6 +2537,8 @@ void exit_request()
void return_macro_request()
{
+ if (has_arg() && tok.ch())
+ input_stack::pop_macro();
input_stack::pop_macro();
tok.next();
}
@@ -2528,12 +2669,16 @@ int node::reread(int *)
return 0;
}
+int global_diverted_space = 0;
+
int diverted_space_node::reread(int *bolp)
{
+ global_diverted_space = 1;
if (curenv->get_fill())
trapping_blank_line();
else
curdiv->space(n);
+ global_diverted_space = 0;
*bolp = 1;
return 1;
}
@@ -2590,10 +2735,33 @@ void process_input_stack()
tok.next();
} while (tok.white_space());
symbol nm = get_name();
+#if defined(DEBUGGING)
+ if (debug_state) {
+ if (! nm.is_null()) {
+ if (strcmp(nm.contents(), "test") == 0) {
+ fprintf(stderr, "found it!\n");
+ fflush(stderr);
+ }
+ fprintf(stderr, "interpreting [%s]", nm.contents());
+ if (strcmp(nm.contents(), "di") == 0 && topdiv != curdiv)
+ fprintf(stderr, " currently in diversion: %s",
+ curdiv->get_diversion_name());
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ }
+ }
+#endif
if (nm.is_null())
skip_line();
- else
+ else {
interpolate_macro(nm);
+#if defined(DEBUGGING)
+ if (debug_state) {
+ fprintf(stderr, "finished interpreting [%s] and environment state is\n", nm.contents());
+ curenv->dump_troff_state();
+ }
+#endif
+ }
suppress_next = 1;
}
else {
@@ -2601,6 +2769,11 @@ void process_input_stack()
;
else {
for (;;) {
+#if defined(DEBUGGING)
+ if (debug_state) {
+ fprintf(stderr, "found [%c]\n", ch); fflush(stderr);
+ }
+#endif
curenv->add_char(charset_table[ch]);
tok.next();
if (tok.type != token::TOKEN_CHAR)
@@ -2637,7 +2810,7 @@ void process_input_stack()
}
case token::TOKEN_NEWLINE:
{
- if (bol && !have_input
+ if (bol && !old_have_input
&& !curenv->get_prev_line_interrupted())
trapping_blank_line();
else {
@@ -2962,7 +3135,7 @@ node_list::~node_list()
delete_node_list(head);
}
-struct macro_header {
+class macro_header {
public:
int count;
char_list cl;
@@ -2978,6 +3151,7 @@ macro::~macro()
}
macro::macro()
+: is_a_diversion(0)
{
if (!input_stack::get_location(1, &filename, &lineno)) {
filename = 0;
@@ -2989,13 +3163,30 @@ macro::macro()
}
macro::macro(const macro &m)
-: p(m.p), filename(m.filename), lineno(m.lineno), len(m.len),
- empty_macro(m.empty_macro)
+: filename(m.filename), lineno(m.lineno), len(m.len),
+ empty_macro(m.empty_macro), is_a_diversion(m.is_a_diversion), p(m.p)
{
if (p != 0)
p->count++;
}
+macro::macro(int is_div)
+ : is_a_diversion(is_div)
+{
+ if (!input_stack::get_location(1, &filename, &lineno)) {
+ filename = 0;
+ lineno = 0;
+ }
+ len = 0;
+ empty_macro = 1;
+ p = 0;
+}
+
+int macro::is_diversion()
+{
+ return is_a_diversion;
+}
+
macro &macro::operator=(const macro &m)
{
// don't assign object
@@ -3008,6 +3199,7 @@ macro &macro::operator=(const macro &m)
lineno = m.lineno;
len = m.len;
empty_macro = m.empty_macro;
+ is_a_diversion = m.is_a_diversion;
return *this;
}
@@ -3024,7 +3216,7 @@ void macro::append(unsigned char c)
}
p->cl.append(c);
++len;
- if (c != COMPATIBLE_SAVE && c != COMPATIBLE_RESTORE)
+ if (c != PUSH_GROFF_MODE && c != PUSH_COMP_MODE && c != POP_GROFFCOMP_MODE)
empty_macro = 0;
}
@@ -3110,7 +3302,7 @@ macro_header *macro_header::copy(int n)
bp = bp->next;
ptr = bp->s;
}
- int c = *ptr++;
+ unsigned char c = *ptr++;
p->cl.append(c);
if (c == 0) {
p->nl.append(nd->copy());
@@ -3158,11 +3350,12 @@ public:
void backtrace();
void save_compatible_flag(int f) { saved_compatible_flag = f; }
int get_compatible_flag() { return saved_compatible_flag; }
+ int is_diversion();
};
string_iterator::string_iterator(const macro &m, const char *p, symbol s)
-: mac(m), how_invoked(p),
- newline_flag(0), lineno(1), nm(s)
+: input_iterator(m.is_a_diversion), mac(m), how_invoked(p), newline_flag(0),
+ lineno(1), nm(s)
{
count = mac.len;
if (count != 0) {
@@ -3188,6 +3381,11 @@ string_iterator::string_iterator()
count = 0;
}
+int string_iterator::is_diversion()
+{
+ return mac.is_diversion();
+}
+
int string_iterator::fill(node **np)
{
if (newline_flag)
@@ -3201,8 +3399,13 @@ int string_iterator::fill(node **np)
p = bp->s;
}
if (*p == '\0') {
- if (np)
+ if (np) {
*np = nd->copy();
+ if (is_diversion())
+ (*np)->div_nest_level = input_stack::get_div_level();
+ else
+ (*np)->div_nest_level = 0;
+ }
nd = nd->next;
eptr = ptr = p + 1;
count--;
@@ -3390,6 +3593,7 @@ public:
void add_arg(const macro &m);
void shift(int n);
int is_macro() { return 1; }
+ int is_diversion();
};
input_iterator *macro_iterator::get_arg(int i)
@@ -3513,12 +3717,13 @@ static void decode_args(macro_iterator *mi)
macro arg;
int quote_input_level = 0;
int done_tab_warning = 0;
- if (c == '\"') {
+ if (c == '"') {
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 == '\"'
+ if (quote_input_level > 0 && c == '"'
&& (compatible_flag
|| input_stack::get_level() == quote_input_level)) {
c = get_copy(&n);
@@ -3542,6 +3747,7 @@ static void decode_args(macro_iterator *mi)
c = get_copy(&n);
}
}
+ arg.append(POP_GROFFCOMP_MODE);
mi->add_arg(arg);
}
}
@@ -3563,14 +3769,14 @@ static void decode_string_args(macro_iterator *mi)
macro arg;
int quote_input_level = 0;
int done_tab_warning = 0;
- if (c == '\"') {
+ if (c == '"') {
quote_input_level = input_stack::get_level();
c = get_copy(&n);
}
while (c != EOF && c != '\n'
&& !(c == ']' && quote_input_level == 0)
&& !(c == ' ' && quote_input_level == 0)) {
- if (quote_input_level > 0 && c == '\"'
+ if (quote_input_level > 0 && c == '"'
&& input_stack::get_level() == quote_input_level) {
c = get_copy(&n);
if (c == '"') {
@@ -3615,8 +3821,8 @@ int macro::empty()
return empty_macro == 1;
}
-macro_iterator::macro_iterator(symbol s, macro &m, const char *how_invoked)
-: string_iterator(m, how_invoked, s), args(0), argc(0)
+macro_iterator::macro_iterator(symbol s, macro &m, const char *how_called)
+: string_iterator(m, how_called, s), args(0), argc(0)
{
}
@@ -3821,12 +4027,13 @@ void read_request()
}
enum define_mode { DEFINE_NORMAL, DEFINE_APPEND, DEFINE_IGNORE };
-enum calling_mode { CALLING_NORMAL, CALLING_INDIRECT, CALLING_DISABLE_COMP };
+enum calling_mode { CALLING_NORMAL, CALLING_INDIRECT };
+enum comp_mode { COMP_IGNORE, COMP_DISABLE, COMP_ENABLE };
-void do_define_string(define_mode mode, calling_mode calling)
+void do_define_string(define_mode mode, comp_mode comp)
{
symbol nm;
- node *n;
+ node *n = 0; // pacify compiler
int c;
nm = get_name(1);
if (nm.is_null()) {
@@ -3853,8 +4060,10 @@ void do_define_string(define_mode mode, calling_mode calling)
macro *mm = rm ? rm->to_macro() : 0;
if (mode == DEFINE_APPEND && mm)
mac = *mm;
- if (calling == CALLING_DISABLE_COMP)
- mac.append(COMPATIBLE_SAVE);
+ if (comp == COMP_DISABLE)
+ mac.append(PUSH_GROFF_MODE);
+ else if (comp == COMP_ENABLE)
+ mac.append(PUSH_COMP_MODE);
while (c != '\n' && c != EOF) {
if (c == 0)
mac.append(n);
@@ -3866,35 +4075,37 @@ void do_define_string(define_mode mode, calling_mode calling)
mm = new macro;
request_dictionary.define(nm, mm);
}
- if (calling == CALLING_DISABLE_COMP)
- mac.append(COMPATIBLE_RESTORE);
+ if (comp == COMP_DISABLE || comp == COMP_ENABLE)
+ mac.append(POP_GROFFCOMP_MODE);
*mm = mac;
tok.next();
}
void define_string()
{
- do_define_string(DEFINE_NORMAL, CALLING_NORMAL);
+ do_define_string(DEFINE_NORMAL,
+ compatible_flag ? COMP_ENABLE: COMP_IGNORE);
}
void define_nocomp_string()
{
- do_define_string(DEFINE_NORMAL, CALLING_DISABLE_COMP);
+ do_define_string(DEFINE_NORMAL, COMP_DISABLE);
}
void append_string()
{
- do_define_string(DEFINE_APPEND, CALLING_NORMAL);
+ do_define_string(DEFINE_APPEND,
+ compatible_flag ? COMP_ENABLE : COMP_IGNORE);
}
void append_nocomp_string()
{
- do_define_string(DEFINE_APPEND, CALLING_DISABLE_COMP);
+ do_define_string(DEFINE_APPEND, COMP_DISABLE);
}
void do_define_character(char_mode mode, const char *font_name)
{
- node *n;
+ node *n = 0; // pacify compiler
int c;
tok.skip();
charinfo *ci = tok.get_char(1);
@@ -3996,26 +4207,6 @@ static void interpolate_string_with_args(symbol s)
}
}
-/* This class is used for the implementation of \$@. It is used for
-each of the closing double quotes. It artificially increases the
-input level by 2, so that the closing double quote will appear to have
-the same input level as the opening quote. */
-
-class end_quote_iterator : public input_iterator {
- unsigned char buf[1];
-public:
- end_quote_iterator();
- ~end_quote_iterator() { }
- int internal_level() { return 2; }
-};
-
-end_quote_iterator::end_quote_iterator()
-{
- buf[0] = '"';
- ptr = buf;
- eptr = buf + 1;
-}
-
static void interpolate_arg(symbol nm)
{
const char *s = nm.contents();
@@ -4024,17 +4215,39 @@ static void interpolate_arg(symbol nm)
else if (s[1] == 0 && csdigit(s[0]))
input_stack::push(input_stack::get_arg(s[0] - '0'));
else if (s[0] == '*' && s[1] == '\0') {
- for (int i = input_stack::nargs(); i > 0; i--) {
- input_stack::push(input_stack::get_arg(i));
- if (i != 1)
- input_stack::push(make_temp_iterator(" "));
+ int limit = input_stack::nargs();
+ string args;
+ for (int i = 1; i <= limit; i++) {
+ input_iterator *p = input_stack::get_arg(i);
+ int c;
+ while ((c = p->get(0)) != EOF)
+ args += c;
+ if (i != limit)
+ args += ' ';
+ }
+ if (limit > 0) {
+ args += '\0';
+ input_stack::push(make_temp_iterator(args.contents()));
}
}
else if (s[0] == '@' && s[1] == '\0') {
- for (int i = input_stack::nargs(); i > 0; i--) {
- input_stack::push(new end_quote_iterator);
- input_stack::push(input_stack::get_arg(i));
- input_stack::push(make_temp_iterator(i == 1 ? "\"" : " \""));
+ int limit = input_stack::nargs();
+ string args;
+ for (int i = 1; i <= limit; i++) {
+ args += '"';
+ args += BEGIN_QUOTE;
+ input_iterator *p = input_stack::get_arg(i);
+ int c;
+ while ((c = p->get(0)) != EOF)
+ args += c;
+ args += END_QUOTE;
+ args += '"';
+ if (i != limit)
+ args += ' ';
+ }
+ if (limit > 0) {
+ args += '\0';
+ input_stack::push(make_temp_iterator(args.contents()));
}
}
else {
@@ -4091,7 +4304,7 @@ void handle_initial_title()
// this should be local to define_macro, but cfront 1.2 doesn't support that
static symbol dot_symbol(".");
-void do_define_macro(define_mode mode, calling_mode calling)
+void do_define_macro(define_mode mode, calling_mode calling, comp_mode comp)
{
symbol nm, term;
if (calling == CALLING_INDIRECT) {
@@ -4140,8 +4353,10 @@ void do_define_macro(define_mode mode, calling_mode calling)
mac = *mm;
}
int bol = 1;
- if (calling == CALLING_DISABLE_COMP)
- mac.append(COMPATIBLE_SAVE);
+ if (comp == COMP_DISABLE)
+ mac.append(PUSH_GROFF_MODE);
+ else if (comp == COMP_ENABLE)
+ mac.append(PUSH_COMP_MODE);
for (;;) {
while (c == ESCAPE_NEWLINE) {
if (mode == DEFINE_NORMAL || mode == DEFINE_APPEND)
@@ -4177,8 +4392,8 @@ void do_define_macro(define_mode mode, calling_mode calling)
mm = new macro;
request_dictionary.define(nm, mm);
}
- if (calling == CALLING_DISABLE_COMP)
- mac.append(COMPATIBLE_RESTORE);
+ if (comp == COMP_DISABLE || comp == COMP_ENABLE)
+ mac.append(POP_GROFFCOMP_MODE);
*mm = mac;
}
if (term != dot_symbol) {
@@ -4228,38 +4443,52 @@ void do_define_macro(define_mode mode, calling_mode calling)
void define_macro()
{
- do_define_macro(DEFINE_NORMAL, CALLING_NORMAL);
+ do_define_macro(DEFINE_NORMAL, CALLING_NORMAL,
+ compatible_flag ? COMP_ENABLE : COMP_IGNORE);
}
void define_nocomp_macro()
{
- do_define_macro(DEFINE_NORMAL, CALLING_DISABLE_COMP);
+ do_define_macro(DEFINE_NORMAL, CALLING_NORMAL, COMP_DISABLE);
}
void define_indirect_macro()
{
- do_define_macro(DEFINE_NORMAL, CALLING_INDIRECT);
+ do_define_macro(DEFINE_NORMAL, CALLING_INDIRECT,
+ compatible_flag ? COMP_ENABLE : COMP_IGNORE);
+}
+
+void define_indirect_nocomp_macro()
+{
+ do_define_macro(DEFINE_NORMAL, CALLING_INDIRECT, COMP_DISABLE);
}
void append_macro()
{
- do_define_macro(DEFINE_APPEND, CALLING_NORMAL);
+ do_define_macro(DEFINE_APPEND, CALLING_NORMAL,
+ compatible_flag ? COMP_ENABLE : COMP_IGNORE);
+}
+
+void append_nocomp_macro()
+{
+ do_define_macro(DEFINE_APPEND, CALLING_NORMAL, COMP_DISABLE);
}
void append_indirect_macro()
{
- do_define_macro(DEFINE_APPEND, CALLING_INDIRECT);
+ do_define_macro(DEFINE_APPEND, CALLING_INDIRECT,
+ compatible_flag ? COMP_ENABLE : COMP_IGNORE);
}
-void append_nocomp_macro()
+void append_indirect_nocomp_macro()
{
- do_define_macro(DEFINE_APPEND, CALLING_DISABLE_COMP);
+ do_define_macro(DEFINE_APPEND, CALLING_INDIRECT, COMP_DISABLE);
}
void ignore()
{
ignoring = 1;
- do_define_macro(DEFINE_IGNORE, CALLING_NORMAL);
+ do_define_macro(DEFINE_IGNORE, CALLING_NORMAL, COMP_IGNORE);
ignoring = 0;
}
@@ -4313,11 +4542,12 @@ void chop_macro()
// we have to check for additional save/restore pairs which could be
// there due to empty am1 requests.
for (;;) {
- if (m->get(m->len - 1) != COMPATIBLE_RESTORE)
+ if (m->get(m->len - 1) != POP_GROFFCOMP_MODE)
break;
have_restore = 1;
m->len -= 1;
- if (m->get(m->len - 1) != COMPATIBLE_SAVE)
+ if (m->get(m->len - 1) != PUSH_GROFF_MODE
+ && m->get(m->len - 1) != PUSH_COMP_MODE)
break;
have_restore = 0;
m->len -= 1;
@@ -4328,7 +4558,7 @@ void chop_macro()
error("cannot chop empty macro");
else {
if (have_restore)
- m->set(COMPATIBLE_RESTORE, m->len - 1);
+ m->set(POP_GROFFCOMP_MODE, m->len - 1);
else
m->len -= 1;
}
@@ -4353,7 +4583,9 @@ void substring_request()
string_iterator iter1(*m);
for (int l = 0; l < m->len; l++) {
int c = iter1.get(0);
- if (c == COMPATIBLE_SAVE || c == COMPATIBLE_RESTORE)
+ if (c == PUSH_GROFF_MODE
+ || c == PUSH_COMP_MODE
+ || c == POP_GROFFCOMP_MODE)
continue;
if (c == EOF)
break;
@@ -4395,16 +4627,20 @@ void substring_request()
int i;
for (i = 0; i < start; i++) {
int c = iter.get(0);
- while (c == COMPATIBLE_SAVE || c == COMPATIBLE_RESTORE)
+ while (c == PUSH_GROFF_MODE
+ || c == PUSH_COMP_MODE
+ || c == POP_GROFFCOMP_MODE)
c = iter.get(0);
if (c == EOF)
break;
}
macro mac;
for (; i <= end; i++) {
- node *nd;
+ node *nd = 0; // pacify compiler
int c = iter.get(&nd);
- while (c == COMPATIBLE_SAVE || c == COMPATIBLE_RESTORE)
+ while (c == PUSH_GROFF_MODE
+ || c == PUSH_COMP_MODE
+ || c == POP_GROFFCOMP_MODE)
c = iter.get(0);
if (c == EOF)
break;
@@ -4470,7 +4706,7 @@ void asciify_macro()
macro am;
string_iterator iter(*m);
for (;;) {
- node *nd;
+ node *nd = 0; // pacify compiler
int c = iter.get(&nd);
if (c == EOF)
break;
@@ -4497,7 +4733,7 @@ void unformat_macro()
macro am;
string_iterator iter(*m);
for (;;) {
- node *nd;
+ node *nd = 0; // pacify compiler
int c = iter.get(&nd);
if (c == EOF)
break;
@@ -4538,7 +4774,7 @@ static void interpolate_number_format(symbol nm)
input_stack::push(make_temp_iterator(r->get_format()));
}
-static int get_delim_number(units *n, int si, int prev_value)
+static int get_delim_number(units *n, unsigned char si, int prev_value)
{
token start;
start.next();
@@ -4553,7 +4789,7 @@ static int get_delim_number(units *n, int si, int prev_value)
return 0;
}
-static int get_delim_number(units *n, int si)
+static int get_delim_number(units *n, unsigned char si)
{
token start;
start.next();
@@ -4568,7 +4804,7 @@ static int get_delim_number(units *n, int si)
return 0;
}
-static int get_line_arg(units *n, int si, charinfo **cp)
+static int get_line_arg(units *n, unsigned char si, charinfo **cp)
{
token start;
start.next();
@@ -4605,7 +4841,7 @@ static int read_size(int *x)
tok.next();
c = tok.ch();
}
- int val;
+ int val = 0; // pacify compiler
int bad = 0;
if (c == '(') {
tok.next();
@@ -4866,15 +5102,22 @@ public:
non_interpreted_node(const macro &);
int interpret(macro *);
node *copy();
+ int ends_sentence();
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
non_interpreted_node::non_interpreted_node(const macro &m) : mac(m)
{
}
+int non_interpreted_node::ends_sentence()
+{
+ return 2;
+}
+
int non_interpreted_node::same(node *nd)
{
return mac == ((non_interpreted_node *)nd)->mac;
@@ -4890,6 +5133,11 @@ int non_interpreted_node::force_tprint()
return 0;
}
+int non_interpreted_node::is_tag()
+{
+ return 0;
+}
+
node *non_interpreted_node::copy()
{
return new non_interpreted_node(mac);
@@ -4898,7 +5146,7 @@ node *non_interpreted_node::copy()
int non_interpreted_node::interpret(macro *m)
{
string_iterator si(mac);
- node *n;
+ node *n = 0; // pacify compiler
for (;;) {
int c = si.get(&n);
if (c == EOF)
@@ -5247,6 +5495,24 @@ int do_if_request()
result = character_exists(ci, curenv);
tok.next();
}
+ else if (c == 'F') {
+ tok.next();
+ symbol nm = get_long_name(1);
+ if (nm.is_null()) {
+ skip_alternative();
+ return 0;
+ }
+ result = check_font(curenv->get_family()->nm, nm);
+ }
+ else if (c == 'S') {
+ tok.next();
+ symbol nm = get_long_name(1);
+ if (nm.is_null()) {
+ skip_alternative();
+ return 0;
+ }
+ result = check_style(nm);
+ }
else if (tok.space())
result = 0;
else if (tok.delimiter()) {
@@ -5256,6 +5522,7 @@ int do_if_request()
environment env2(curenv);
environment *oldenv = curenv;
curenv = &env1;
+ suppress_push = 1;
for (int i = 0; i < 2; i++) {
for (;;) {
tok.next();
@@ -5279,6 +5546,7 @@ int do_if_request()
delete_node_list(n2);
curenv = oldenv;
have_input = 0;
+ suppress_push = 0;
tok.next();
}
else {
@@ -5333,7 +5601,7 @@ void while_request()
int level = 0;
mac.append(new token_node(tok));
for (;;) {
- node *n;
+ node *n = 0; // pacify compiler
int c = input_stack::get(&n);
if (c == EOF)
break;
@@ -5424,7 +5692,7 @@ void source()
while (!tok.newline() && !tok.eof())
tok.next();
errno = 0;
- FILE *fp = fopen(nm.contents(), "r");
+ FILE *fp = include_search_path.open_file_cautious(nm.contents());
if (fp)
input_stack::push(new file_iterator(fp, nm.contents()));
else
@@ -5663,7 +5931,8 @@ void ps_bbox_request()
errno = 0;
// PS files might contain non-printable characters, such as ^Z
// and CRs not followed by an LF, so open them in binary mode.
- FILE *fp = fopen(nm.contents(), FOPEN_RB);
+ FILE *fp = include_search_path.open_file_cautious(nm.contents(),
+ 0, FOPEN_RB);
if (fp) {
do_ps_file(fp, nm.contents());
fclose(fp);
@@ -5737,8 +6006,9 @@ const char *asciify(int c)
case ESCAPE_COLON:
buf[1] = ':';
break;
- case COMPATIBLE_SAVE:
- case COMPATIBLE_RESTORE:
+ case PUSH_GROFF_MODE:
+ case PUSH_COMP_MODE:
+ case POP_GROFFCOMP_MODE:
buf[0] = '\0';
break;
default:
@@ -5789,6 +6059,52 @@ const char *input_char_description(int c)
return buf;
}
+void tag()
+{
+ if (!tok.newline() && !tok.eof()) {
+ string s;
+ int c;
+ for (;;) {
+ c = get_copy(0);
+ if (c == '"') {
+ c = get_copy(0);
+ break;
+ }
+ if (c != ' ' && c != '\t')
+ break;
+ }
+ s = "x X ";
+ for (; c != '\n' && c != EOF; c = get_copy(0))
+ s += (char)c;
+ s += '\n';
+ curenv->add_node(new tag_node(s, 0));
+ }
+ tok.next();
+}
+
+void taga()
+{
+ if (!tok.newline() && !tok.eof()) {
+ string s;
+ int c;
+ for (;;) {
+ c = get_copy(0);
+ if (c == '"') {
+ c = get_copy(0);
+ break;
+ }
+ if (c != ' ' && c != '\t')
+ break;
+ }
+ s = "x X ";
+ for (; c != '\n' && c != EOF; c = get_copy(0))
+ s += (char)c;
+ s += '\n';
+ curenv->add_node(new tag_node(s, 1));
+ }
+ tok.next();
+}
+
// .tm, .tm1, and .tmc
void do_terminal(int newline, int string_like)
@@ -6630,7 +6946,7 @@ void transparent_file()
curenv->do_break();
if (!filename.is_null()) {
errno = 0;
- FILE *fp = fopen(filename.contents(), "r");
+ FILE *fp = include_search_path.open_file_cautious(filename.contents());
if (!fp)
error("can't open `%1': %2", filename.contents(), strerror(errno));
else {
@@ -6824,7 +7140,7 @@ static void process_input_file(const char *name)
}
else {
errno = 0;
- fp = fopen(name, "r");
+ fp = include_search_path.open_file_cautious(name);
if (!fp)
fatal("can't open `%1': %2", name, strerror(errno));
}
@@ -6920,7 +7236,7 @@ void usage(FILE *stream, const char *prog)
{
fprintf(stream,
"usage: %s -abcivzCERU -wname -Wname -dcs -ffam -mname -nnum -olist\n"
-" -rcn -Tname -Fdir -Mdir [files...]\n",
+" -rcn -Tname -Fdir -Idir -Mdir [files...]\n",
prog);
}
@@ -6938,7 +7254,7 @@ int main(int argc, char **argv)
int fflag = 0;
int nflag = 0;
int no_rc = 0; // don't process troffrc and troffrc-end
- int next_page_number;
+ int next_page_number = 0; // pacify compiler
opterr = 0;
hresolution = vresolution = 1;
// restore $PATH if called from groff
@@ -6957,8 +7273,12 @@ int main(int argc, char **argv)
{ "version", no_argument, 0, 'v' },
{ 0, 0, 0, 0 }
};
- while ((c = getopt_long(argc, argv, "abcivw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU",
- long_options, 0))
+#if defined(DEBUGGING)
+#define DEBUG_OPTION "D"
+#endif
+ while ((c = getopt_long(argc, argv,
+ "abciI:vw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU"
+ DEBUG_OPTION, long_options, 0))
!= EOF)
switch(c) {
case 'v':
@@ -6967,6 +7287,11 @@ int main(int argc, char **argv)
exit(0);
break;
}
+ case 'I':
+ // Search path for .psbb files
+ // and most other non-system input files.
+ include_search_path.command_line_dir(optarg);
+ break;
case 'T':
device = optarg;
tflag = 1;
@@ -7046,6 +7371,11 @@ int main(int argc, char **argv)
case 'U':
safer_flag = 0; // unsafe behaviour
break;
+#if defined(DEBUGGING)
+ case 'D':
+ debug_state = 1;
+ break;
+#endif
case CHAR_MAX + 1: // --help
usage(stdout, argv[0]);
exit(0);
@@ -7214,6 +7544,7 @@ void init_input_requests()
init_request("am", append_macro);
init_request("am1", append_nocomp_macro);
init_request("ami", append_indirect_macro);
+ init_request("ami1", append_indirect_nocomp_macro);
init_request("as", append_string);
init_request("as1", append_nocomp_string);
init_request("asciify", asciify_macro);
@@ -7233,6 +7564,7 @@ void init_input_requests()
init_request("de1", define_nocomp_macro);
init_request("defcolor", define_color);
init_request("dei", define_indirect_macro);
+ init_request("dei1", define_indirect_nocomp_macro);
init_request("do", do_request);
init_request("ds", define_string);
init_request("ds1", define_nocomp_string);
@@ -7279,6 +7611,8 @@ void init_input_requests()
init_request("spreadwarn", spreadwarn_request);
init_request("substring", substring_request);
init_request("sy", system_request);
+ init_request("tag", tag);
+ init_request("taga", taga);
init_request("tm", terminal);
init_request("tm1", terminal1);
init_request("tmc", terminal_continue);
@@ -7305,6 +7639,7 @@ void init_input_requests()
number_reg_dictionary.define(".g", new constant_reg("1"));
number_reg_dictionary.define(".H", new constant_int_reg(&hresolution));
number_reg_dictionary.define(".R", new constant_reg("10000"));
+ number_reg_dictionary.define(".U", new constant_int_reg(&safer_flag));
number_reg_dictionary.define(".V", new constant_int_reg(&vresolution));
number_reg_dictionary.define(".warn", new constant_int_reg(&warning_mask));
extern const char *major_version;
@@ -7514,7 +7849,7 @@ static void read_color_draw_node(token &start)
}
unsigned char scheme = tok.ch();
tok.next();
- color *col;
+ color *col = 0;
char end = start.ch();
switch (scheme) {
case 'c':
diff --git a/contrib/groff/src/roff/troff/input.h b/contrib/groff/src/roff/troff/input.h
index 8d06574..ba6e2e1 100644
--- a/contrib/groff/src/roff/troff/input.h
+++ b/contrib/groff/src/roff/troff/input.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
This file is part of groff.
@@ -16,7 +16,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
/* special character codes */
@@ -54,8 +54,11 @@ const int LAST_PAGE_EJECTOR = 0205;
const int ESCAPE_RIGHT_PARENTHESIS = 0206;
const int ESCAPE_TILDE = 0207;
const int ESCAPE_COLON = 0210;
-const int COMPATIBLE_SAVE = 0211;
-const int COMPATIBLE_RESTORE = 0212;
+const int PUSH_GROFF_MODE = 0211;
+const int PUSH_COMP_MODE = 0212;
+const int POP_GROFFCOMP_MODE = 0213;
+const int BEGIN_QUOTE = 0214;
+const int END_QUOTE = 0215;
#else /* IS_EBCDIC_HOST */
@@ -90,7 +93,13 @@ const int LAST_PAGE_EJECTOR = 065;
const int ESCAPE_RIGHT_PARENTHESIS = 066;
const int ESCAPE_TILDE = 067;
const int ESCAPE_COLON = 070;
-const int COMPATIBLE_SAVE = 071;
-const int COMPATIBLE_RESTORE = 072;
+const int PUSH_GROFF_MODE = 071;
+const int PUSH_COMP_MODE = 072;
+const int POP_GROFFCOMP_MODE = 073;
+const int BEGIN_QUOTE = 074;
+const int END_QUOTE = 075;
#endif /* IS_EBCDIC_HOST */
+
+extern void do_glyph_color(symbol);
+extern void do_fill_color(symbol);
diff --git a/contrib/groff/src/roff/troff/mtsm.cpp b/contrib/groff/src/roff/troff/mtsm.cpp
new file mode 100644
index 0000000..630e973
--- /dev/null
+++ b/contrib/groff/src/roff/troff/mtsm.cpp
@@ -0,0 +1,632 @@
+// -*- C++ -*-
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Written by Gaius Mulley (gaius@glam.ac.uk)
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define DEBUGGING
+
+extern int debug_state;
+
+#include "troff.h"
+#include "hvunits.h"
+#include "stringclass.h"
+#include "mtsm.h"
+#include "env.h"
+
+static int no_of_statems = 0; // debugging aid
+
+int_value::int_value()
+: value(0), is_known(0)
+{
+}
+
+int_value::~int_value()
+{
+}
+
+void int_value::diff(FILE *fp, const char *s, int_value compare)
+{
+ if (differs(compare)) {
+ fputs("x X ", fp);
+ fputs(s, fp);
+ fputs(" ", fp);
+ fputs(i_to_a(compare.value), fp);
+ fputs("\n", fp);
+ value = compare.value;
+ is_known = 1;
+ if (debug_state)
+ fflush(fp);
+ }
+}
+
+void int_value::set(int v)
+{
+ is_known = 1;
+ value = v;
+}
+
+void int_value::unset()
+{
+ is_known = 0;
+}
+
+void int_value::set_if_unknown(int v)
+{
+ if (!is_known)
+ set(v);
+}
+
+int int_value::differs(int_value compare)
+{
+ return compare.is_known
+ && (!is_known || value != compare.value);
+}
+
+bool_value::bool_value()
+{
+}
+
+bool_value::~bool_value()
+{
+}
+
+void bool_value::diff(FILE *fp, const char *s, bool_value compare)
+{
+ if (differs(compare)) {
+ fputs("x X ", fp);
+ fputs(s, fp);
+ fputs("\n", fp);
+ value = compare.value;
+ is_known = 1;
+ if (debug_state)
+ fflush(fp);
+ }
+}
+
+units_value::units_value()
+{
+}
+
+units_value::~units_value()
+{
+}
+
+void units_value::diff(FILE *fp, const char *s, units_value compare)
+{
+ if (differs(compare)) {
+ fputs("x X ", fp);
+ fputs(s, fp);
+ fputs(" ", fp);
+ fputs(i_to_a(compare.value), fp);
+ fputs("\n", fp);
+ value = compare.value;
+ is_known = 1;
+ if (debug_state)
+ fflush(fp);
+ }
+}
+
+void units_value::set(hunits v)
+{
+ is_known = 1;
+ value = v.to_units();
+}
+
+int units_value::differs(units_value compare)
+{
+ return compare.is_known
+ && (!is_known || value != compare.value);
+}
+
+string_value::string_value()
+: value(string("")), is_known(0)
+{
+}
+
+string_value::~string_value()
+{
+}
+
+void string_value::diff(FILE *fp, const char *s, string_value compare)
+{
+ if (differs(compare)) {
+ fputs("x X ", fp);
+ fputs(s, fp);
+ fputs(" ", fp);
+ fputs(compare.value.contents(), fp);
+ fputs("\n", fp);
+ value = compare.value;
+ is_known = 1;
+ }
+}
+
+void string_value::set(string v)
+{
+ is_known = 1;
+ value = v;
+}
+
+void string_value::unset()
+{
+ is_known = 0;
+}
+
+int string_value::differs(string_value compare)
+{
+ return compare.is_known
+ && (!is_known || value != compare.value);
+}
+
+statem::statem()
+{
+ issue_no = no_of_statems;
+ no_of_statems++;
+}
+
+statem::statem(statem *copy)
+{
+ int i;
+ for (i = 0; i < LAST_BOOL; i++)
+ bool_values[i] = copy->bool_values[i];
+ for (i = 0; i < LAST_INT; i++)
+ int_values[i] = copy->int_values[i];
+ for (i = 0; i < LAST_UNITS; i++)
+ units_values[i] = copy->units_values[i];
+ for (i = 0; i < LAST_STRING; i++)
+ string_values[i] = copy->string_values[i];
+ issue_no = copy->issue_no;
+}
+
+statem::~statem()
+{
+}
+
+void statem::flush(FILE *fp, statem *compare)
+{
+ int_values[MTSM_FI].diff(fp, "devtag:.fi",
+ compare->int_values[MTSM_FI]);
+ int_values[MTSM_RJ].diff(fp, "devtag:.rj",
+ compare->int_values[MTSM_RJ]);
+ int_values[MTSM_SP].diff(fp, "devtag:.sp",
+ compare->int_values[MTSM_SP]);
+ units_values[MTSM_IN].diff(fp, "devtag:.in",
+ compare->units_values[MTSM_IN]);
+ units_values[MTSM_LL].diff(fp, "devtag:.ll",
+ compare->units_values[MTSM_LL]);
+ units_values[MTSM_PO].diff(fp, "devtag:.po",
+ compare->units_values[MTSM_PO]);
+ string_values[MTSM_TA].diff(fp, "devtag:.ta",
+ compare->string_values[MTSM_TA]);
+ units_values[MTSM_TI].diff(fp, "devtag:.ti",
+ compare->units_values[MTSM_TI]);
+ int_values[MTSM_CE].diff(fp, "devtag:.ce",
+ compare->int_values[MTSM_CE]);
+ bool_values[MTSM_EOL].diff(fp, "devtag:.eol",
+ compare->bool_values[MTSM_EOL]);
+ bool_values[MTSM_BR].diff(fp, "devtag:.br",
+ compare->bool_values[MTSM_BR]);
+ if (debug_state) {
+ fprintf(stderr, "compared state %d\n", compare->issue_no);
+ fflush(stderr);
+ }
+}
+
+void statem::add_tag(int_value_state t, int v)
+{
+ int_values[t].set(v);
+}
+
+void statem::add_tag(units_value_state t, hunits v)
+{
+ units_values[t].set(v);
+}
+
+void statem::add_tag(bool_value_state t)
+{
+ bool_values[t].set(1);
+}
+
+void statem::add_tag(string_value_state t, string v)
+{
+ string_values[t].set(v);
+}
+
+void statem::add_tag_if_unknown(int_value_state t, int v)
+{
+ int_values[t].set_if_unknown(v);
+}
+
+void statem::sub_tag_ce()
+{
+ int_values[MTSM_CE].unset();
+}
+
+/*
+ * add_tag_ta - add the tab settings to the minimum troff state machine
+ */
+
+void statem::add_tag_ta()
+{
+ if (is_html) {
+ string s = string("");
+ hunits d, l;
+ enum tab_type t;
+ do {
+ t = curenv->tabs.distance_to_next_tab(l, &d);
+ l += d;
+ switch (t) {
+ case TAB_LEFT:
+ s += " L ";
+ s += as_string(l.to_units());
+ break;
+ case TAB_CENTER:
+ s += " C ";
+ s += as_string(l.to_units());
+ break;
+ case TAB_RIGHT:
+ s += " R ";
+ s += as_string(l.to_units());
+ break;
+ case TAB_NONE:
+ break;
+ }
+ } while (t != TAB_NONE && l < curenv->get_line_length());
+ s += '\0';
+ string_values[MTSM_TA].set(s);
+ }
+}
+
+void statem::update(statem *older, statem *newer, int_value_state t)
+{
+ if (newer->int_values[t].differs(older->int_values[t])
+ && !newer->int_values[t].is_known)
+ newer->int_values[t].set(older->int_values[t].value);
+}
+
+void statem::update(statem *older, statem *newer, units_value_state t)
+{
+ if (newer->units_values[t].differs(older->units_values[t])
+ && !newer->units_values[t].is_known)
+ newer->units_values[t].set(older->units_values[t].value);
+}
+
+void statem::update(statem *older, statem *newer, bool_value_state t)
+{
+ if (newer->bool_values[t].differs(older->bool_values[t])
+ && !newer->bool_values[t].is_known)
+ newer->bool_values[t].set(older->bool_values[t].value);
+}
+
+void statem::update(statem *older, statem *newer, string_value_state t)
+{
+ if (newer->string_values[t].differs(older->string_values[t])
+ && !newer->string_values[t].is_known)
+ newer->string_values[t].set(older->string_values[t].value);
+}
+
+void statem::merge(statem *newer, statem *older)
+{
+ if (newer == 0 || older == 0)
+ return;
+ update(older, newer, MTSM_EOL);
+ update(older, newer, MTSM_BR);
+ update(older, newer, MTSM_FI);
+ update(older, newer, MTSM_LL);
+ update(older, newer, MTSM_PO);
+ update(older, newer, MTSM_RJ);
+ update(older, newer, MTSM_SP);
+ update(older, newer, MTSM_TA);
+ update(older, newer, MTSM_TI);
+ update(older, newer, MTSM_CE);
+}
+
+stack::stack()
+: next(0), state(0)
+{
+}
+
+stack::stack(statem *s, stack *n)
+: next(n), state(s)
+{
+}
+
+stack::~stack()
+{
+ if (state)
+ delete state;
+ if (next)
+ delete next;
+}
+
+mtsm::mtsm()
+: sp(0)
+{
+ driver = new statem();
+}
+
+mtsm::~mtsm()
+{
+ delete driver;
+ if (sp)
+ delete sp;
+}
+
+/*
+ * push_state - push the current troff state and use `n' as
+ * the new troff state.
+ */
+
+void mtsm::push_state(statem *n)
+{
+ if (is_html) {
+#if defined(DEBUGGING)
+ if (debug_state)
+ fprintf(stderr, "--> state %d pushed\n", n->issue_no) ; fflush(stderr);
+#endif
+ sp = new stack(n, sp);
+ }
+}
+
+void mtsm::pop_state()
+{
+ if (is_html) {
+#if defined(DEBUGGING)
+ if (debug_state)
+ fprintf(stderr, "--> state popped\n") ; fflush(stderr);
+#endif
+ if (sp == 0)
+ fatal("empty state machine stack");
+ if (sp->state)
+ delete sp->state;
+ sp->state = 0;
+ stack *t = sp;
+ sp = sp->next;
+ t->next = 0;
+ delete t;
+ }
+}
+
+/*
+ * inherit - scan the stack and collects inherited values.
+ */
+
+void mtsm::inherit(statem *s, int reset_bool)
+{
+ if (sp && sp->state) {
+ if (s->units_values[MTSM_IN].is_known
+ && sp->state->units_values[MTSM_IN].is_known)
+ s->units_values[MTSM_IN].value += sp->state->units_values[MTSM_IN].value;
+ s->update(sp->state, s, MTSM_FI);
+ s->update(sp->state, s, MTSM_LL);
+ s->update(sp->state, s, MTSM_PO);
+ s->update(sp->state, s, MTSM_RJ);
+ s->update(sp->state, s, MTSM_TA);
+ s->update(sp->state, s, MTSM_TI);
+ s->update(sp->state, s, MTSM_CE);
+ if (sp->state->bool_values[MTSM_BR].is_known
+ && sp->state->bool_values[MTSM_BR].value) {
+ if (reset_bool)
+ sp->state->bool_values[MTSM_BR].set(0);
+ s->bool_values[MTSM_BR].set(1);
+ if (debug_state)
+ fprintf(stderr, "inherited br from pushed state %d\n",
+ sp->state->issue_no);
+ }
+ else if (s->bool_values[MTSM_BR].is_known
+ && s->bool_values[MTSM_BR].value)
+ if (! s->int_values[MTSM_CE].is_known)
+ s->bool_values[MTSM_BR].unset();
+ if (sp->state->bool_values[MTSM_EOL].is_known
+ && sp->state->bool_values[MTSM_EOL].value) {
+ if (reset_bool)
+ sp->state->bool_values[MTSM_EOL].set(0);
+ s->bool_values[MTSM_EOL].set(1);
+ }
+ }
+}
+
+void mtsm::flush(FILE *fp, statem *s, string tag_list)
+{
+ if (is_html && s) {
+ inherit(s, 1);
+ driver->flush(fp, s);
+ // Set rj, ce, ti to unknown if they were known and
+ // we have seen an eol or br. This ensures that these values
+ // are emitted during the next glyph (as they step from n..0
+ // at each newline).
+ if ((driver->bool_values[MTSM_EOL].is_known
+ && driver->bool_values[MTSM_EOL].value)
+ || (driver->bool_values[MTSM_BR].is_known
+ && driver->bool_values[MTSM_BR].value)) {
+ if (driver->units_values[MTSM_TI].is_known)
+ driver->units_values[MTSM_TI].is_known = 0;
+ if (driver->int_values[MTSM_RJ].is_known
+ && driver->int_values[MTSM_RJ].value > 0)
+ driver->int_values[MTSM_RJ].is_known = 0;
+ if (driver->int_values[MTSM_CE].is_known
+ && driver->int_values[MTSM_CE].value > 0)
+ driver->int_values[MTSM_CE].is_known = 0;
+ }
+ // reset the boolean values
+ driver->bool_values[MTSM_BR].set(0);
+ driver->bool_values[MTSM_EOL].set(0);
+ // reset space value
+ driver->int_values[MTSM_SP].set(0);
+ // lastly write out any direct tag entries
+ if (tag_list != string("")) {
+ string t = tag_list + '\0';
+ fputs(t.contents(), fp);
+ }
+ }
+}
+
+/*
+ * display_state - dump out a synopsis of the state to stderr.
+ */
+
+void statem::display_state()
+{
+ fprintf(stderr, " <state ");
+ if (bool_values[MTSM_BR].is_known)
+ if (bool_values[MTSM_BR].value)
+ fprintf(stderr, "[br]");
+ else
+ fprintf(stderr, "[!br]");
+ if (bool_values[MTSM_EOL].is_known)
+ if (bool_values[MTSM_EOL].value)
+ fprintf(stderr, "[eol]");
+ else
+ fprintf(stderr, "[!eol]");
+ if (int_values[MTSM_SP].is_known)
+ if (int_values[MTSM_SP].value)
+ fprintf(stderr, "[sp %d]", int_values[MTSM_SP].value);
+ else
+ fprintf(stderr, "[!sp]");
+ fprintf(stderr, ">");
+ fflush(stderr);
+}
+
+int mtsm::has_changed(int_value_state t, statem *s)
+{
+ return driver->int_values[t].differs(s->int_values[t]);
+}
+
+int mtsm::has_changed(units_value_state t, statem *s)
+{
+ return driver->units_values[t].differs(s->units_values[t]);
+}
+
+int mtsm::has_changed(bool_value_state t, statem *s)
+{
+ return driver->bool_values[t].differs(s->bool_values[t]);
+}
+
+int mtsm::has_changed(string_value_state t, statem *s)
+{
+ return driver->string_values[t].differs(s->string_values[t]);
+}
+
+int mtsm::changed(statem *s)
+{
+ if (s == 0 || !is_html)
+ return 0;
+ s = new statem(s);
+ inherit(s, 0);
+ int result = has_changed(MTSM_EOL, s)
+ || has_changed(MTSM_BR, s)
+ || has_changed(MTSM_FI, s)
+ || has_changed(MTSM_IN, s)
+ || has_changed(MTSM_LL, s)
+ || has_changed(MTSM_PO, s)
+ || has_changed(MTSM_RJ, s)
+ || has_changed(MTSM_SP, s)
+ || has_changed(MTSM_TA, s)
+ || has_changed(MTSM_CE, s);
+ delete s;
+ return result;
+}
+
+void mtsm::add_tag(FILE *fp, string s)
+{
+ fflush(fp);
+ s += '\0';
+ fputs(s.contents(), fp);
+}
+
+/*
+ * state_set class
+ */
+
+state_set::state_set()
+: boolset(0), intset(0), unitsset(0), stringset(0)
+{
+}
+
+state_set::~state_set()
+{
+}
+
+void state_set::incl(bool_value_state b)
+{
+ boolset |= 1 << (int)b;
+}
+
+void state_set::incl(int_value_state i)
+{
+ intset |= 1 << (int)i;
+}
+
+void state_set::incl(units_value_state u)
+{
+ unitsset |= 1 << (int)u;
+}
+
+void state_set::incl(string_value_state s)
+{
+ stringset |= 1 << (int)s;
+}
+
+void state_set::excl(bool_value_state b)
+{
+ boolset &= ~(1 << (int)b);
+}
+
+void state_set::excl(int_value_state i)
+{
+ intset &= ~(1 << (int)i);
+}
+
+void state_set::excl(units_value_state u)
+{
+ unitsset &= ~(1 << (int)u);
+}
+
+void state_set::excl(string_value_state s)
+{
+ stringset &= ~(1 << (int)s);
+}
+
+int state_set::is_in(bool_value_state b)
+{
+ return (boolset & (1 << (int)b)) != 0;
+}
+
+int state_set::is_in(int_value_state i)
+{
+ return (intset & (1 << (int)i)) != 0;
+}
+
+int state_set::is_in(units_value_state u)
+{
+ return (unitsset & (1 << (int)u) != 0);
+}
+
+int state_set::is_in(string_value_state s)
+{
+ return (stringset & (1 << (int)s) != 0);
+}
+
+void state_set::add(units_value_state, int n)
+{
+ unitsset += n;
+}
+
+units state_set::val(units_value_state)
+{
+ return unitsset;
+}
diff --git a/contrib/groff/src/roff/troff/mtsm.h b/contrib/groff/src/roff/troff/mtsm.h
new file mode 100644
index 0000000..9ef909c
--- /dev/null
+++ b/contrib/groff/src/roff/troff/mtsm.h
@@ -0,0 +1,164 @@
+// -*- C++ -*-
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ *
+ * mtsm.h
+ *
+ * written by Gaius Mulley (gaius@glam.ac.uk)
+ *
+ * provides a minimal troff state machine which is necessary to
+ * emit meta tags for the post-grohtml device driver.
+ */
+
+/*
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+struct int_value {
+ int value;
+ int is_known;
+ int_value();
+ ~int_value();
+ void diff(FILE *, const char *, int_value);
+ int differs(int_value);
+ void set(int);
+ void unset();
+ void set_if_unknown(int);
+};
+
+struct bool_value : public int_value {
+ bool_value();
+ ~bool_value();
+ void diff(FILE *, const char *, bool_value);
+};
+
+struct units_value : public int_value {
+ units_value();
+ ~units_value();
+ void diff(FILE *, const char *, units_value);
+ int differs(units_value);
+ void set(hunits);
+};
+
+struct string_value {
+ string value;
+ int is_known;
+ string_value();
+ ~string_value();
+ void diff(FILE *, const char *, string_value);
+ int differs(string_value);
+ void set(string);
+ void unset();
+};
+
+enum bool_value_state {
+ MTSM_EOL,
+ MTSM_BR,
+ LAST_BOOL
+};
+enum int_value_state {
+ MTSM_FI,
+ MTSM_RJ,
+ MTSM_CE,
+ MTSM_SP,
+ LAST_INT
+};
+enum units_value_state {
+ MTSM_IN,
+ MTSM_LL,
+ MTSM_PO,
+ MTSM_TI,
+ LAST_UNITS
+};
+enum string_value_state {
+ MTSM_TA,
+ LAST_STRING
+};
+
+struct statem {
+ int issue_no;
+ bool_value bool_values[LAST_BOOL];
+ int_value int_values[LAST_INT];
+ units_value units_values[LAST_UNITS];
+ string_value string_values[LAST_STRING];
+ statem();
+ statem(statem *);
+ ~statem();
+ void flush(FILE *, statem *);
+ int changed(statem *);
+ void merge(statem *, statem *);
+ void add_tag(int_value_state, int);
+ void add_tag(bool_value_state);
+ void add_tag(units_value_state, hunits);
+ void add_tag(string_value_state, string);
+ void sub_tag_ce();
+ void add_tag_if_unknown(int_value_state, int);
+ void add_tag_ta();
+ void display_state();
+ void update(statem *, statem *, int_value_state);
+ void update(statem *, statem *, bool_value_state);
+ void update(statem *, statem *, units_value_state);
+ void update(statem *, statem *, string_value_state);
+};
+
+struct stack {
+ stack *next;
+ statem *state;
+ stack();
+ stack(statem *, stack *);
+ ~stack();
+};
+
+class mtsm {
+ statem *driver;
+ stack *sp;
+ int has_changed(int_value_state, statem *);
+ int has_changed(bool_value_state, statem *);
+ int has_changed(units_value_state, statem *);
+ int has_changed(string_value_state, statem *);
+ void inherit(statem *, int);
+public:
+ mtsm();
+ ~mtsm();
+ void push_state(statem *);
+ void pop_state();
+ void flush(FILE *, statem *, string);
+ int changed(statem *);
+ void add_tag(FILE *, string);
+};
+
+class state_set {
+ int boolset;
+ int intset;
+ int unitsset;
+ int stringset;
+public:
+ state_set();
+ ~state_set();
+ void incl(bool_value_state);
+ void incl(int_value_state);
+ void incl(units_value_state);
+ void incl(string_value_state);
+ void excl(bool_value_state);
+ void excl(int_value_state);
+ void excl(units_value_state);
+ void excl(string_value_state);
+ int is_in(bool_value_state);
+ int is_in(int_value_state);
+ int is_in(units_value_state);
+ int is_in(string_value_state);
+ void add(units_value_state, int);
+ units val(units_value_state);
+};
diff --git a/contrib/groff/src/roff/troff/node.cpp b/contrib/groff/src/roff/troff/node.cpp
index 73776b1..0d874d3 100644
--- a/contrib/groff/src/roff/troff/node.cpp
+++ b/contrib/groff/src/roff/troff/node.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,7 +17,9 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+extern int debug_state;
#include "troff.h"
@@ -25,20 +27,20 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <unistd.h>
#endif
-#include "symbol.h"
#include "dictionary.h"
#include "hvunits.h"
+#include "stringclass.h"
+#include "mtsm.h"
#include "env.h"
#include "request.h"
#include "node.h"
#include "token.h"
+#include "div.h"
+#include "reg.h"
#include "charinfo.h"
#include "font.h"
-#include "reg.h"
#include "input.h"
-#include "div.h"
#include "geometry.h"
-#include "stringclass.h"
#include "nonposix.h"
@@ -59,6 +61,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif /* not _POSIX_VERSION */
+// declarations to avoid friend name injections
+class tfont;
+class tfont_spec;
+tfont *make_tfont(tfont_spec &);
+
+
/*
* how many boundaries of images have been written? Useful for
* debugging grohtml
@@ -112,8 +120,6 @@ struct conditional_bold {
conditional_bold(int, hunits, conditional_bold * = 0);
};
-struct tfont;
-
class font_info {
tfont *last_tfont;
int number;
@@ -134,7 +140,7 @@ class font_info {
void flush();
public:
special_font_list *sf;
- font_info(symbol nm, int n, symbol enm, font *f);
+ font_info(symbol, int, symbol, font *);
int contains(charinfo *);
void set_bold(hunits);
void unbold();
@@ -152,6 +158,7 @@ public:
int is_special();
int is_style();
friend symbol get_font_name(int, environment *);
+ friend symbol get_style_name(int);
};
class tfont_spec {
@@ -170,7 +177,7 @@ protected:
int height;
int slant;
public:
- tfont_spec(symbol nm, int pos, font *, font_size, int, int);
+ tfont_spec(symbol, int, font *, font_size, int, int);
tfont_spec(const tfont_spec &spec) { *this = spec; }
tfont_spec plain();
int operator==(const tfont_spec &);
@@ -400,11 +407,19 @@ symbol get_font_name(int fontno, environment *env)
return f;
}
-hunits font_info::get_space_width(font_size fs, int space_size)
+symbol get_style_name(int fontno)
+{
+ if (font_table[fontno]->is_style())
+ return font_table[fontno]->get_name();
+ else
+ return EMPTY_SYMBOL;
+}
+
+hunits font_info::get_space_width(font_size fs, int space_sz)
{
if (is_constant_spaced == CONSTANT_SPACE_NONE)
return scale(hunits(fm->get_space_width(fs.to_scaled_points())),
- space_size, 12);
+ space_sz, 12);
else if (is_constant_spaced == CONSTANT_SPACE_ABSOLUTE)
return constant_space;
else
@@ -681,9 +696,8 @@ class real_output_file : public output_file {
virtual void really_put_filename(const char *filename);
virtual void really_on();
virtual void really_off();
-protected:
- FILE *fp;
public:
+ FILE *fp;
real_output_file();
~real_output_file();
void flush();
@@ -751,6 +765,8 @@ class troff_output_file : public real_output_file {
int tbuf_len;
int tbuf_kern;
int begun_page;
+ int cur_div_level;
+ string tag_list;
void do_motion();
void put(char c);
void put(unsigned char c);
@@ -787,6 +803,7 @@ public:
void fill_color(color *c);
int get_hpos() { return hpos; }
int get_vpos() { return vpos; }
+ void add_to_tag_list(string s);
friend void space_char_hmotion_node::tprint(troff_output_file *);
friend void unbreakable_space_node::tprint(troff_output_file *);
};
@@ -864,6 +881,29 @@ void troff_output_file::really_print_line(hunits x, vunits y, node *n,
{
moveto(x, y);
while (n != 0) {
+ // Check whether we should push the current troff state and use
+ // the state at the start of the invocation of this diversion.
+ if (n->div_nest_level > cur_div_level && n->push_state) {
+ state.push_state(n->push_state);
+ cur_div_level = n->div_nest_level;
+ }
+ // Has the current diversion level decreased? Then we must pop the
+ // troff state.
+ while (n->div_nest_level < cur_div_level) {
+ state.pop_state();
+ cur_div_level = n->div_nest_level;
+ }
+ // Now check whether the state has changed.
+ if ((is_on() || n->force_tprint())
+ && (state.changed(n->state) || n->is_tag() || n->is_special)) {
+ flush_tbuf();
+ do_motion();
+ force_motion = 1;
+ flush();
+ state.flush(fp, n->state, tag_list);
+ tag_list = string("");
+ flush();
+ }
n->tprint(this);
n = n->next;
}
@@ -987,7 +1027,7 @@ void troff_output_file::put_char_width(charinfo *ci, tfont *tf,
return;
}
set_font(tf);
- char c = ci->get_ascii_code();
+ unsigned char c = ci->get_ascii_code();
if (c == '\0') {
glyph_color(gcol);
fill_color(fcol);
@@ -1065,7 +1105,7 @@ void troff_output_file::put_char(charinfo *ci, tfont *tf,
if (!is_on())
return;
set_font(tf);
- char c = ci->get_ascii_code();
+ unsigned char c = ci->get_ascii_code();
if (c == '\0') {
glyph_color(gcol);
fill_color(fcol);
@@ -1275,6 +1315,16 @@ void troff_output_file::glyph_color(color *col)
put('\n');
}
+void troff_output_file::add_to_tag_list(string s)
+{
+ if (tag_list == string(""))
+ tag_list = s;
+ else {
+ tag_list += string("\n");
+ tag_list += s;
+ }
+}
+
// determine_line_limits - works out the smallest box which will contain
// the entity, code, built from the point array.
void troff_output_file::determine_line_limits(char code, hvpair *point,
@@ -1456,13 +1506,14 @@ void troff_output_file::really_begin_page(int pageno, vunits page_length)
put('\n');
}
-void troff_output_file::really_copy_file(hunits x, vunits y, const char *filename)
+void troff_output_file::really_copy_file(hunits x, vunits y,
+ const char *filename)
{
moveto(x, y);
flush_tbuf();
do_motion();
errno = 0;
- FILE *ifp = fopen(filename, "r");
+ FILE *ifp = include_search_path.open_file_cautious(filename);
if (ifp == 0)
error("can't open `%1': %2", filename, strerror(errno));
else {
@@ -1503,7 +1554,8 @@ void troff_output_file::trailer(vunits page_length)
troff_output_file::troff_output_file()
: current_slant(0), current_height(0), current_fill_color(0),
- current_glyph_color(0), nfont_positions(10), tbuf_len(0), begun_page(0)
+ current_glyph_color(0), nfont_positions(10), tbuf_len(0), begun_page(0),
+ cur_div_level(0)
{
font_position = new symbol[nfont_positions];
put("x T ");
@@ -1726,14 +1778,14 @@ class charinfo_node : public node {
protected:
charinfo *ci;
public:
- charinfo_node(charinfo *, node * = 0);
+ charinfo_node(charinfo *, statem *, int, node * = 0);
int ends_sentence();
int overlaps_vertically();
int overlaps_horizontally();
};
-charinfo_node::charinfo_node(charinfo *c, node *x)
-: node(x), ci(c)
+charinfo_node::charinfo_node(charinfo *c, statem *s, int pop, node *x)
+: node(x, s, pop), ci(c)
{
}
@@ -1765,12 +1817,14 @@ protected:
color *fcol; /* this is needed for grotty */
#ifdef STORE_WIDTH
hunits wid;
- glyph_node(charinfo *, tfont *, color *, color *, hunits, node * = 0);
+ glyph_node(charinfo *, tfont *, color *, color *, hunits,
+ statem *, int, node * = 0);
#endif
public:
void *operator new(size_t);
void operator delete(void *);
- glyph_node(charinfo *, tfont *, color *, color *, node * = 0);
+ glyph_node(charinfo *, tfont *, color *, color *,
+ statem *, int, node * = 0);
~glyph_node() {}
node *copy();
node *merge_glyph_node(glyph_node *);
@@ -1797,6 +1851,8 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
+ void debug_node();
};
glyph_node *glyph_node::free_list = 0;
@@ -1806,13 +1862,13 @@ class ligature_node : public glyph_node {
node *n2;
#ifdef STORE_WIDTH
ligature_node(charinfo *, tfont *, color *, color *, hunits,
- node *, node *, node * = 0);
+ node *, node *, statem *, int, node * = 0);
#endif
public:
void *operator new(size_t);
void operator delete(void *);
ligature_node(charinfo *, tfont *, color *, color *,
- node *, node *, node * = 0);
+ node *, node *, statem *, int, node * = 0);
~ligature_node();
node *copy();
node *add_self(node *, hyphen_list **);
@@ -1822,6 +1878,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class kern_pair_node : public node {
@@ -1829,7 +1886,7 @@ class kern_pair_node : public node {
node *n1;
node *n2;
public:
- kern_pair_node(hunits n, node *first, node *second, node *x = 0);
+ kern_pair_node(hunits, node *, node *, statem *, int, node * = 0);
~kern_pair_node();
node *copy();
node *merge_glyph_node(glyph_node *);
@@ -1848,6 +1905,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
void vertical_extent(vunits *, vunits *);
};
@@ -1856,7 +1914,7 @@ class dbreak_node : public node {
node *pre;
node *post;
public:
- dbreak_node(node *n, node *p, node *x = 0);
+ dbreak_node(node *, node *, statem *, int, node * = 0);
~dbreak_node();
node *copy();
node *merge_glyph_node(glyph_node *);
@@ -1877,6 +1935,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
void *glyph_node::operator new(size_t n)
@@ -1913,8 +1972,9 @@ void ligature_node::operator delete(void *p)
delete[] (char *)p;
}
-glyph_node::glyph_node(charinfo *c, tfont *t, color *gc, color *fc, node *x)
-: charinfo_node(c, x), tf(t), gcol(gc), fcol(fc)
+glyph_node::glyph_node(charinfo *c, tfont *t, color *gc, color *fc,
+ statem *s, int pop, node *x)
+: charinfo_node(c, s, pop, x), tf(t), gcol(gc), fcol(fc)
{
#ifdef STORE_WIDTH
wid = tf->get_width(ci);
@@ -1923,8 +1983,9 @@ glyph_node::glyph_node(charinfo *c, tfont *t, color *gc, color *fc, node *x)
#ifdef STORE_WIDTH
glyph_node::glyph_node(charinfo *c, tfont *t,
- color *gc, color *fc, hunits w, node *x)
-: charinfo_node(c, x), tf(t), gcol(gc), fcol(fc), wid(w)
+ color *gc, color *fc, hunits w,
+ statem *s, int pop, node *x)
+: charinfo_node(c, s, pop, x), tf(t), gcol(gc), fcol(fc), wid(w)
{
}
#endif
@@ -1932,9 +1993,9 @@ glyph_node::glyph_node(charinfo *c, tfont *t,
node *glyph_node::copy()
{
#ifdef STORE_WIDTH
- return new glyph_node(ci, tf, gcol, fcol, wid);
+ return new glyph_node(ci, tf, gcol, fcol, wid, state, div_nest_level);
#else
- return new glyph_node(ci, tf, gcol, fcol);
+ return new glyph_node(ci, tf, gcol, fcol, state, div_nest_level);
#endif
}
@@ -2018,13 +2079,15 @@ node *glyph_node::merge_glyph_node(glyph_node *gn)
if ((lig = tf->get_lig(ci, gn->ci)) != 0) {
node *next1 = next;
next = 0;
- return new ligature_node(lig, tf, gcol, fcol, this, gn, next1);
+ return new ligature_node(lig, tf, gcol, fcol, this, gn, state,
+ gn->div_nest_level, next1);
}
hunits kern;
if (tf->get_kern(ci, gn->ci, &kern)) {
node *next1 = next;
next = 0;
- return new kern_pair_node(kern, this, gn, next1);
+ return new kern_pair_node(kern, this, gn, state,
+ gn->div_nest_level, next1);
}
}
return 0;
@@ -2087,16 +2150,35 @@ void glyph_node::ascii_print(ascii_output_file *ascii)
ascii->outs(ci->nm.contents());
}
+void glyph_node::debug_node()
+{
+ unsigned char c = ci->get_ascii_code();
+ fprintf(stderr, "{ %s [", type());
+ if (c)
+ fprintf(stderr, "%c", c);
+ else
+ fprintf(stderr, ci->nm.contents());
+ if (push_state)
+ fprintf(stderr, " <push_state>");
+ if (state)
+ state->display_state();
+ fprintf(stderr, " nest level %d", div_nest_level);
+ fprintf(stderr, "]}\n");
+ fflush(stderr);
+}
+
ligature_node::ligature_node(charinfo *c, tfont *t, color *gc, color *fc,
- node *gn1, node *gn2, node *x)
-: glyph_node(c, t, gc, fc, x), n1(gn1), n2(gn2)
+ node *gn1, node *gn2, statem *s,
+ int pop, node *x)
+: glyph_node(c, t, gc, fc, s, pop, x), n1(gn1), n2(gn2)
{
}
#ifdef STORE_WIDTH
ligature_node::ligature_node(charinfo *c, tfont *t, color *gc, color *fc,
- hunits w, node *gn1, node *gn2, node *x)
-: glyph_node(c, t, gc, fc, w, x), n1(gn1), n2(gn2)
+ hunits w, node *gn1, node *gn2, statem *s,
+ int pop, node *x)
+: glyph_node(c, t, gc, fc, w, s, pop, x), n1(gn1), n2(gn2)
{
}
#endif
@@ -2110,9 +2192,11 @@ ligature_node::~ligature_node()
node *ligature_node::copy()
{
#ifdef STORE_WIDTH
- return new ligature_node(ci, tf, gcol, fcol, wid, n1->copy(), n2->copy());
+ return new ligature_node(ci, tf, gcol, fcol, wid, n1->copy(), n2->copy(),
+ state, div_nest_level);
#else
- return new ligature_node(ci, tf, gcol, fcol, n1->copy(), n2->copy());
+ return new ligature_node(ci, tf, gcol, fcol, n1->copy(), n2->copy(),
+ state, div_nest_level);
#endif
}
@@ -2137,13 +2221,14 @@ node *ligature_node::add_self(node *n, hyphen_list **p)
return n;
}
-kern_pair_node::kern_pair_node(hunits n, node *first, node *second, node *x)
-: node(x), amount(n), n1(first), n2(second)
+kern_pair_node::kern_pair_node(hunits n, node *first, node *second,
+ statem* s, int pop, node *x)
+: node(x, s, pop), amount(n), n1(first), n2(second)
{
}
-dbreak_node::dbreak_node(node *n, node *p, node *x)
-: node(x), none(n), pre(p), post(0)
+dbreak_node::dbreak_node(node *n, node *p, statem *s, int pop, node *x)
+: node(x, s, pop), none(n), pre(p), post(0)
{
}
@@ -2219,13 +2304,14 @@ node *kern_pair_node::add_discretionary_hyphen()
node *next1 = next;
next = 0;
node *n = copy();
- glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol);
+ glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol,
+ state, div_nest_level);
node *nn = n->merge_glyph_node(gn);
if (nn == 0) {
gn->next = n;
nn = gn;
}
- return new dbreak_node(this, nn, next1);
+ return new dbreak_node(this, nn, state, div_nest_level, next1);
}
}
return this;
@@ -2248,7 +2334,8 @@ dbreak_node::~dbreak_node()
node *kern_pair_node::copy()
{
- return new kern_pair_node(amount, n1->copy(), n2->copy());
+ return new kern_pair_node(amount, n1->copy(), n2->copy(), state,
+ div_nest_level);
}
node *copy_node_list(node *n)
@@ -2280,7 +2367,8 @@ void delete_node_list(node *n)
node *dbreak_node::copy()
{
- dbreak_node *p = new dbreak_node(copy_node_list(none), copy_node_list(pre));
+ dbreak_node *p = new dbreak_node(copy_node_list(none), copy_node_list(pre),
+ state, div_nest_level);
p->post = copy_node_list(post);
return p;
}
@@ -2298,11 +2386,12 @@ hyphen_list *kern_pair_node::get_hyphen_list(hyphen_list *tail, int *count)
class hyphen_inhibitor_node : public node {
public:
- hyphen_inhibitor_node(node *nd = 0);
+ hyphen_inhibitor_node(node * = 0);
node *copy();
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
hyphenation_type get_hyphenation_type();
};
@@ -2330,6 +2419,11 @@ int hyphen_inhibitor_node::force_tprint()
return 0;
}
+int hyphen_inhibitor_node::is_tag()
+{
+ return 0;
+}
+
hyphenation_type hyphen_inhibitor_node::get_hyphenation_type()
{
return HYPHEN_INHIBIT;
@@ -2357,13 +2451,14 @@ node *node::add_discretionary_hyphen()
node *next1 = next;
next = 0;
node *n = copy();
- glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol);
+ glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol,
+ state, div_nest_level);
node *n1 = n->merge_glyph_node(gn);
if (n1 == 0) {
gn->next = n;
n1 = gn;
}
- return new dbreak_node(this, n1, next1);
+ return new dbreak_node(this, n1, state, div_nest_level, next1);
}
return this;
}
@@ -2403,6 +2498,11 @@ int node::force_tprint()
return 0;
}
+int node::is_tag()
+{
+ return 0;
+}
+
hunits hmotion_node::width()
{
return n;
@@ -2413,6 +2513,29 @@ units node::size()
return points_to_units(10);
}
+void node::debug_node()
+{
+ fprintf(stderr, "{ %s ", type());
+ if (push_state)
+ fprintf(stderr, " <push_state>");
+ if (state)
+ fprintf(stderr, " <state>");
+ fprintf(stderr, " nest level %d", div_nest_level);
+ fprintf(stderr, " }\n");
+ fflush(stderr);
+}
+
+void node::debug_node_list()
+{
+ node *n = next;
+
+ debug_node();
+ while (n != 0) {
+ n->debug_node();
+ n = n->next;
+ }
+}
+
hunits kern_pair_node::width()
{
return n1->width() + n2->width() + amount;
@@ -2437,9 +2560,9 @@ hunits dbreak_node::width()
node *dbreak_node::last_char_node()
{
for (node *n = none; n; n = n->next) {
- node *last = n->last_char_node();
- if (last)
- return last;
+ node *last_node = n->last_char_node();
+ if (last_node)
+ return last_node;
}
return 0;
}
@@ -2458,7 +2581,7 @@ class italic_corrected_node : public node {
node *n;
hunits x;
public:
- italic_corrected_node(node *, hunits, node * = 0);
+ italic_corrected_node(node *, hunits, statem *, int, node * = 0);
~italic_corrected_node();
node *copy();
void ascii_print(ascii_output_file *);
@@ -2480,9 +2603,10 @@ public:
node *add_self(node *, hyphen_list **);
const char *type();
int force_tprint();
+ int is_tag();
};
-node *node::add_italic_correction(hunits *width)
+node *node::add_italic_correction(hunits *wd)
{
hunits ic = italic_correction();
if (ic.is_zero())
@@ -2490,13 +2614,14 @@ node *node::add_italic_correction(hunits *width)
else {
node *next1 = next;
next = 0;
- *width += ic;
- return new italic_corrected_node(this, ic, next1);
+ *wd += ic;
+ return new italic_corrected_node(this, ic, state, div_nest_level, next1);
}
}
-italic_corrected_node::italic_corrected_node(node *nn, hunits xx, node *p)
-: node(p), n(nn), x(xx)
+italic_corrected_node::italic_corrected_node(node *nn, hunits xx, statem *s,
+ int pop, node *p)
+: node(p, s, pop), n(nn), x(xx)
{
assert(n != 0);
}
@@ -2508,7 +2633,7 @@ italic_corrected_node::~italic_corrected_node()
node *italic_corrected_node::copy()
{
- return new italic_corrected_node(n->copy(), x);
+ return new italic_corrected_node(n->copy(), x, state, div_nest_level);
}
hunits italic_corrected_node::width()
@@ -2599,6 +2724,7 @@ class break_char_node : public node {
color *col;
public:
break_char_node(node *, int, color *, node * = 0);
+ break_char_node(node *, int, color *, statem *, int, node * = 0);
~break_char_node();
node *copy();
hunits width();
@@ -2620,6 +2746,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
break_char_node::break_char_node(node *n, int bc, color *c, node *x)
@@ -2627,6 +2754,12 @@ break_char_node::break_char_node(node *n, int bc, color *c, node *x)
{
}
+break_char_node::break_char_node(node *n, int bc, color *c, statem *s,
+ int pop, node *x)
+: node(x, s, pop), ch(n), break_code(bc), col(c)
+{
+}
+
break_char_node::~break_char_node()
{
delete ch;
@@ -2634,7 +2767,8 @@ break_char_node::~break_char_node()
node *break_char_node::copy()
{
- return new break_char_node(ch->copy(), break_code, col);
+ return new break_char_node(ch->copy(), break_code, col, state,
+ div_nest_level);
}
hunits break_char_node::width()
@@ -2718,27 +2852,57 @@ tfont *break_char_node::get_tfont()
node *extra_size_node::copy()
{
- return new extra_size_node(n);
+ return new extra_size_node(n, state, div_nest_level);
+}
+
+extra_size_node::extra_size_node(vunits i, statem *s, int pop)
+: node(0, s, pop), n(i)
+{
+}
+
+extra_size_node::extra_size_node(vunits i)
+: n(i)
+{
}
node *vertical_size_node::copy()
{
- return new vertical_size_node(n);
+ return new vertical_size_node(n, state, div_nest_level);
+}
+
+vertical_size_node::vertical_size_node(vunits i, statem *s, int pop)
+: node(0, s, pop), n(i)
+{
+}
+
+vertical_size_node::vertical_size_node(vunits i)
+: n(i)
+{
}
node *hmotion_node::copy()
{
- return new hmotion_node(n, was_tab, unformat, col);
+ return new hmotion_node(n, was_tab, unformat, col, state, div_nest_level);
}
node *space_char_hmotion_node::copy()
{
- return new space_char_hmotion_node(n, col);
+ return new space_char_hmotion_node(n, col, state, div_nest_level);
+}
+
+vmotion_node::vmotion_node(vunits i, color *c)
+: n(i), col(c)
+{
+}
+
+vmotion_node::vmotion_node(vunits i, color *c, statem *s, int pop)
+: node(0, s, pop), n(i), col(c)
+{
}
node *vmotion_node::copy()
{
- return new vmotion_node(n, col);
+ return new vmotion_node(n, col, state, div_nest_level);
}
node *dummy_node::copy()
@@ -2757,9 +2921,19 @@ hline_node::~hline_node()
delete n;
}
+hline_node::hline_node(hunits i, node *c, node *nxt)
+: node(nxt), x(i), n(c)
+{
+}
+
+hline_node::hline_node(hunits i, node *c, statem *s, int pop, node *nxt)
+: node(nxt, s, pop), x(i), n(c)
+{
+}
+
node *hline_node::copy()
{
- return new hline_node(x, n ? n->copy() : 0);
+ return new hline_node(x, n ? n->copy() : 0, state, div_nest_level);
}
hunits hline_node::width()
@@ -2767,6 +2941,16 @@ hunits hline_node::width()
return x < H0 ? H0 : x;
}
+vline_node::vline_node(vunits i, node *c, node *nxt)
+: node(nxt), x(i), n(c)
+{
+}
+
+vline_node::vline_node(vunits i, node *c, statem *s, int pop, node *nxt)
+: node(nxt, s, pop), x(i), n(c)
+{
+}
+
vline_node::~vline_node()
{
if (n)
@@ -2775,7 +2959,7 @@ vline_node::~vline_node()
node *vline_node::copy()
{
- return new vline_node(x, n ? n->copy() : 0);
+ return new vline_node(x, n ? n->copy() : 0, state, div_nest_level);
}
hunits vline_node::width()
@@ -2783,7 +2967,13 @@ hunits vline_node::width()
return n == 0 ? H0 : n->width();
}
-zero_width_node::zero_width_node(node *nd) : n(nd)
+zero_width_node::zero_width_node(node *nd, statem *s, int pop)
+: node(0, s, pop), n(nd)
+{
+}
+
+zero_width_node::zero_width_node(node *nd)
+: n(nd)
{
}
@@ -2794,7 +2984,7 @@ zero_width_node::~zero_width_node()
node *zero_width_node::copy()
{
- return new zero_width_node(copy_node_list(n));
+ return new zero_width_node(copy_node_list(n), state, div_nest_level);
}
int node_list_character_type(node *p)
@@ -2833,7 +3023,13 @@ void zero_width_node::vertical_extent(vunits *min, vunits *max)
node_list_vertical_extent(n, min, max);
}
-overstrike_node::overstrike_node() : list(0), max_width(H0)
+overstrike_node::overstrike_node()
+: list(0), max_width(H0)
+{
+}
+
+overstrike_node::overstrike_node(statem *s, int pop)
+: node(0, s, pop), list(0), max_width(H0)
{
}
@@ -2844,7 +3040,7 @@ overstrike_node::~overstrike_node()
node *overstrike_node::copy()
{
- overstrike_node *on = new overstrike_node;
+ overstrike_node *on = new overstrike_node(state, div_nest_level);
for (node *tem = list; tem; tem = tem->next)
on->overstrike(tem->copy());
return on;
@@ -2869,7 +3065,13 @@ hunits overstrike_node::width()
return max_width;
}
-bracket_node::bracket_node() : list(0), max_width(H0)
+bracket_node::bracket_node()
+: list(0), max_width(H0)
+{
+}
+
+bracket_node::bracket_node(statem *s, int pop)
+: node(0, s, pop), list(0), max_width(H0)
{
}
@@ -2880,17 +3082,17 @@ bracket_node::~bracket_node()
node *bracket_node::copy()
{
- bracket_node *on = new bracket_node;
- node *last = 0;
+ bracket_node *on = new bracket_node(state, div_nest_level);
+ node *last_node = 0;
node *tem;
if (list)
list->last = 0;
for (tem = list; tem; tem = tem->next) {
if (tem->next)
tem->next->last = tem;
- last = tem;
+ last_node = tem;
}
- for (tem = last; tem; tem = tem->last)
+ for (tem = last_node; tem; tem = tem->last)
on->bracket(tem->copy());
return on;
}
@@ -2949,12 +3151,18 @@ inline void space_node::operator delete(void *p)
#endif
space_node::space_node(hunits nn, color *c, node *p)
-: node(p), n(nn), set(0), was_escape_colon(0), col(c)
+: node(p, 0, 0), n(nn), set(0), was_escape_colon(0), col(c)
+{
+}
+
+space_node::space_node(hunits nn, color *c, statem *s, int pop, node *p)
+: node(p, s, pop), n(nn), set(0), was_escape_colon(0), col(c)
{
}
-space_node::space_node(hunits nn, int s, int flag, color *c, node *p)
-: node(p), n(nn), set(s), was_escape_colon(flag), col(c)
+space_node::space_node(hunits nn, int s, int flag, color *c, statem *st,
+ int pop, node *p)
+: node(p, st, pop), n(nn), set(s), was_escape_colon(flag), col(c)
{
}
@@ -2966,7 +3174,7 @@ space_node::~space_node()
node *space_node::copy()
{
- return new space_node(n, set, was_escape_colon, col);
+ return new space_node(n, set, was_escape_colon, col, state, div_nest_level);
}
int space_node::force_tprint()
@@ -2974,6 +3182,11 @@ int space_node::force_tprint()
return 0;
}
+int space_node::is_tag()
+{
+ return 0;
+}
+
int space_node::nspaces()
{
return set ? 0 : 1;
@@ -2994,20 +3207,20 @@ void node::spread_space(int*, hunits*)
{
}
-void space_node::spread_space(int *nspaces, hunits *desired_space)
+void space_node::spread_space(int *n_spaces, hunits *desired_space)
{
if (!set) {
- assert(*nspaces > 0);
- if (*nspaces == 1) {
+ assert(*n_spaces > 0);
+ if (*n_spaces == 1) {
n += *desired_space;
*desired_space = H0;
}
else {
- hunits extra = *desired_space / *nspaces;
+ hunits extra = *desired_space / *n_spaces;
*desired_space -= extra;
n += extra;
}
- *nspaces -= 1;
+ *n_spaces -= 1;
set = 1;
}
}
@@ -3030,6 +3243,12 @@ void space_node::is_escape_colon()
was_escape_colon = 1;
}
+diverted_space_node::diverted_space_node(vunits d, statem *s, int pop,
+ node *p)
+: node(p, s, pop), n(d)
+{
+}
+
diverted_space_node::diverted_space_node(vunits d, node *p)
: node(p), n(d)
{
@@ -3037,7 +3256,13 @@ diverted_space_node::diverted_space_node(vunits d, node *p)
node *diverted_space_node::copy()
{
- return new diverted_space_node(n);
+ return new diverted_space_node(n, state, div_nest_level);
+}
+
+diverted_copy_file_node::diverted_copy_file_node(symbol s, statem *st,
+ int pop, node *p)
+: node(p, st, pop), filename(s)
+{
}
diverted_copy_file_node::diverted_copy_file_node(symbol s, node *p)
@@ -3047,7 +3272,7 @@ diverted_copy_file_node::diverted_copy_file_node(symbol s, node *p)
node *diverted_copy_file_node::copy()
{
- return new diverted_copy_file_node(filename);
+ return new diverted_copy_file_node(filename, state, div_nest_level);
}
int node::ends_sentence()
@@ -3338,8 +3563,15 @@ void hmotion_node::asciify(macro *m)
}
space_char_hmotion_node::space_char_hmotion_node(hunits i, color *c,
- node *next)
-: hmotion_node(i, c, next)
+ statem *s, int pop,
+ node *nxt)
+: hmotion_node(i, c, s, pop, nxt)
+{
+}
+
+space_char_hmotion_node::space_char_hmotion_node(hunits i, color *c,
+ node *nxt)
+: hmotion_node(i, c, 0, 0, nxt)
{
}
@@ -3393,14 +3625,14 @@ int node::nbreaks()
return 0;
}
-breakpoint *space_node::get_breakpoints(hunits width, int ns,
+breakpoint *space_node::get_breakpoints(hunits wd, int ns,
breakpoint *rest, int is_inner)
{
- if (next->discardable())
+ if (next && next->discardable())
return rest;
breakpoint *bp = new breakpoint;
bp->next = rest;
- bp->width = width;
+ bp->width = wd;
bp->nspaces = ns;
bp->hyphenated = 0;
if (is_inner) {
@@ -3417,7 +3649,7 @@ breakpoint *space_node::get_breakpoints(hunits width, int ns,
int space_node::nbreaks()
{
- if (next->discardable())
+ if (next && next->discardable())
return 0;
else
return 1;
@@ -3437,12 +3669,12 @@ static breakpoint *node_list_get_breakpoints(node *p, hunits *widthp,
return rest;
}
-breakpoint *dbreak_node::get_breakpoints(hunits width, int ns,
+breakpoint *dbreak_node::get_breakpoints(hunits wd, int ns,
breakpoint *rest, int is_inner)
{
breakpoint *bp = new breakpoint;
bp->next = rest;
- bp->width = width;
+ bp->width = wd;
for (node *tem = pre; tem != 0; tem = tem->next)
bp->width += tem->width();
bp->nspaces = ns;
@@ -3456,7 +3688,7 @@ breakpoint *dbreak_node::get_breakpoints(hunits width, int ns,
bp->nd = this;
bp->index = 0;
}
- return node_list_get_breakpoints(none, &width, ns, bp);
+ return node_list_get_breakpoints(none, &wd, ns, bp);
}
int dbreak_node::nbreaks()
@@ -3597,12 +3829,16 @@ special_node::special_node(const macro &m, int n)
tf = tf->get_plain();
gcol = curenv->get_glyph_color();
fcol = curenv->get_fill_color();
+ is_special = 1;
}
special_node::special_node(const macro &m, tfont *t,
- color *gc, color *fc, int n)
-: mac(m), tf(t), gcol(gc), fcol(fc), no_init_string(n)
+ color *gc, color *fc,
+ statem *s, int pop,
+ int n)
+: node(0, s, pop), mac(m), tf(t), gcol(gc), fcol(fc), no_init_string(n)
{
+ is_special = 1;
}
int special_node::same(node *n)
@@ -3629,9 +3865,15 @@ int special_node::force_tprint()
return 0;
}
+int special_node::is_tag()
+{
+ return 0;
+}
+
node *special_node::copy()
{
- return new special_node(mac, tf, gcol, fcol, no_init_string);
+ return new special_node(mac, tf, gcol, fcol, state, div_nest_level,
+ no_init_string);
}
void special_node::tprint_start(troff_output_file *out)
@@ -3657,20 +3899,22 @@ tfont *special_node::get_tfont()
/* suppress_node */
suppress_node::suppress_node(int on_or_off, int issue_limits)
-: is_on(on_or_off), emit_limits(issue_limits),
- filename(0), position(0), image_id(0)
+: is_on(on_or_off), emit_limits(issue_limits), filename(0), position(0),
+ image_id(0)
{
}
suppress_node::suppress_node(symbol f, char p, int id)
: is_on(2), emit_limits(0), filename(f), position(p), image_id(id)
{
+ is_special = 1;
}
suppress_node::suppress_node(int issue_limits, int on_or_off,
- symbol f, char p, int id)
-: is_on(on_or_off), emit_limits(issue_limits),
- filename(f), position(p), image_id(id)
+ symbol f, char p, int id,
+ statem *s, int pop)
+: node(0, s, pop), is_on(on_or_off), emit_limits(issue_limits), filename(f),
+ position(p), image_id(id)
{
}
@@ -3690,7 +3934,67 @@ const char *suppress_node::type()
node *suppress_node::copy()
{
- return new suppress_node(emit_limits, is_on, filename, position, image_id);
+ return new suppress_node(emit_limits, is_on, filename, position, image_id,
+ state, div_nest_level);
+}
+
+/* tag_node */
+
+tag_node::tag_node()
+: delayed(0)
+{
+ is_special = 1;
+}
+
+tag_node::tag_node(string s, int delay)
+: tag_string(s), delayed(delay)
+{
+ is_special = !delay;
+}
+
+tag_node::tag_node(string s, statem *st, int pop, int delay)
+: node(0, st, pop), tag_string(s), delayed(delay)
+{
+ is_special = !delay;
+}
+
+node *tag_node::copy()
+{
+ return new tag_node(tag_string, state, div_nest_level, delayed);
+}
+
+void tag_node::tprint(troff_output_file *out)
+{
+ if (delayed)
+ out->add_to_tag_list(tag_string);
+ else
+ out->state.add_tag(out->fp, tag_string);
+}
+
+int tag_node::same(node *nd)
+{
+ return tag_string == ((tag_node *)nd)->tag_string
+ && delayed == ((tag_node *)nd)->delayed;
+}
+
+const char *tag_node::type()
+{
+ return "tag_node";
+}
+
+int tag_node::force_tprint()
+{
+ return !delayed;
+}
+
+int tag_node::is_tag()
+{
+ return !delayed;
+}
+
+int tag_node::ends_sentence()
+{
+ return 2;
}
int get_reg_int(const char *p)
@@ -3761,10 +4065,10 @@ void suppress_node::tprint(troff_output_file *out)
if (is_on == 2) {
// remember position and filename
last_position = position;
- const char *tem = last_image_filename;
+ char *tem = (char *)last_image_filename;
last_image_filename = strsave(filename.contents());
if (tem)
- a_delete(tem);
+ a_delete tem;
last_image_id = image_id;
// printf("start of image and page = %d\n", current_page);
}
@@ -3774,20 +4078,23 @@ void suppress_node::tprint(troff_output_file *out)
char name[8192];
// remember that the filename will contain a %d in which the
// last_image_id is placed
- sprintf(name, last_image_filename, last_image_id);
+ if (last_image_filename == (char *) 0)
+ *name = '\0';
+ else
+ sprintf(name, last_image_filename, last_image_id);
if (is_html) {
switch (last_position) {
case 'c':
out->start_special();
- put(out, "html-tag:.centered-image");
+ put(out, "devtag:.centered-image");
break;
case 'r':
out->start_special();
- put(out, "html-tag:.right-image");
+ put(out, "devtag:.right-image");
break;
case 'l':
out->start_special();
- put(out, "html-tag:.left-image");
+ put(out, "devtag:.left-image");
break;
case 'i':
;
@@ -3796,7 +4103,7 @@ void suppress_node::tprint(troff_output_file *out)
}
out->end_special();
out->start_special();
- put(out, "html-tag:.auto-image ");
+ put(out, "devtag:.auto-image ");
put(out, name);
out->end_special();
}
@@ -3840,6 +4147,11 @@ int suppress_node::force_tprint()
return is_on;
}
+int suppress_node::is_tag()
+{
+ return is_on;
+}
+
hunits suppress_node::width()
{
return H0;
@@ -3851,7 +4163,7 @@ class composite_node : public charinfo_node {
node *n;
tfont *tf;
public:
- composite_node(node *, charinfo *, tfont *, node * = 0);
+ composite_node(node *, charinfo *, tfont *, statem *, int, node * = 0);
~composite_node();
node *copy();
hunits width();
@@ -3867,12 +4179,14 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
void vertical_extent(vunits *, vunits *);
vunits vertical_width();
};
-composite_node::composite_node(node *p, charinfo *c, tfont *t, node *x)
-: charinfo_node(c, x), n(p), tf(t)
+composite_node::composite_node(node *p, charinfo *c, tfont *t, statem *s,
+ int pop, node *x)
+: charinfo_node(c, s, pop, x), n(p), tf(t)
{
}
@@ -3883,7 +4197,7 @@ composite_node::~composite_node()
node *composite_node::copy()
{
- return new composite_node(copy_node_list(n), ci, tf);
+ return new composite_node(copy_node_list(n), ci, tf, state, div_nest_level);
}
hunits composite_node::width()
@@ -3983,10 +4297,10 @@ node *reverse_node_list(node *n)
return r;
}
-void composite_node::vertical_extent(vunits *min, vunits *max)
+void composite_node::vertical_extent(vunits *minimum, vunits *maximum)
{
n = reverse_node_list(n);
- node_list_vertical_extent(n, min, max);
+ node_list_vertical_extent(n, minimum, maximum);
n = reverse_node_list(n);
}
@@ -4006,8 +4320,8 @@ word_space_node::word_space_node(hunits d, color *c, width_list *w, node *x)
}
word_space_node::word_space_node(hunits d, int s, color *c, width_list *w,
- int flag, node *x)
-: space_node(d, s, 0, c, x), orig_width(w), unformat(flag)
+ int flag, statem *st, int pop, node *x)
+: space_node(d, s, 0, c, st, pop, x), orig_width(w), unformat(flag)
{
}
@@ -4033,7 +4347,8 @@ node *word_space_node::copy()
w_new_curr = w_new_curr->next;
w_old_curr = w_old_curr->next;
}
- return new word_space_node(n, set, col, w_new, unformat);
+ return new word_space_node(n, set, col, w_new, unformat, state,
+ div_nest_level);
}
int word_space_node::set_unformat_flag()
@@ -4066,14 +4381,15 @@ unbreakable_space_node::unbreakable_space_node(hunits d, color *c, node *x)
}
unbreakable_space_node::unbreakable_space_node(hunits d, int s,
- color *c, node *x)
-: word_space_node(d, s, c, 0, 0, x)
+ color *c, statem *st, int pop,
+ node *x)
+: word_space_node(d, s, c, 0, 0, st, pop, x)
{
}
node *unbreakable_space_node::copy()
{
- return new unbreakable_space_node(n, set, col);
+ return new unbreakable_space_node(n, set, col, state, div_nest_level);
}
int unbreakable_space_node::force_tprint()
@@ -4081,6 +4397,11 @@ int unbreakable_space_node::force_tprint()
return 0;
}
+int unbreakable_space_node::is_tag()
+{
+ return 0;
+}
+
breakpoint *unbreakable_space_node::get_breakpoints(hunits, int,
breakpoint *rest, int)
{
@@ -4115,6 +4436,15 @@ draw_node::draw_node(char c, hvpair *p, int np, font_size s,
point[i] = p[i];
}
+draw_node::draw_node(char c, hvpair *p, int np, font_size s,
+ color *gc, color *fc, statem *st, int pop)
+: node(0, st, pop), npoints(np), sz(s), gcol(gc), fcol(fc), code(c)
+{
+ point = new hvpair[npoints];
+ for (int i = 0; i < npoints; i++)
+ point[i] = p[i];
+}
+
int draw_node::same(node *n)
{
draw_node *nd = (draw_node *)n;
@@ -4137,6 +4467,11 @@ int draw_node::force_tprint()
return 0;
}
+int draw_node::is_tag()
+{
+ return 0;
+}
+
draw_node::~draw_node()
{
if (point)
@@ -4163,7 +4498,8 @@ vunits draw_node::vertical_width()
node *draw_node::copy()
{
- return new draw_node(code, point, npoints, sz, gcol, fcol);
+ return new draw_node(code, point, npoints, sz, gcol, fcol, state,
+ div_nest_level);
}
void draw_node::tprint(troff_output_file *out)
@@ -4498,7 +4834,7 @@ node *make_composite_node(charinfo *s, environment *env)
fontno);
if (env->is_composite())
tf = tf->get_plain();
- return new composite_node(n, s, tf);
+ return new composite_node(n, s, tf, 0, 0, 0);
}
node *make_glyph_node(charinfo *s, environment *env, int no_error_message = 0)
@@ -4584,7 +4920,7 @@ node *make_glyph_node(charinfo *s, environment *env, int no_error_message = 0)
tf = tf->get_plain();
color *gcol = env->get_glyph_color();
color *fcol = env->get_fill_color();
- return new glyph_node(s, tf, gcol, fcol);
+ return new glyph_node(s, tf, gcol, fcol, 0, 0);
}
node *make_node(charinfo *ci, environment *env)
@@ -4630,7 +4966,7 @@ int character_exists(charinfo *ci, environment *env)
}
node *node::add_char(charinfo *ci, environment *env,
- hunits *widthp, int *spacep)
+ hunits *widthp, int *spacep, node **glyph_comp_np)
{
node *res;
switch (ci->get_special_translation()) {
@@ -4660,9 +4996,14 @@ node *node::add_char(charinfo *ci, environment *env,
if (res) {
res->next = this;
*widthp += res->width();
+ if (glyph_comp_np)
+ *glyph_comp_np = res;
}
- else
+ else {
+ if (glyph_comp_np)
+ *glyph_comp_np = res;
return this;
+ }
}
else {
node *gn = make_glyph_node(ci, env);
@@ -4680,6 +5021,8 @@ node *node::add_char(charinfo *ci, environment *env,
*widthp += p->width() - old_width;
res = p;
}
+ if (glyph_comp_np)
+ *glyph_comp_np = res;
}
}
int break_code = 0;
@@ -4736,6 +5079,11 @@ int extra_size_node::force_tprint()
return 0;
}
+int extra_size_node::is_tag()
+{
+ return 0;
+}
+
int vertical_size_node::same(node *nd)
{
return n == ((vertical_size_node *)nd)->n;
@@ -4756,6 +5104,11 @@ int vertical_size_node::force_tprint()
return 0;
}
+int vertical_size_node::is_tag()
+{
+ return 0;
+}
+
int hmotion_node::same(node *nd)
{
return n == ((hmotion_node *)nd)->n
@@ -4778,9 +5131,14 @@ int hmotion_node::force_tprint()
return 0;
}
-node *hmotion_node::add_self(node *n, hyphen_list **p)
+int hmotion_node::is_tag()
{
- next = n;
+ return 0;
+}
+
+node *hmotion_node::add_self(node *nd, hyphen_list **p)
+{
+ next = nd;
hyphen_list *pp = *p;
*p = (*p)->next;
delete pp;
@@ -4808,9 +5166,14 @@ int space_char_hmotion_node::force_tprint()
return 0;
}
-node *space_char_hmotion_node::add_self(node *n, hyphen_list **p)
+int space_char_hmotion_node::is_tag()
{
- next = n;
+ return 0;
+}
+
+node *space_char_hmotion_node::add_self(node *nd, hyphen_list **p)
+{
+ next = nd;
hyphen_list *pp = *p;
*p = (*p)->next;
delete pp;
@@ -4839,6 +5202,11 @@ int vmotion_node::force_tprint()
return 0;
}
+int vmotion_node::is_tag()
+{
+ return 0;
+}
+
int hline_node::same(node *nd)
{
return x == ((hline_node *)nd)->x && same_node(n, ((hline_node *)nd)->n);
@@ -4854,6 +5222,11 @@ int hline_node::force_tprint()
return 0;
}
+int hline_node::is_tag()
+{
+ return 0;
+}
+
int vline_node::same(node *nd)
{
return x == ((vline_node *)nd)->x && same_node(n, ((vline_node *)nd)->n);
@@ -4869,6 +5242,11 @@ int vline_node::force_tprint()
return 0;
}
+int vline_node::is_tag()
+{
+ return 0;
+}
+
int dummy_node::same(node * /*nd*/)
{
return 1;
@@ -4884,6 +5262,11 @@ int dummy_node::force_tprint()
return 0;
}
+int dummy_node::is_tag()
+{
+ return 0;
+}
+
int transparent_dummy_node::same(node * /*nd*/)
{
return 1;
@@ -4899,6 +5282,11 @@ int transparent_dummy_node::force_tprint()
return 0;
}
+int transparent_dummy_node::is_tag()
+{
+ return 0;
+}
+
int transparent_dummy_node::ends_sentence()
{
return 2;
@@ -4919,6 +5307,11 @@ int zero_width_node::force_tprint()
return 0;
}
+int zero_width_node::is_tag()
+{
+ return 0;
+}
+
int italic_corrected_node::same(node *nd)
{
return (x == ((italic_corrected_node *)nd)->x
@@ -4935,8 +5328,19 @@ int italic_corrected_node::force_tprint()
return 0;
}
-left_italic_corrected_node::left_italic_corrected_node(node *x)
-: node(x), n(0)
+int italic_corrected_node::is_tag()
+{
+ return 0;
+}
+
+left_italic_corrected_node::left_italic_corrected_node(node *xx)
+: node(xx), n(0)
+{
+}
+
+left_italic_corrected_node::left_italic_corrected_node(statem *s, int pop,
+ node *xx)
+: node(xx, s, pop), n(0)
{
}
@@ -4968,7 +5372,8 @@ node *left_italic_corrected_node::merge_glyph_node(glyph_node *gn)
node *left_italic_corrected_node::copy()
{
- left_italic_corrected_node *nd = new left_italic_corrected_node;
+ left_italic_corrected_node *nd =
+ new left_italic_corrected_node(state, div_nest_level);
if (n) {
nd->n = n->copy();
nd->x = x;
@@ -4994,6 +5399,11 @@ int left_italic_corrected_node::force_tprint()
return 0;
}
+int left_italic_corrected_node::is_tag()
+{
+ return 0;
+}
+
int left_italic_corrected_node::same(node *nd)
{
return (x == ((left_italic_corrected_node *)nd)->x
@@ -5011,12 +5421,13 @@ hunits left_italic_corrected_node::width()
return n ? n->width() + x : H0;
}
-void left_italic_corrected_node::vertical_extent(vunits *min, vunits *max)
+void left_italic_corrected_node::vertical_extent(vunits *minimum,
+ vunits *maximum)
{
if (n)
- n->vertical_extent(min, max);
+ n->vertical_extent(minimum, maximum);
else
- node::vertical_extent(min, max);
+ node::vertical_extent(minimum, maximum);
}
hunits left_italic_corrected_node::skew()
@@ -5076,7 +5487,7 @@ hyphen_list *left_italic_corrected_node::get_hyphen_list(hyphen_list *tail,
node *left_italic_corrected_node::add_self(node *nd, hyphen_list **p)
{
if (n) {
- nd = new left_italic_corrected_node(nd);
+ nd = new left_italic_corrected_node(state, div_nest_level, nd);
nd = n->add_self(nd, p);
n = 0;
delete this;
@@ -5104,6 +5515,11 @@ int overstrike_node::force_tprint()
return 0;
}
+int overstrike_node::is_tag()
+{
+ return 0;
+}
+
node *overstrike_node::add_self(node *n, hyphen_list **p)
{
next = n;
@@ -5133,6 +5549,11 @@ int bracket_node::force_tprint()
return 0;
}
+int bracket_node::is_tag()
+{
+ return 0;
+}
+
int composite_node::same(node *nd)
{
return ci == ((composite_node *)nd)->ci
@@ -5149,6 +5570,11 @@ int composite_node::force_tprint()
return 0;
}
+int composite_node::is_tag()
+{
+ return 0;
+}
+
int glyph_node::same(node *nd)
{
return ci == ((glyph_node *)nd)->ci
@@ -5167,6 +5593,11 @@ int glyph_node::force_tprint()
return 0;
}
+int glyph_node::is_tag()
+{
+ return 0;
+}
+
int ligature_node::same(node *nd)
{
return (same_node(n1, ((ligature_node *)nd)->n1)
@@ -5184,6 +5615,11 @@ int ligature_node::force_tprint()
return 0;
}
+int ligature_node::is_tag()
+{
+ return 0;
+}
+
int kern_pair_node::same(node *nd)
{
return (amount == ((kern_pair_node *)nd)->amount
@@ -5201,6 +5637,11 @@ int kern_pair_node::force_tprint()
return 0;
}
+int kern_pair_node::is_tag()
+{
+ return 0;
+}
+
int dbreak_node::same(node *nd)
{
return (same_node_list(none, ((dbreak_node *)nd)->none)
@@ -5218,6 +5659,11 @@ int dbreak_node::force_tprint()
return 0;
}
+int dbreak_node::is_tag()
+{
+ return 0;
+}
+
int break_char_node::same(node *nd)
{
return break_code == ((break_char_node *)nd)->break_code
@@ -5235,6 +5681,11 @@ int break_char_node::force_tprint()
return 0;
}
+int break_char_node::is_tag()
+{
+ return 0;
+}
+
int line_start_node::same(node * /*nd*/)
{
return 1;
@@ -5250,6 +5701,11 @@ int line_start_node::force_tprint()
return 0;
}
+int line_start_node::is_tag()
+{
+ return 0;
+}
+
int space_node::same(node *nd)
{
return n == ((space_node *)nd)->n
@@ -5279,6 +5735,11 @@ int word_space_node::force_tprint()
return 0;
}
+int word_space_node::is_tag()
+{
+ return 0;
+}
+
void unbreakable_space_node::tprint(troff_output_file *out)
{
out->fill_color(col);
@@ -5305,9 +5766,9 @@ const char *unbreakable_space_node::type()
return "unbreakable_space_node";
}
-node *unbreakable_space_node::add_self(node *n, hyphen_list **p)
+node *unbreakable_space_node::add_self(node *nd, hyphen_list **p)
{
- next = n;
+ next = nd;
hyphen_list *pp = *p;
*p = (*p)->next;
delete pp;
@@ -5334,6 +5795,11 @@ int diverted_space_node::force_tprint()
return 0;
}
+int diverted_space_node::is_tag()
+{
+ return 0;
+}
+
int diverted_copy_file_node::same(node *nd)
{
return filename == ((diverted_copy_file_node *)nd)->filename;
@@ -5349,6 +5815,11 @@ int diverted_copy_file_node::force_tprint()
return 0;
}
+int diverted_copy_file_node::is_tag()
+{
+ return 0;
+}
+
// Grow the font_table so that its size is > n.
static void grow_font_table(int n)
@@ -5378,7 +5849,8 @@ static symbol get_font_translation(symbol nm)
dictionary font_dictionary(50);
-static int mount_font_no_translate(int n, symbol name, symbol external_name)
+static int mount_font_no_translate(int n, symbol name, symbol external_name,
+ int check_only = 0)
{
assert(n >= 0);
// We store the address of this char in font_dictionary to indicate
@@ -5388,7 +5860,9 @@ static int mount_font_no_translate(int n, symbol name, symbol external_name)
void *p = font_dictionary.lookup(external_name);
if (p == 0) {
int not_found;
- fm = font::load_font(external_name.contents(), &not_found);
+ fm = font::load_font(external_name.contents(), &not_found, check_only);
+ if (check_only)
+ return fm != 0;
if (!fm) {
if (not_found)
warning(WARN_FONT, "can't find font `%1'", external_name.contents());
@@ -5405,6 +5879,8 @@ static int mount_font_no_translate(int n, symbol name, symbol external_name)
}
else
fm = (font*)p;
+ if (check_only)
+ return 1;
if (n >= font_table_size) {
if (n - font_table_size > 1000) {
error("font position too much larger than first unused position");
@@ -5430,6 +5906,19 @@ int mount_font(int n, symbol name, symbol external_name)
return mount_font_no_translate(n, name, external_name);
}
+int check_font(symbol fam, symbol name)
+{
+ if (check_style(name))
+ name = concat(fam, name);
+ return mount_font_no_translate(0, name, name, 1);
+}
+
+int check_style(symbol s)
+{
+ int i = symbol_fontno(s);
+ return i < 0 ? 0 : font_table[i]->is_style();
+}
+
void mount_style(int n, symbol name)
{
assert(n >= 0);
@@ -5555,13 +6044,13 @@ void font_family::invalidate_fontno(int n)
{
assert(n >= 0 && n < font_table_size);
dictionary_iterator iter(family_dictionary);
- symbol nm;
+ symbol nam;
font_family *fam;
- while (iter.get(&nm, (void **)&fam)) {
- int map_size = fam->map_size;
- if (n < map_size)
+ while (iter.get(&nam, (void **)&fam)) {
+ int mapsize = fam->map_size;
+ if (n < mapsize)
fam->map[n] = -1;
- for (int i = 0; i < map_size; i++)
+ for (int i = 0; i < mapsize; i++)
if (fam->map[i] == n)
fam->map[i] = -1;
}
diff --git a/contrib/groff/src/roff/troff/node.h b/contrib/groff/src/roff/troff/node.h
index 54f8822..c7c8b41 100644
--- a/contrib/groff/src/roff/troff/node.h
+++ b/contrib/groff/src/roff/troff/node.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,8 +17,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
struct hyphen_list {
unsigned char hyphen;
@@ -36,7 +35,7 @@ class ascii_output_file;
struct breakpoint;
struct vertical_size;
-struct charinfo;
+class charinfo;
class macro;
@@ -51,14 +50,20 @@ class token_node;
struct node {
node *next;
node *last;
+ statem *state;
+ statem *push_state;
+ int div_nest_level;
+ int is_special;
node();
- node(node *n);
- node *add_char(charinfo *c, environment *, hunits *widthp, int *spacep);
+ node(node *);
+ node(node *, statem *, int);
+ node *add_char(charinfo *, environment *, hunits *, int *, node ** = 0);
virtual ~node();
virtual node *copy() = 0;
virtual int set_unformat_flag();
virtual int force_tprint() = 0;
+ virtual int is_tag() = 0;
virtual hunits width();
virtual hunits subscript_correction();
virtual hunits italic_correction();
@@ -68,7 +73,7 @@ struct node {
virtual int merge_space(hunits, hunits, hunits);
virtual vunits vertical_width();
virtual node *last_char_node();
- virtual void vertical_extent(vunits *min, vunits *max);
+ virtual void vertical_extent(vunits *, vunits *);
virtual int character_type();
virtual void set_vertical_size(vertical_size *);
virtual int ends_sentence();
@@ -82,9 +87,7 @@ struct node {
virtual void spread_space(int *, hunits *);
virtual void freeze_space();
virtual void is_escape_colon();
- virtual breakpoint *get_breakpoints(hunits width, int nspaces,
- breakpoint *rest = 0,
- int is_inner = 0);
+ virtual breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
virtual int nbreaks();
virtual void split(int, node **, node **);
virtual hyphenation_type get_hyphenation_type();
@@ -106,16 +109,27 @@ struct node {
virtual int same(node *) = 0;
virtual const char *type() = 0;
+ virtual void debug_node();
+ virtual void debug_node_list();
};
inline node::node()
-: next(0), last(0)
+: next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
{
}
inline node::node(node *n)
-: next(n), last(0)
+: next(n), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
+{
+}
+
+inline node::node(node *n, statem *s, int divlevel)
+: next(n), last(0), push_state(0), div_nest_level(divlevel), is_special(0)
{
+ if (s)
+ state = new statem(s);
+ else
+ state = 0;
}
inline node::~node()
@@ -141,6 +155,7 @@ public:
node *copy() { return new line_start_node; }
int same(node *);
int force_tprint();
+ int is_tag();
const char *type();
void asciify(macro *);
};
@@ -157,8 +172,9 @@ protected:
char set;
char was_escape_colon;
color *col; /* for grotty */
- space_node(hunits, int, int, color *, node * = 0);
+ space_node(hunits, int, int, color *, statem *, int, node * = 0);
public:
+ space_node(hunits, color *, statem *, int, node * = 0);
space_node(hunits, color *, node * = 0);
#if 0
~space_node();
@@ -173,8 +189,7 @@ public:
void is_escape_colon();
void spread_space(int *, hunits *);
void tprint(troff_output_file *);
- breakpoint *get_breakpoints(hunits width, int nspaces, breakpoint *rest = 0,
- int is_inner = 0);
+ breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
int nbreaks();
void split(int, node **, node **);
void ascii_print(ascii_output_file *);
@@ -182,6 +197,7 @@ public:
void asciify(macro *);
const char *type();
int force_tprint();
+ int is_tag();
hyphenation_type get_hyphenation_type();
};
@@ -197,7 +213,8 @@ class word_space_node : public space_node {
protected:
width_list *orig_width;
unsigned char unformat;
- word_space_node(hunits, int, color *, width_list *, int, node * = 0);
+ word_space_node(hunits, int, color *, width_list *, int, statem *, int,
+ node * = 0);
public:
word_space_node(hunits, color *, width_list *, node * = 0);
~word_space_node();
@@ -210,10 +227,11 @@ public:
const char *type();
int merge_space(hunits, hunits, hunits);
int force_tprint();
+ int is_tag();
};
class unbreakable_space_node : public word_space_node {
- unbreakable_space_node(hunits, int, color *, node * = 0);
+ unbreakable_space_node(hunits, int, color *, statem *, int, node * = 0);
public:
unbreakable_space_node(hunits, color *, node * = 0);
node *copy();
@@ -223,8 +241,8 @@ public:
void asciify(macro *);
const char *type();
int force_tprint();
- breakpoint *get_breakpoints(hunits width, int nspaces, breakpoint *rest = 0,
- int is_inner = 0);
+ int is_tag();
+ breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
int nbreaks();
void split(int, node **, node **);
int merge_space(hunits, hunits, hunits);
@@ -236,41 +254,48 @@ public:
class diverted_space_node : public node {
public:
vunits n;
- diverted_space_node(vunits d, node *p = 0);
+ diverted_space_node(vunits, node * = 0);
+ diverted_space_node(vunits, statem *, int, node * = 0);
node *copy();
int reread(int *);
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class diverted_copy_file_node : public node {
symbol filename;
public:
vunits n;
- diverted_copy_file_node(symbol s, node *p = 0);
+ diverted_copy_file_node(symbol, node * = 0);
+ diverted_copy_file_node(symbol, statem *, int, node * = 0);
node *copy();
int reread(int *);
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class extra_size_node : public node {
vunits n;
public:
- extra_size_node(vunits i) : n(i) {}
+ extra_size_node(vunits);
+ extra_size_node(vunits, statem *, int);
void set_vertical_size(vertical_size *);
node *copy();
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class vertical_size_node : public node {
vunits n;
public:
- vertical_size_node(vunits i) : n(i) {}
+ vertical_size_node(vunits, statem *, int);
+ vertical_size_node(vunits);
void set_vertical_size(vertical_size *);
void asciify(macro *);
node *copy();
@@ -278,6 +303,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class hmotion_node : public node {
@@ -287,10 +313,16 @@ protected:
unsigned char unformat;
color *col; /* for grotty */
public:
- hmotion_node(hunits i, color *c, node *next = 0)
- : node(next), n(i), was_tab(0), unformat(0), col(c) {}
- hmotion_node(hunits i, int flag1, int flag2, color *c, node *next = 0)
- : node(next), n(i), was_tab(flag1), unformat(flag2), col(c) {}
+ hmotion_node(hunits i, color *c, node *nxt = 0)
+ : node(nxt), n(i), was_tab(0), unformat(0), col(c) {}
+ hmotion_node(hunits i, color *c, statem *s, int divlevel, node *nxt = 0)
+ : node(nxt, s, divlevel), n(i), was_tab(0), unformat(0), col(c) {}
+ hmotion_node(hunits i, int flag1, int flag2, color *c, statem *s,
+ int divlevel, node *nxt = 0)
+ : node(nxt, s, divlevel), n(i), was_tab(flag1), unformat(flag2),
+ col(c) {}
+ hmotion_node(hunits i, int flag1, int flag2, color *c, node *nxt = 0)
+ : node(nxt), n(i), was_tab(flag1), unformat(flag2), col(c) {}
node *copy();
int reread(int *);
int set_unformat_flag();
@@ -301,6 +333,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
node *add_self(node *, hyphen_list **);
hyphen_list *get_hyphen_list(hyphen_list *, int *);
hyphenation_type get_hyphenation_type();
@@ -309,6 +342,7 @@ public:
class space_char_hmotion_node : public hmotion_node {
public:
space_char_hmotion_node(hunits, color *, node * = 0);
+ space_char_hmotion_node(hunits, color *, statem *, int, node * = 0);
node *copy();
void ascii_print(ascii_output_file *);
void asciify(macro *);
@@ -316,6 +350,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
node *add_self(node *, hyphen_list **);
hyphen_list *get_hyphen_list(hyphen_list *, int *);
hyphenation_type get_hyphenation_type();
@@ -325,20 +360,23 @@ class vmotion_node : public node {
vunits n;
color *col; /* for grotty */
public:
- vmotion_node(vunits i, color *c) : n(i), col(c) {}
+ vmotion_node(vunits, color *);
+ vmotion_node(vunits, color *, statem *, int);
void tprint(troff_output_file *);
node *copy();
vunits vertical_width();
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class hline_node : public node {
hunits x;
node *n;
public:
- hline_node(hunits i, node *c, node *next = 0) : node(next), x(i), n(c) {}
+ hline_node(hunits, node *, node * = 0);
+ hline_node(hunits, node *, statem *, int, node * = 0);
~hline_node();
node *copy();
hunits width();
@@ -346,13 +384,15 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class vline_node : public node {
vunits x;
node *n;
public:
- vline_node(vunits i, node *c, node *next= 0) : node(next), x(i), n(c) {}
+ vline_node(vunits, node *, node * = 0);
+ vline_node(vunits, node *, statem *, int, node * = 0);
~vline_node();
node *copy();
void tprint(troff_output_file *);
@@ -362,9 +402,9 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
-
class dummy_node : public node {
public:
dummy_node(node *nd = 0) : node(nd) {}
@@ -372,6 +412,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
hyphenation_type get_hyphenation_type();
};
@@ -382,6 +423,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
int ends_sentence();
hyphenation_type get_hyphenation_type();
};
@@ -389,16 +431,18 @@ public:
class zero_width_node : public node {
node *n;
public:
- zero_width_node(node *gn);
+ zero_width_node(node *);
+ zero_width_node(node *, statem *, int);
~zero_width_node();
node *copy();
void tprint(troff_output_file *);
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
void append(node *);
int character_type();
- void vertical_extent(vunits *min, vunits *max);
+ void vertical_extent(vunits *, vunits *);
};
class left_italic_corrected_node : public node {
@@ -406,6 +450,7 @@ class left_italic_corrected_node : public node {
hunits x;
public:
left_italic_corrected_node(node * = 0);
+ left_italic_corrected_node(statem *, int, node * = 0);
~left_italic_corrected_node();
void tprint(troff_output_file *);
void ascii_print(ascii_output_file *);
@@ -414,6 +459,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
hunits width();
node *last_char_node();
void vertical_extent(vunits *, vunits *);
@@ -436,6 +482,7 @@ class overstrike_node : public node {
hunits max_width;
public:
overstrike_node();
+ overstrike_node(statem *, int);
~overstrike_node();
node *copy();
void tprint(troff_output_file *);
@@ -444,6 +491,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
node *add_self(node *, hyphen_list **);
hyphen_list *get_hyphen_list(hyphen_list *, int *);
hyphenation_type get_hyphenation_type();
@@ -454,6 +502,7 @@ class bracket_node : public node {
hunits max_width;
public:
bracket_node();
+ bracket_node(statem *, int);
~bracket_node();
node *copy();
void tprint(troff_output_file *);
@@ -462,6 +511,7 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class special_node : public node {
@@ -475,12 +525,14 @@ class special_node : public node {
void tprint_end(troff_output_file *);
public:
special_node(const macro &, int = 0);
- special_node(const macro &, tfont *, color *, color *, int = 0);
+ special_node(const macro &, tfont *, color *, color *, statem *, int,
+ int = 0);
node *copy();
void tprint(troff_output_file *);
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
int ends_sentence();
tfont *get_tfont();
};
@@ -493,16 +545,34 @@ class suppress_node : public node {
int image_id;
public:
suppress_node(int, int);
- suppress_node(symbol f, char p, int id);
- suppress_node(int, int, symbol f, char p, int id);
+ suppress_node(symbol, char, int);
+ suppress_node(int, int, symbol, char, int, statem *, int);
+ suppress_node(int, int, symbol, char, int);
node *copy();
void tprint(troff_output_file *);
hunits width();
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
private:
- void put(troff_output_file *out, const char *s);
+ void put(troff_output_file *, const char *);
+};
+
+class tag_node : public node {
+public:
+ string tag_string;
+ int delayed;
+ tag_node();
+ tag_node(string, int);
+ tag_node(string, statem *, int, int);
+ node *copy();
+ void tprint(troff_output_file *);
+ int same(node *);
+ const char *type();
+ int force_tprint();
+ int is_tag();
+ int ends_sentence();
};
struct hvpair {
@@ -520,6 +590,7 @@ class draw_node : public node {
hvpair *point;
public:
draw_node(char, hvpair *, int, font_size, color *, color *);
+ draw_node(char, hvpair *, int, font_size, color *, color *, statem *, int);
~draw_node();
hunits width();
vunits vertical_width();
@@ -528,18 +599,19 @@ public:
int same(node *);
const char *type();
int force_tprint();
+ int is_tag();
};
class charinfo;
-node *make_node(charinfo *ci, environment *);
+node *make_node(charinfo *, environment *);
int character_exists(charinfo *, environment *);
-int same_node_list(node *n1, node *n2);
-node *reverse_node_list(node *n);
+int same_node_list(node *, node *);
+node *reverse_node_list(node *);
void delete_node_list(node *);
node *copy_node_list(node *);
-int get_bold_fontno(int f);
+int get_bold_fontno(int);
inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p)
: hyphen(0), breakable(0), hyphenation_code(code), next(p)
@@ -547,9 +619,11 @@ inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p)
}
extern void read_desc();
-extern int mount_font(int n, symbol, symbol = NULL_SYMBOL);
-extern void mount_style(int n, symbol);
-extern int is_good_fontno(int n);
+extern int mount_font(int, symbol, symbol = NULL_SYMBOL);
+extern int check_font(symbol, symbol);
+extern int check_style(symbol);
+extern void mount_style(int, symbol);
+extern int is_good_fontno(int);
extern int symbol_fontno(symbol);
extern int next_available_font_position();
extern void init_size_table(int *);
@@ -560,7 +634,7 @@ class output_file {
public:
output_file();
virtual ~output_file();
- virtual void trailer(vunits page_length);
+ virtual void trailer(vunits);
virtual void flush() = 0;
virtual void transparent_char(unsigned char) = 0;
virtual void print_line(hunits x, vunits y, node *n,
@@ -568,12 +642,13 @@ public:
virtual void begin_page(int pageno, vunits page_length) = 0;
virtual void copy_file(hunits x, vunits y, const char *filename) = 0;
virtual int is_printing() = 0;
- virtual void put_filename(const char *filename);
+ virtual void put_filename(const char *);
virtual void on();
virtual void off();
#ifdef COLUMN
virtual void vjustify(vunits, symbol);
#endif /* COLUMN */
+ mtsm state;
};
#ifndef POPEN_MISSING
@@ -582,7 +657,7 @@ extern char *pipe_command;
extern output_file *the_output;
extern void init_output();
-int in_output_page_list(int n);
+int in_output_page_list(int);
class font_family {
int *map;
@@ -597,3 +672,5 @@ public:
font_family *lookup_family(symbol);
symbol get_font_name(int, environment *);
+symbol get_style_name(int);
+extern search_path include_search_path;
diff --git a/contrib/groff/src/roff/troff/number.cpp b/contrib/groff/src/roff/troff/number.cpp
index 8fed342..0a4563e 100644
--- a/contrib/groff/src/roff/troff/number.cpp
+++ b/contrib/groff/src/roff/troff/number.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,12 +17,13 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "troff.h"
-#include "symbol.h"
#include "hvunits.h"
+#include "stringclass.h"
+#include "mtsm.h"
#include "env.h"
#include "token.h"
#include "div.h"
diff --git a/contrib/groff/src/roff/troff/reg.cpp b/contrib/groff/src/roff/troff/reg.cpp
index 8ac20c9..4501090 100644
--- a/contrib/groff/src/roff/troff/reg.cpp
+++ b/contrib/groff/src/roff/troff/reg.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,10 +17,9 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "troff.h"
-#include "symbol.h"
#include "dictionary.h"
#include "token.h"
#include "request.h"
diff --git a/contrib/groff/src/roff/troff/reg.h b/contrib/groff/src/roff/troff/reg.h
index 950be4f..bc2c3f2 100644
--- a/contrib/groff/src/roff/troff/reg.h
+++ b/contrib/groff/src/roff/troff/reg.h
@@ -17,7 +17,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
class reg : public object {
diff --git a/contrib/groff/src/roff/troff/request.h b/contrib/groff/src/roff/troff/request.h
index 0433ac1..24d2589 100644
--- a/contrib/groff/src/roff/troff/request.h
+++ b/contrib/groff/src/roff/troff/request.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,7 +17,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
typedef void (*REQUEST_FUNCP)();
@@ -41,19 +41,21 @@ void delete_request_or_macro(request_or_macro *);
extern object_dictionary request_dictionary;
-struct macro_header;
+class macro_header;
struct node;
class macro : public request_or_macro {
- macro_header *p;
const char *filename; // where was it defined?
int lineno;
int len;
int empty_macro;
+ int is_a_diversion;
public:
+ macro_header *p;
macro();
~macro();
macro(const macro &);
+ macro(int);
macro &operator=(const macro &);
void append(unsigned char);
void append(node *);
@@ -67,6 +69,7 @@ public:
macro *to_macro();
void print_size();
int empty();
+ int is_diversion();
friend class string_iterator;
friend void chop_macro();
friend void substring_request();
diff --git a/contrib/groff/src/roff/troff/token.h b/contrib/groff/src/roff/troff/token.h
index 9f5b069..6493976 100644
--- a/contrib/groff/src/roff/troff/token.h
+++ b/contrib/groff/src/roff/troff/token.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,12 +17,12 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
-struct charinfo;
+class charinfo;
struct node;
-struct vunits;
+class vunits;
class token {
symbol nm;
@@ -121,7 +121,7 @@ enum char_mode {
extern void do_define_character(char_mode, const char * = 0);
-struct hunits;
+class hunits;
extern void read_title_parts(node **part, hunits *part_width);
extern int get_number_rigidly(units *result, unsigned char si);
diff --git a/contrib/groff/src/roff/troff/troff.h b/contrib/groff/src/roff/troff/troff.h
index 80d9f0b..661b3ed 100644
--- a/contrib/groff/src/roff/troff/troff.h
+++ b/contrib/groff/src/roff/troff/troff.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -17,7 +17,7 @@ for more details.
You should have received a copy of the GNU General Public License along
with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "lib.h"
@@ -33,8 +33,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "device.h"
#include "searchpath.h"
-void cleanup_and_exit(int n);
-
typedef int units;
extern units scale(units n, units x, units y); // scale n by x/y
@@ -82,7 +80,7 @@ enum warning_type {
// change WARN_TOTAL if you add more warning types
};
-const int WARN_TOTAL = 02777777;
+const int WARN_TOTAL = 03777777;
int warning(warning_type, const char *,
const errarg & = empty_errarg,
diff --git a/contrib/groff/src/roff/troff/troff.man b/contrib/groff/src/roff/troff/troff.man
index dce81dd..064a03f 100644
--- a/contrib/groff/src/roff/troff/troff.man
+++ b/contrib/groff/src/roff/troff/troff.man
@@ -2,11 +2,11 @@
.ig
troff.man
-Last update : 09 Dec 2002
+Last update : 12 Oct 2003
This file is part of groff, the GNU roff type-setting system.
-Copyright (C) 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
+Copyright (C) 1989, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
written by James Clark
@@ -28,6 +28,9 @@ FDL in the main directory of the groff source package.
.\" Setup
.\" --------------------------------------------------------------------
.
+.do nr troff_C \n[.C]
+.cp 0
+.
.mso www.tmac
.
.if n \{\
@@ -81,6 +84,7 @@ FDL in the main directory of the groff source package.
.OP \-d cs
.OP \-f fam
.OP \-F dir
+.OP \-I dir
.OP \-m name
.OP \-M dir
.OP \-n num
@@ -195,6 +199,17 @@ Read the standard input after all the named input files have been
processed.
.
.TP
+.BI \-I dir
+This option may be used to specify a directory to search for
+files (both those on the command line and those named in
+.B \&.psbb
+requests).
+The current directory is always searched first.
+This option may be specified more than once;
+the directories will be searched in the order specified.
+No directory search is performed for files specified using an absolute path.
+.
+.TP
.BI \-m name
Read in the file
.IB name .tmac\fR.
@@ -607,7 +622,7 @@ necessary.
.SH AUTHOR
.\" --------------------------------------------------------------------
.
-Copyright (C) 1989, 2001, 2002 Free Software Foundation, Inc.
+Copyright (C) 1989, 2001, 2002, 2003 Free Software Foundation, Inc.
.
.P
This document is distributed under the terms of the FDL (GNU Free
@@ -679,6 +694,7 @@ cf.\&
.BR info (@MAN1EXT@),
presents all groff documentation within a single document.
.
+.cp \n[troff_C]
.
.\" --------------------------------------------------------------------
.\" Emacs variables
OpenPOWER on IntegriCloud