1// -*- C++ -*-
2/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004
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
22
23class charinfo;
24struct node;
25class vunits;
26
27class token {
28  symbol nm;
29  node *nd;
30  unsigned char c;
31  int val;
32  units dim;
33  enum token_type {
34    TOKEN_BACKSPACE,
35    TOKEN_BEGIN_TRAP,
36    TOKEN_CHAR,			// a normal printing character
37    TOKEN_DUMMY,		// \&
38    TOKEN_EMPTY,		// this is the initial value
39    TOKEN_END_TRAP,
40    TOKEN_ESCAPE,		// \e
41    TOKEN_HYPHEN_INDICATOR,
42    TOKEN_INTERRUPT,		// \c
43    TOKEN_ITALIC_CORRECTION,	// \/
44    TOKEN_LEADER,		// ^A
45    TOKEN_LEFT_BRACE,
46    TOKEN_MARK_INPUT,		// \k -- `nm' is the name of the register
47    TOKEN_NEWLINE,		// newline
48    TOKEN_NODE,
49    TOKEN_NUMBERED_CHAR,
50    TOKEN_PAGE_EJECTOR,
51    TOKEN_REQUEST,
52    TOKEN_RIGHT_BRACE,
53    TOKEN_SPACE,		// ` ' -- ordinary space
54    TOKEN_SPECIAL,		// a special character -- \' \` \- \(xx \[xxx]
55    TOKEN_SPREAD,		// \p -- break and spread output line
56    TOKEN_STRETCHABLE_SPACE,	// \~
57    TOKEN_UNSTRETCHABLE_SPACE,	// `\ '
58    TOKEN_TAB,			// tab
59    TOKEN_TRANSPARENT,		// \!
60    TOKEN_TRANSPARENT_DUMMY,	// \)
61    TOKEN_ZERO_WIDTH_BREAK,	// \:
62    TOKEN_EOF			// end of file
63  } type;
64public:
65  token();
66  ~token();
67  token(const token &);
68  void operator=(const token &);
69  void next();
70  void process();
71  void skip();
72  int eof();
73  int nspaces();		// 1 if space, 2 if double space, 0 otherwise
74  int space();			// is the current token a space?
75  int stretchable_space();	// is the current token a stretchable space?
76  int unstretchable_space();	// is the current token an unstretchable space?
77  int white_space();		// is the current token space or tab?
78  int special();		// is the current token a special character?
79  int newline();		// is the current token a newline?
80  int tab();			// is the current token a tab?
81  int leader();
82  int backspace();
83  int delimiter(int warn = 0);	// is it suitable for use as a delimiter?
84  int dummy();
85  int transparent_dummy();
86  int transparent();
87  int left_brace();
88  int right_brace();
89  int page_ejector();
90  int hyphen_indicator();
91  int zero_width_break();
92  int operator==(const token &); // need this for delimiters, and for conditions
93  int operator!=(const token &); // ditto
94  unsigned char ch();
95  charinfo *get_char(int required = 0);
96  int add_to_node_list(node **);
97  int title();
98  void make_space();
99  void make_newline();
100  const char *description();
101
102  friend void process_input_stack();
103};
104
105extern token tok;		// the current token
106
107extern symbol get_name(int required = 0);
108extern symbol get_long_name(int required = 0);
109extern charinfo *get_optional_char();
110extern char *read_string();
111extern void check_missing_character();
112extern void skip_line();
113extern void handle_initial_title();
114
115enum char_mode {
116  CHAR_NORMAL,
117  CHAR_FALLBACK,
118  CHAR_FONT_SPECIAL,
119  CHAR_SPECIAL
120};
121
122extern void do_define_character(char_mode, const char * = 0);
123
124class hunits;
125extern void read_title_parts(node **part, hunits *part_width);
126
127extern int get_number_rigidly(units *result, unsigned char si);
128
129extern int get_number(units *result, unsigned char si);
130extern int get_integer(int *result);
131
132extern int get_number(units *result, unsigned char si, units prev_value);
133extern int get_integer(int *result, int prev_value);
134
135void interpolate_number_reg(symbol, int);
136
137const char *asciify(int c);
138
139inline int token::newline()
140{
141  return type == TOKEN_NEWLINE;
142}
143
144inline int token::space()
145{
146  return type == TOKEN_SPACE;
147}
148
149inline int token::stretchable_space()
150{
151  return type == TOKEN_STRETCHABLE_SPACE;
152}
153
154inline int token::unstretchable_space()
155{
156  return type == TOKEN_UNSTRETCHABLE_SPACE;
157}
158
159inline int token::special()
160{
161  return type == TOKEN_SPECIAL;
162}
163
164inline int token::nspaces()
165{
166  if (type == TOKEN_SPACE)
167    return 1;
168  else
169    return 0;
170}
171
172inline int token::white_space()
173{
174  return type == TOKEN_SPACE || type == TOKEN_TAB;
175}
176
177inline int token::transparent()
178{
179  return type == TOKEN_TRANSPARENT;
180}
181
182inline int token::page_ejector()
183{
184  return type == TOKEN_PAGE_EJECTOR;
185}
186
187inline unsigned char token::ch()
188{
189  return type == TOKEN_CHAR ? c : 0;
190}
191
192inline int token::eof()
193{
194  return type == TOKEN_EOF;
195}
196
197inline int token::dummy()
198{
199  return type == TOKEN_DUMMY;
200}
201
202inline int token::transparent_dummy()
203{
204  return type == TOKEN_TRANSPARENT_DUMMY;
205}
206
207inline int token::left_brace()
208{
209  return type == TOKEN_LEFT_BRACE;
210}
211
212inline int token::right_brace()
213{
214  return type == TOKEN_RIGHT_BRACE;
215}
216
217inline int token::tab()
218{
219  return type == TOKEN_TAB;
220}
221
222inline int token::leader()
223{
224  return type == TOKEN_LEADER;
225}
226
227inline int token::backspace()
228{
229  return type == TOKEN_BACKSPACE;
230}
231
232inline int token::hyphen_indicator()
233{
234  return type == TOKEN_HYPHEN_INDICATOR;
235}
236
237inline int token::zero_width_break()
238{
239  return type == TOKEN_ZERO_WIDTH_BREAK;
240}
241
242int has_arg();
243