summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/groff/troff/div.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/groff/troff/div.cc')
-rw-r--r--gnu/usr.bin/groff/troff/div.cc1131
1 files changed, 0 insertions, 1131 deletions
diff --git a/gnu/usr.bin/groff/troff/div.cc b/gnu/usr.bin/groff/troff/div.cc
deleted file mode 100644
index f82d838..0000000
--- a/gnu/usr.bin/groff/troff/div.cc
+++ /dev/null
@@ -1,1131 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-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, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-// diversions
-
-#include "troff.h"
-#include "symbol.h"
-#include "dictionary.h"
-#include "hvunits.h"
-#include "env.h"
-#include "request.h"
-#include "node.h"
-#include "token.h"
-#include "div.h"
-#include "reg.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
-int last_page_number = 0; // if > 0, the number of the last page
- // specified with -o
-static int began_page_in_end_macro = 0; // a new page was begun during the end macro
-
-static int last_post_line_extra_space = 0; // needed for \n(.a
-static int nl_reg_contents = -1;
-static int dl_reg_contents = 0;
-static int dn_reg_contents = 0;
-static int vertical_position_traps_flag = 1;
-static vunits truncated_space;
-static vunits needed_space;
-
-diversion::diversion(symbol s)
-: nm(s), prev(0), vertical_position(V0), marked_place(V0), high_water_mark(V0)
-{
-}
-
-struct vertical_size {
- vunits pre_extra, post_extra, pre, post;
- vertical_size(vunits vs, int ls);
-};
-
-vertical_size::vertical_size(vunits vs, int ls)
-: pre_extra(V0), post_extra(V0), pre(vs)
-{
- if (ls > 1)
- post = vs*(ls - 1);
- else
- post = V0;
-}
-
-void node::set_vertical_size(vertical_size *)
-{
-}
-
-void extra_size_node::set_vertical_size(vertical_size *v)
-{
- if (n < V0) {
- if (-n > v->pre_extra)
- v->pre_extra = -n;
- }
- else if (n > v->post_extra)
- v->post_extra = n;
-}
-
-void vertical_size_node::set_vertical_size(vertical_size *v)
-{
- if (n < V0)
- v->pre = -n;
- else
- v->post = n;
-}
-
-top_level_diversion *topdiv;
-
-diversion *curdiv;
-
-void do_divert(int append)
-{
- tok.skip();
- symbol nm = get_name();
- if (nm.is_null()) {
- if (curdiv->prev) {
- diversion *temp = curdiv;
- curdiv = curdiv->prev;
- delete temp;
- }
- else
- warning(WARN_DI, "diversion stack underflow");
- }
- else {
- macro_diversion *md = new macro_diversion(nm, append);
- md->prev = curdiv;
- curdiv = md;
- }
- skip_line();
-}
-
-void divert()
-{
- do_divert(0);
-}
-
-void divert_append()
-{
- do_divert(1);
-}
-
-void diversion::need(vunits n)
-{
- vunits d = distance_to_next_trap();
- if (d < n) {
- space(d, 1);
- truncated_space = -d;
- needed_space = n;
- }
-}
-
-macro_diversion::macro_diversion(symbol s, int append)
-: diversion(s), max_width(H0)
-{
-#if 0
- if (append) {
- /* We don't allow recursive appends eg:
-
- .da a
- .a
- .di
-
- This causes an infinite loop in troff anyway.
- This is because the user could do
-
- .as a foo
-
- in the diversion, and this would mess things up royally,
- since there would be two things appending to the same
- macro_header.
- To make it work, we would have to copy the _contents_
- of the macro into which we were diverting; this doesn't
- strike me as worthwhile.
- However,
-
- .di a
- .a
- .a
- .di
-
- will work and will make `a' contain two copies of what it contained
- before; in troff, `a' would contain nothing. */
- request_or_macro *rm
- = (request_or_macro *)request_dictionary.remove(s);
- if (!rm || (mac = rm->to_macro()) == 0)
- mac = new macro;
- }
- else
- mac = new macro;
-#endif
- // 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;
- if (append) {
- request_or_macro *rm
- = (request_or_macro *)request_dictionary.lookup(s);
- if (rm) {
- macro *m = rm->to_macro();
- if (m)
- *mac = *m;
- }
- }
-}
-
-macro_diversion::~macro_diversion()
-{
- request_or_macro *rm = (request_or_macro *)request_dictionary.lookup(nm);
- macro *m = rm ? rm->to_macro() : 0;
- if (m) {
- *m = *mac;
- delete mac;
- }
- else
- request_dictionary.define(nm, mac);
- mac = 0;
- dl_reg_contents = max_width.to_units();
- dn_reg_contents = vertical_position.to_units();
-}
-
-vunits macro_diversion::distance_to_next_trap()
-{
- if (!diversion_trap.is_null() && diversion_trap_pos > vertical_position)
- return diversion_trap_pos - vertical_position;
- else
- // Substract vresolution so that vunits::vunits does not overflow.
- return vunits(INT_MAX - vresolution);
-}
-
-void macro_diversion::transparent_output(unsigned char c)
-{
- mac->append(c);
-}
-
-void macro_diversion::transparent_output(node *n)
-{
- mac->append(n);
-}
-
-void macro_diversion::output(node *nd, int retain_size,
- vunits vs, int ls, hunits width)
-{
- vertical_size v(vs, ls);
- while (nd != 0) {
- nd->set_vertical_size(&v);
- node *temp = nd;
- nd = nd->next;
- if (temp->interpret(mac)) {
- delete temp;
- }
- else {
-#if 1
- temp->freeze_space();
-#endif
- mac->append(temp);
- }
- }
- if (!v.post_extra.is_zero())
- last_post_line_extra_space = v.post_extra.to_units();
- if (!retain_size) {
- v.pre = vs;
- v.post = (ls > 1) ? vs*(ls - 1) : V0;
- }
- if (width > max_width)
- max_width = width;
- vunits x = v.pre + v.pre_extra + v.post + v.post_extra;
- if (vertical_position_traps_flag
- && !diversion_trap.is_null() && diversion_trap_pos > vertical_position
- && diversion_trap_pos <= vertical_position + x) {
- vunits trunc = vertical_position + x - diversion_trap_pos;
- if (trunc > v.post)
- trunc = v.post;
- v.post -= trunc;
- x -= trunc;
- truncated_space = trunc;
- spring_trap(diversion_trap);
- }
- mac->append(new vertical_size_node(-v.pre));
- mac->append(new vertical_size_node(v.post));
- mac->append('\n');
- vertical_position += x;
- if (vertical_position - v.post > high_water_mark)
- high_water_mark = vertical_position - v.post;
-}
-
-void macro_diversion::space(vunits n, int)
-{
- if (vertical_position_traps_flag
- && !diversion_trap.is_null() && diversion_trap_pos > vertical_position
- && diversion_trap_pos <= vertical_position + n) {
- truncated_space = vertical_position + n - diversion_trap_pos;
- n = diversion_trap_pos - vertical_position;
- spring_trap(diversion_trap);
- }
- else if (n + vertical_position < V0)
- n = -vertical_position;
- mac->append(new diverted_space_node(n));
- vertical_position += n;
-}
-
-void macro_diversion::copy_file(const char *filename)
-{
- mac->append(new diverted_copy_file_node(filename));
-}
-
-top_level_diversion::top_level_diversion()
-: page_count(0), have_next_page_number(0), page_length(units_per_inch*11),
- page_offset(units_per_inch), prev_page_offset(units_per_inch),
- ejecting_page(0), page_trap_list(0), before_first_page(1), no_space_mode(0),
- page_number(0), last_page_count(-1)
-{
-}
-
-// find the next trap after pos
-
-trap *top_level_diversion::find_next_trap(vunits *next_trap_pos)
-{
- trap *next_trap = 0;
- for (trap *pt = page_trap_list; pt != 0; pt = pt->next)
- if (!pt->nm.is_null()) {
- if (pt->position >= V0) {
- if (pt->position > vertical_position
- && pt->position < page_length
- && (next_trap == 0 || pt->position < *next_trap_pos)) {
- next_trap = pt;
- *next_trap_pos = pt->position;
- }
- }
- else {
- vunits pos = pt->position;
- pos += page_length;
- if (pos > 0 && pos > vertical_position && (next_trap == 0 || pos < *next_trap_pos)) {
- next_trap = pt;
- *next_trap_pos = pos;
- }
- }
- }
- return next_trap;
-}
-
-vunits top_level_diversion::distance_to_next_trap()
-{
- vunits d;
- if (!find_next_trap(&d))
- return page_length - vertical_position;
- else
- return d - vertical_position;
-}
-
-void top_level_diversion::output(node *nd, int retain_size,
- vunits vs, int ls, hunits /*width*/)
-{
- no_space_mode = 0;
- vunits next_trap_pos;
- trap *next_trap = find_next_trap(&next_trap_pos);
- if (before_first_page && begin_page())
- fatal("sorry, I didn't manage to begin the first page in time: use an explicit .br request");
- vertical_size v(vs, ls);
- for (node *tem = nd; tem != 0; tem = tem->next)
- tem->set_vertical_size(&v);
- if (!v.post_extra.is_zero())
- last_post_line_extra_space = v.post_extra.to_units();
- if (!retain_size) {
- v.pre = vs;
- v.post = (ls > 1) ? vs*(ls - 1) : V0;
- }
- vertical_position += v.pre;
- vertical_position += v.pre_extra;
- the_output->print_line(page_offset, vertical_position, nd,
- v.pre + v.pre_extra, v.post_extra);
- vertical_position += v.post_extra;
- if (vertical_position > high_water_mark)
- high_water_mark = vertical_position;
- if (vertical_position_traps_flag && vertical_position >= page_length)
- begin_page();
- else if (vertical_position_traps_flag
- && next_trap != 0 && vertical_position >= next_trap_pos) {
- nl_reg_contents = vertical_position.to_units();
- truncated_space = v.post;
- spring_trap(next_trap->nm);
- }
- else if (v.post > V0) {
- vertical_position += v.post;
- if (vertical_position_traps_flag
- && next_trap != 0 && vertical_position >= next_trap_pos) {
- truncated_space = vertical_position - next_trap_pos;
- vertical_position = next_trap_pos;
- nl_reg_contents = vertical_position.to_units();
- spring_trap(next_trap->nm);
- }
- else if (vertical_position_traps_flag && vertical_position >= page_length)
- begin_page();
- else
- nl_reg_contents = vertical_position.to_units();
- }
- else
- nl_reg_contents = vertical_position.to_units();
-}
-
-void top_level_diversion::transparent_output(unsigned char c)
-{
- if (before_first_page && begin_page())
- // This can only happen with the transparent() request.
- fatal("sorry, I didn't manage to begin the first page in time: use an explicit .br request");
- const char *s = asciify(c);
- while (*s)
- the_output->transparent_char(*s++);
-}
-
-void top_level_diversion::transparent_output(node * /*n*/)
-{
- error("can't transparently output node at top level");
-}
-
-void top_level_diversion::copy_file(const char *filename)
-{
- if (before_first_page && begin_page())
- fatal("sorry, I didn't manage to begin the first page in time: use an explicit .br request");
- the_output->copy_file(page_offset, vertical_position, filename);
-}
-
-void top_level_diversion::space(vunits n, int forced)
-{
- if (no_space_mode) {
- if (!forced)
- return;
- else
- no_space_mode = 0;
- }
- if (before_first_page) {
- if (begin_page()) {
- // This happens if there's a top of page trap, and the first-page
- // transition is caused by `'sp'.
- truncated_space = n > V0 ? n : V0;
- return;
- }
- }
- vunits next_trap_pos;
- trap *next_trap = find_next_trap(&next_trap_pos);
- vunits y = vertical_position + n;
- if (vertical_position_traps_flag && next_trap != 0 && y >= next_trap_pos) {
- vertical_position = next_trap_pos;
- nl_reg_contents = vertical_position.to_units();
- truncated_space = y - vertical_position;
- spring_trap(next_trap->nm);
- }
- else if (y < V0) {
- vertical_position = V0;
- nl_reg_contents = vertical_position.to_units();
- }
- else if (vertical_position_traps_flag && y >= page_length && n >= V0)
- begin_page();
- else {
- vertical_position = y;
- nl_reg_contents = vertical_position.to_units();
- }
-}
-
-trap::trap(symbol s, vunits n, trap *p)
- : nm(s), next(p), position(n)
-{
-}
-
-void top_level_diversion::add_trap(symbol nm, vunits pos)
-{
- trap *first_free_slot = 0;
- for (trap **p = &page_trap_list; *p; p = &(*p)->next) {
- if ((*p)->nm.is_null()) {
- if (first_free_slot == 0)
- first_free_slot = *p;
- }
- else if ((*p)->position == pos) {
- (*p)->nm = nm;
- return;
- }
- }
- if (first_free_slot) {
- first_free_slot->nm = nm;
- first_free_slot->position = pos;
- }
- else
- *p = new trap(nm, pos, 0);
-}
-
-void top_level_diversion::remove_trap(symbol nm)
-{
- for (trap *p = page_trap_list; p; p = p->next)
- if (p->nm == nm) {
- p->nm = NULL_SYMBOL;
- return;
- }
-}
-
-void top_level_diversion::remove_trap_at(vunits pos)
-{
- for (trap *p = page_trap_list; p; p = p->next)
- if (p->position == pos) {
- p->nm = NULL_SYMBOL;
- return;
- }
-}
-
-void top_level_diversion::change_trap(symbol nm, vunits pos)
-{
- for (trap *p = page_trap_list; p; p = p->next)
- if (p->nm == nm) {
- p->position = pos;
- return;
- }
-}
-
-void top_level_diversion::print_traps()
-{
- for (trap *p = page_trap_list; p; p = p->next)
- if (p->nm.is_null())
- fprintf(stderr, " empty\n");
- else
- fprintf(stderr, "%s\t%d\n", p->nm.contents(), p->position.to_units());
- fflush(stderr);
-}
-
-void end_diversions()
-{
- while (curdiv != topdiv) {
- error("automatically ending diversion `%1' on exit",
- curdiv->nm.contents());
- diversion *tem = curdiv;
- curdiv = curdiv->prev;
- delete tem;
- }
-}
-
-void cleanup_and_exit(int exit_code)
-{
- if (the_output) {
- the_output->trailer(topdiv->get_page_length());
- delete the_output;
- }
- exit(exit_code);
-}
-
-// returns non-zero if it sprung a top of page trap
-
-int top_level_diversion::begin_page()
-{
- if (exit_started) {
- if (page_count == last_page_count
- ? curenv->is_empty()
- : (done_end_macro && (seen_last_page_ejector || began_page_in_end_macro)))
- cleanup_and_exit(0);
- if (!done_end_macro)
- began_page_in_end_macro = 1;
- }
- if (last_page_number > 0 && page_number == last_page_number)
- cleanup_and_exit(0);
- if (!the_output)
- init_output();
- ++page_count;
- if (have_next_page_number) {
- page_number = next_page_number;
- have_next_page_number = 0;
- }
- else if (before_first_page == 1)
- page_number = 1;
- else
- page_number++;
- // spring the top of page trap if there is one
- vunits next_trap_pos;
- vertical_position = -vresolution;
- trap *next_trap = find_next_trap(&next_trap_pos);
- vertical_position = V0;
- high_water_mark = V0;
- ejecting_page = 0;
- // If before_first_page was 2, then the top of page transition was undone
- // using eg .nr nl 0-1. See nl_reg::set_value.
- if (before_first_page != 2)
- the_output->begin_page(page_number, page_length);
- before_first_page = 0;
- nl_reg_contents = vertical_position.to_units();
- if (vertical_position_traps_flag && next_trap != 0 && next_trap_pos == V0) {
- truncated_space = V0;
- spring_trap(next_trap->nm);
- return 1;
- }
- else
- return 0;
-}
-
-void continue_page_eject()
-{
- if (topdiv->get_ejecting()) {
- if (curdiv != topdiv)
- error("can't continue page ejection because of current diversion");
- else if (!vertical_position_traps_flag)
- error("can't continue page ejection because vertical position traps disabled");
- else {
- push_page_ejector();
- topdiv->space(topdiv->get_page_length(), 1);
- }
- }
-}
-
-void top_level_diversion::set_next_page_number(int n)
-{
- next_page_number= n;
- have_next_page_number = 1;
-}
-
-int top_level_diversion::get_next_page_number()
-{
- return have_next_page_number ? next_page_number : page_number + 1;
-}
-
-void top_level_diversion::set_page_length(vunits n)
-{
- page_length = n;
-}
-
-diversion::~diversion()
-{
-}
-
-void page_offset()
-{
- hunits n;
- // The troff manual says that the default scaling indicator is v,
- // but it is in fact m: v wouldn't make sense for a horizontally
- // oriented request.
- if (!has_arg() || !get_hunits(&n, 'm', topdiv->page_offset))
- n = topdiv->prev_page_offset;
- topdiv->prev_page_offset = topdiv->page_offset;
- topdiv->page_offset = n;
- skip_line();
-}
-
-void page_length()
-{
- vunits n;
- if (has_arg() && get_vunits(&n, 'v', topdiv->get_page_length()))
- topdiv->set_page_length(n);
- else
- topdiv->set_page_length(11*units_per_inch);
- skip_line();
-}
-
-void when_request()
-{
- vunits n;
- if (get_vunits(&n, 'v')) {
- symbol s = get_name();
- if (s.is_null())
- topdiv->remove_trap_at(n);
- else
- topdiv->add_trap(s, n);
- }
- skip_line();
-}
-
-void begin_page()
-{
- int got_arg = 0;
- int n;
- if (has_arg() && get_integer(&n, topdiv->get_page_number()))
- got_arg = 1;
- while (!tok.newline() && !tok.eof())
- tok.next();
- if (curdiv == topdiv) {
- if (topdiv->before_first_page) {
- if (!break_flag) {
- if (got_arg)
- topdiv->set_next_page_number(n);
- if (got_arg || !topdiv->no_space_mode)
- topdiv->begin_page();
- }
- else if (topdiv->no_space_mode && !got_arg)
- topdiv->begin_page();
- else {
- /* Given this
-
- .wh 0 x
- .de x
- .tm \\n%
- ..
- .bp 3
-
- troff prints
-
- 1
- 3
-
- This code makes groff do the same. */
-
- push_page_ejector();
- topdiv->begin_page();
- if (got_arg)
- topdiv->set_next_page_number(n);
- topdiv->set_ejecting();
- }
- }
- else {
- push_page_ejector();
- if (break_flag)
- curenv->do_break();
- if (got_arg)
- topdiv->set_next_page_number(n);
- if (!(topdiv->no_space_mode && !got_arg))
- topdiv->set_ejecting();
- }
- }
- tok.next();
-}
-
-void no_space()
-{
- if (curdiv == topdiv)
- topdiv->no_space_mode = 1;
- skip_line();
-}
-
-void restore_spacing()
-{
- if (curdiv == topdiv)
- topdiv->no_space_mode = 0;
- 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
-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
-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
-the argument to the request. If the break did cause a trap to be
-sprung, then we don't actually do the space. */
-
-void space_request()
-{
- postpone_traps();
- if (break_flag)
- curenv->do_break();
- vunits n;
- if (!has_arg() || !get_vunits(&n, 'v'))
- n = curenv->get_vertical_spacing();
- while (!tok.newline() && !tok.eof())
- tok.next();
- if (!unpostpone_traps())
- curdiv->space(n);
- else
- // The line might have had line spacing that was truncated.
- truncated_space += n;
- tok.next();
-}
-
-void blank_line()
-{
- curenv->do_break();
- if (!trap_sprung_flag)
- curdiv->space(curenv->get_vertical_spacing());
- else
- truncated_space += curenv->get_vertical_spacing();
-}
-
-/* need_space might spring a trap and so we must be careful that the
-BEGIN_TRAP token is not skipped over. */
-
-void need_space()
-{
- vunits n;
- if (!has_arg() || !get_vunits(&n, 'v'))
- n = curenv->get_vertical_spacing();
- while (!tok.newline() && !tok.eof())
- tok.next();
- curdiv->need(n);
- tok.next();
-}
-
-void page_number()
-{
- int n;
- if (has_arg() && get_integer(&n, topdiv->get_page_number()))
- topdiv->set_next_page_number(n);
- skip_line();
-}
-
-vunits saved_space;
-
-void save_vertical_space()
-{
- vunits x;
- if (get_vunits(&x, 'v')) {
- if (curdiv->distance_to_next_trap() > x)
- curdiv->space(x, 1);
- else
- saved_space = x;
- }
- skip_line();
-}
-
-void output_saved_vertical_space()
-{
- while (!tok.newline() && !tok.eof())
- tok.next();
- if (saved_space > V0)
- curdiv->space(saved_space, 1);
- saved_space = V0;
- tok.next();
-}
-
-void flush_output()
-{
- while (!tok.newline() && !tok.eof())
- tok.next();
- if (break_flag)
- curenv->do_break();
- if (the_output)
- the_output->flush();
- tok.next();
-}
-
-void macro_diversion::set_diversion_trap(symbol s, vunits n)
-{
- diversion_trap = s;
- diversion_trap_pos = n;
-}
-
-void macro_diversion::clear_diversion_trap()
-{
- diversion_trap = NULL_SYMBOL;
-}
-
-void top_level_diversion::set_diversion_trap(symbol, vunits)
-{
- error("can't set diversion trap when no current diversion");
-}
-
-void top_level_diversion::clear_diversion_trap()
-{
- error("can't set diversion trap when no current diversion");
-}
-
-void diversion_trap()
-{
- vunits n;
- if (has_arg() && get_vunits(&n, 'v')) {
- symbol s = get_name();
- if (!s.is_null())
- curdiv->set_diversion_trap(s, n);
- else
- curdiv->clear_diversion_trap();
- }
- else
- curdiv->clear_diversion_trap();
- skip_line();
-}
-
-void change_trap()
-{
- symbol s = get_name(1);
- if (!s.is_null()) {
- vunits x;
- if (has_arg() && get_vunits(&x, 'v'))
- topdiv->change_trap(s, x);
- else
- topdiv->remove_trap(s);
- }
- skip_line();
-}
-
-void print_traps()
-{
- topdiv->print_traps();
- skip_line();
-}
-
-void mark()
-{
- symbol s = get_name();
- if (s.is_null())
- curdiv->marked_place = curdiv->get_vertical_position();
- else if (curdiv == topdiv)
- set_number_reg(s, nl_reg_contents);
- else
- set_number_reg(s, curdiv->get_vertical_position().to_units());
- skip_line();
-}
-
-// This is truly bizarre. It is documented in the SQ manual.
-
-void return_request()
-{
- vunits dist = curdiv->marked_place - curdiv->get_vertical_position();
- if (has_arg()) {
- if (tok.ch() == '-') {
- tok.next();
- vunits x;
- if (get_vunits(&x, 'v'))
- dist = -x;
- }
- else {
- vunits x;
- if (get_vunits(&x, 'v'))
- dist = x >= V0 ? x - curdiv->get_vertical_position() : V0;
- }
- }
- if (dist < V0)
- curdiv->space(dist);
- skip_line();
-}
-
-void vertical_position_traps()
-{
- int n;
- if (has_arg() && get_integer(&n))
- vertical_position_traps_flag = (n != 0);
- else
- vertical_position_traps_flag = 1;
- skip_line();
-}
-
-class page_offset_reg : public reg {
-public:
- int get_value(units *);
- const char *get_string();
-};
-
-int page_offset_reg::get_value(units *res)
-{
- *res = topdiv->get_page_offset().to_units();
- return 1;
-}
-
-const char *page_offset_reg::get_string()
-{
- return itoa(topdiv->get_page_offset().to_units());
-}
-
-class page_length_reg : public reg {
-public:
- int get_value(units *);
- const char *get_string();
-};
-
-int page_length_reg::get_value(units *res)
-{
- *res = topdiv->get_page_length().to_units();
- return 1;
-}
-
-const char *page_length_reg::get_string()
-{
- return itoa(topdiv->get_page_length().to_units());
-}
-
-class vertical_position_reg : public reg {
-public:
- int get_value(units *);
- const char *get_string();
-};
-
-int vertical_position_reg::get_value(units *res)
-{
- if (curdiv == topdiv && topdiv->before_first_page)
- *res = -1;
- else
- *res = curdiv->get_vertical_position().to_units();
- return 1;
-}
-
-const char *vertical_position_reg::get_string()
-{
- if (curdiv == topdiv && topdiv->before_first_page)
- return "-1";
- else
- return itoa(curdiv->get_vertical_position().to_units());
-}
-
-class high_water_mark_reg : public reg {
-public:
- int get_value(units *);
- const char *get_string();
-};
-
-int high_water_mark_reg::get_value(units *res)
-{
- *res = curdiv->get_high_water_mark().to_units();
- return 1;
-}
-
-const char *high_water_mark_reg::get_string()
-{
- return itoa(curdiv->get_high_water_mark().to_units());
-}
-
-class distance_to_next_trap_reg : public reg {
-public:
- int get_value(units *);
- const char *get_string();
-};
-
-int distance_to_next_trap_reg::get_value(units *res)
-{
- *res = curdiv->distance_to_next_trap().to_units();
- return 1;
-}
-
-const char *distance_to_next_trap_reg::get_string()
-{
- return itoa(curdiv->distance_to_next_trap().to_units());
-}
-
-class diversion_name_reg : public reg {
-public:
- const char *get_string();
-};
-
-const char *diversion_name_reg::get_string()
-{
- return curdiv->get_diversion_name();
-}
-
-class page_number_reg : public general_reg {
-public:
- page_number_reg();
- int get_value(units *);
- void set_value(units);
-};
-
-page_number_reg::page_number_reg()
-{
-}
-
-void page_number_reg::set_value(units n)
-{
- topdiv->set_page_number(n);
-}
-
-int page_number_reg::get_value(units *res)
-{
- *res = topdiv->get_page_number();
- return 1;
-}
-
-class next_page_number_reg : public reg {
-public:
- const char *get_string();
-};
-
-const char *next_page_number_reg::get_string()
-{
- return itoa(topdiv->get_next_page_number());
-}
-
-class page_ejecting_reg : public reg {
-public:
- const char *get_string();
-};
-
-const char *page_ejecting_reg::get_string()
-{
- return itoa(topdiv->get_ejecting());
-}
-
-class constant_vunits_reg : public reg {
- vunits *p;
-public:
- constant_vunits_reg(vunits *);
- const char *get_string();
-};
-
-constant_vunits_reg::constant_vunits_reg(vunits *q) : p(q)
-{
-}
-
-const char *constant_vunits_reg::get_string()
-{
- return itoa(p->to_units());
-}
-
-class nl_reg : public variable_reg {
-public:
- nl_reg();
- void set_value(units);
-};
-
-nl_reg::nl_reg() : variable_reg(&nl_reg_contents)
-{
-}
-
-void nl_reg::set_value(units n)
-{
- variable_reg::set_value(n);
- // Setting nl to a negative value when the vertical position in
- // the top-level diversion is 0 undoes the top of page transition,
- // so that the header macro will be called as if the top of page
- // transition hasn't happened. This is used by Larry Wall's
- // wrapman program. Setting before_first_page to 2 rather than 1,
- // tells top_level_diversion::begin_page not to call
- // output_file::begin_page again.
- if (n < 0 && topdiv->get_vertical_position() == V0)
- topdiv->before_first_page = 2;
-}
-
-void init_div_requests()
-{
- init_request("wh", when_request);
- init_request("ch", change_trap);
- init_request("pl", page_length);
- init_request("po", page_offset);
- init_request("rs", restore_spacing);
- init_request("ns", no_space);
- init_request("sp", space_request);
- init_request("di", divert);
- init_request("da", divert_append);
- init_request("bp", begin_page);
- init_request("ne", need_space);
- init_request("pn", page_number);
- init_request("dt", diversion_trap);
- init_request("rt", return_request);
- init_request("mk", mark);
- init_request("sv", save_vertical_space);
- init_request("os", output_saved_vertical_space);
- init_request("fl", flush_output);
- init_request("vpt", vertical_position_traps);
- init_request("ptr", print_traps);
- number_reg_dictionary.define(".a",
- new constant_int_reg(&last_post_line_extra_space));
- number_reg_dictionary.define(".z", new diversion_name_reg);
- number_reg_dictionary.define(".o", new page_offset_reg);
- number_reg_dictionary.define(".p", new page_length_reg);
- number_reg_dictionary.define(".d", new vertical_position_reg);
- number_reg_dictionary.define(".h", new high_water_mark_reg);
- number_reg_dictionary.define(".t", new distance_to_next_trap_reg);
- number_reg_dictionary.define("dl", new variable_reg(&dl_reg_contents));
- number_reg_dictionary.define("dn", new variable_reg(&dn_reg_contents));
- number_reg_dictionary.define("nl", new nl_reg);
- number_reg_dictionary.define(".vpt",
- new constant_int_reg(&vertical_position_traps_flag));
- number_reg_dictionary.define("%", new page_number_reg);
- number_reg_dictionary.define(".pn", new next_page_number_reg);
- number_reg_dictionary.define(".trunc",
- new constant_vunits_reg(&truncated_space));
- number_reg_dictionary.define(".ne",
- new constant_vunits_reg(&needed_space));
- number_reg_dictionary.define(".pe", new page_ejecting_reg);
-}
OpenPOWER on IntegriCloud