1// -*- C++ -*-
2/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2004, 2005
3   Free Software Foundation, Inc.
4     Written by James Clark (jjc@jclark.com)
5
6This file is part of groff.
7
8groff is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13groff is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with groff; see the file COPYING.  If not, write to the Free Software
20Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
21
22void do_divert(int append, int boxing);
23void end_diversions();
24void page_offset();
25
26class diversion {
27  friend void do_divert(int append, int boxing);
28  friend void end_diversions();
29  diversion *prev;
30  node *saved_line;
31  hunits saved_width_total;
32  int saved_space_total;
33  hunits saved_saved_indent;
34  hunits saved_target_text_length;
35  int saved_prev_line_interrupted;
36protected:
37  symbol nm;
38  vunits vertical_position;
39  vunits high_water_mark;
40public:
41  int any_chars_added;
42  int no_space_mode;
43  int needs_push;
44  int saved_seen_break;
45  int saved_seen_space;
46  int saved_seen_eol;
47  int saved_suppress_next_eol;
48  state_set modified_tag;
49  vunits marked_place;
50  diversion(symbol s = NULL_SYMBOL);
51  virtual ~diversion();
52  virtual void output(node *nd, int retain_size, vunits vs, vunits post_vs,
53		      hunits width) = 0;
54  virtual void transparent_output(unsigned char) = 0;
55  virtual void transparent_output(node *) = 0;
56  virtual void space(vunits distance, int forced = 0) = 0;
57#ifdef COLUMN
58  virtual void vjustify(symbol) = 0;
59#endif /* COLUMN */
60  vunits get_vertical_position() { return vertical_position; }
61  vunits get_high_water_mark() { return high_water_mark; }
62  virtual vunits distance_to_next_trap() = 0;
63  void need(vunits);
64  const char *get_diversion_name() { return nm.contents(); }
65  virtual void set_diversion_trap(symbol, vunits) = 0;
66  virtual void clear_diversion_trap() = 0;
67  virtual void copy_file(const char *filename) = 0;
68  virtual int is_diversion() = 0;
69};
70
71class macro;
72
73class macro_diversion : public diversion {
74  macro *mac;
75  hunits max_width;
76  symbol diversion_trap;
77  vunits diversion_trap_pos;
78public:
79  macro_diversion(symbol, int);
80  ~macro_diversion();
81  void output(node *nd, int retain_size, vunits vs, vunits post_vs,
82	      hunits width);
83  void transparent_output(unsigned char);
84  void transparent_output(node *);
85  void space(vunits distance, int forced = 0);
86#ifdef COLUMN
87  void vjustify(symbol);
88#endif /* COLUMN */
89  vunits distance_to_next_trap();
90  void set_diversion_trap(symbol, vunits);
91  void clear_diversion_trap();
92  void copy_file(const char *filename);
93  int is_diversion() { return 1; }
94};
95
96struct trap {
97  trap *next;
98  vunits position;
99  symbol nm;
100  trap(symbol, vunits, trap *);
101};
102
103class output_file;
104
105class top_level_diversion : public diversion {
106  int page_number;
107  int page_count;
108  int last_page_count;
109  vunits page_length;
110  hunits prev_page_offset;
111  hunits page_offset;
112  trap *page_trap_list;
113  trap *find_next_trap(vunits *);
114  int have_next_page_number;
115  int next_page_number;
116  int ejecting_page;		// Is the current page being ejected?
117public:
118  int before_first_page;
119  top_level_diversion();
120  void output(node *nd, int retain_size, vunits vs, vunits post_vs,
121	      hunits width);
122  void transparent_output(unsigned char);
123  void transparent_output(node *);
124  void space(vunits distance, int forced = 0);
125#ifdef COLUMN
126  void vjustify(symbol);
127#endif /* COLUMN */
128  hunits get_page_offset() { return page_offset; }
129  vunits get_page_length() { return page_length; }
130  vunits distance_to_next_trap();
131  void add_trap(symbol nm, vunits pos);
132  void change_trap(symbol nm, vunits pos);
133  void remove_trap(symbol);
134  void remove_trap_at(vunits pos);
135  void print_traps();
136  int get_page_count() { return page_count; }
137  int get_page_number() { return page_number; }
138  int get_next_page_number();
139  void set_page_number(int n) { page_number = n; }
140  int begin_page(vunits = V0);
141  void set_next_page_number(int);
142  void set_page_length(vunits);
143  void copy_file(const char *filename);
144  int get_ejecting() { return ejecting_page; }
145  void set_ejecting() { ejecting_page = 1; }
146  friend void page_offset();
147  void set_diversion_trap(symbol, vunits);
148  void clear_diversion_trap();
149  void set_last_page() { last_page_count = page_count; }
150  int is_diversion() { return 0; }
151};
152
153extern top_level_diversion *topdiv;
154extern diversion *curdiv;
155
156extern int exit_started;
157extern int done_end_macro;
158extern int last_page_number;
159extern int seen_last_page_ejector;
160
161void spring_trap(symbol);	// implemented by input.c
162extern int trap_sprung_flag;
163void postpone_traps();
164int unpostpone_traps();
165
166void push_page_ejector();
167void continue_page_eject();
168void handle_first_page_transition();
169void blank_line();
170void begin_page();
171
172extern void cleanup_and_exit(int);
173