175584Sru// -*- C++ -*-
2151497Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004
375584Sru   Free Software Foundation, Inc.
475584Sru     Written by James Clark (jjc@jclark.com)
575584Sru
675584SruThis file is part of groff.
775584Sru
875584Srugroff is free software; you can redistribute it and/or modify it under
975584Sruthe terms of the GNU General Public License as published by the Free
1075584SruSoftware Foundation; either version 2, or (at your option) any later
1175584Sruversion.
1275584Sru
1375584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
1475584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
1575584SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1675584Srufor more details.
1775584Sru
1875584SruYou should have received a copy of the GNU General Public License along
1975584Sruwith groff; see the file COPYING.  If not, write to the Free Software
20151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
2175584Sru
2275584Sru
23151497Sruclass charinfo;
2475584Srustruct node;
25151497Sruclass vunits;
2675584Sru
2775584Sruclass token {
2875584Sru  symbol nm;
2975584Sru  node *nd;
3075584Sru  unsigned char c;
3175584Sru  int val;
3275584Sru  units dim;
3375584Sru  enum token_type {
3475584Sru    TOKEN_BACKSPACE,
3575584Sru    TOKEN_BEGIN_TRAP,
3675584Sru    TOKEN_CHAR,			// a normal printing character
3775584Sru    TOKEN_DUMMY,		// \&
3875584Sru    TOKEN_EMPTY,		// this is the initial value
3975584Sru    TOKEN_END_TRAP,
4075584Sru    TOKEN_ESCAPE,		// \e
4175584Sru    TOKEN_HYPHEN_INDICATOR,
4275584Sru    TOKEN_INTERRUPT,		// \c
4375584Sru    TOKEN_ITALIC_CORRECTION,	// \/
4475584Sru    TOKEN_LEADER,		// ^A
4575584Sru    TOKEN_LEFT_BRACE,
4675584Sru    TOKEN_MARK_INPUT,		// \k -- `nm' is the name of the register
4775584Sru    TOKEN_NEWLINE,		// newline
4875584Sru    TOKEN_NODE,
4975584Sru    TOKEN_NUMBERED_CHAR,
5075584Sru    TOKEN_PAGE_EJECTOR,
5175584Sru    TOKEN_REQUEST,
5275584Sru    TOKEN_RIGHT_BRACE,
5375584Sru    TOKEN_SPACE,		// ` ' -- ordinary space
54104862Sru    TOKEN_SPECIAL,		// a special character -- \' \` \- \(xx \[xxx]
5575584Sru    TOKEN_SPREAD,		// \p -- break and spread output line
5675584Sru    TOKEN_STRETCHABLE_SPACE,	// \~
57104862Sru    TOKEN_UNSTRETCHABLE_SPACE,	// `\ '
5875584Sru    TOKEN_TAB,			// tab
5975584Sru    TOKEN_TRANSPARENT,		// \!
6075584Sru    TOKEN_TRANSPARENT_DUMMY,	// \)
61104862Sru    TOKEN_ZERO_WIDTH_BREAK,	// \:
6275584Sru    TOKEN_EOF			// end of file
63104862Sru  } type;
6475584Srupublic:
6575584Sru  token();
6675584Sru  ~token();
6775584Sru  token(const token &);
6875584Sru  void operator=(const token &);
6975584Sru  void next();
7075584Sru  void process();
7175584Sru  void skip();
7275584Sru  int eof();
7375584Sru  int nspaces();		// 1 if space, 2 if double space, 0 otherwise
7475584Sru  int space();			// is the current token a space?
7575584Sru  int stretchable_space();	// is the current token a stretchable space?
76104862Sru  int unstretchable_space();	// is the current token an unstretchable space?
7775584Sru  int white_space();		// is the current token space or tab?
7879543Sru  int special();		// is the current token a special character?
7975584Sru  int newline();		// is the current token a newline?
8075584Sru  int tab();			// is the current token a tab?
8175584Sru  int leader();
8275584Sru  int backspace();
8375584Sru  int delimiter(int warn = 0);	// is it suitable for use as a delimiter?
8475584Sru  int dummy();
8575584Sru  int transparent_dummy();
8675584Sru  int transparent();
8775584Sru  int left_brace();
8875584Sru  int right_brace();
8975584Sru  int page_ejector();
9075584Sru  int hyphen_indicator();
91104862Sru  int zero_width_break();
9275584Sru  int operator==(const token &); // need this for delimiters, and for conditions
9375584Sru  int operator!=(const token &); // ditto
9475584Sru  unsigned char ch();
9575584Sru  charinfo *get_char(int required = 0);
9675584Sru  int add_to_node_list(node **);
9775584Sru  int title();
9875584Sru  void make_space();
9975584Sru  void make_newline();
10075584Sru  const char *description();
10175584Sru
10275584Sru  friend void process_input_stack();
10375584Sru};
10475584Sru
10575584Sruextern token tok;		// the current token
10675584Sru
10775584Sruextern symbol get_name(int required = 0);
10875584Sruextern symbol get_long_name(int required = 0);
10975584Sruextern charinfo *get_optional_char();
110104862Sruextern char *read_string();
11175584Sruextern void check_missing_character();
11275584Sruextern void skip_line();
11375584Sruextern void handle_initial_title();
11475584Sru
115114402Sruenum char_mode {
116114402Sru  CHAR_NORMAL,
117114402Sru  CHAR_FALLBACK,
118114402Sru  CHAR_FONT_SPECIAL,
119114402Sru  CHAR_SPECIAL
120114402Sru};
121114402Sru
122114402Sruextern void do_define_character(char_mode, const char * = 0);
123114402Sru
124151497Sruclass hunits;
12575584Sruextern void read_title_parts(node **part, hunits *part_width);
12675584Sru
12775584Sruextern int get_number_rigidly(units *result, unsigned char si);
12875584Sru
12975584Sruextern int get_number(units *result, unsigned char si);
13075584Sruextern int get_integer(int *result);
13175584Sru
13275584Sruextern int get_number(units *result, unsigned char si, units prev_value);
13375584Sruextern int get_integer(int *result, int prev_value);
13475584Sru
13575584Sruvoid interpolate_number_reg(symbol, int);
13675584Sru
13775584Sruconst char *asciify(int c);
13875584Sru
13975584Sruinline int token::newline()
14075584Sru{
14175584Sru  return type == TOKEN_NEWLINE;
14275584Sru}
14375584Sru
14475584Sruinline int token::space()
14575584Sru{
14675584Sru  return type == TOKEN_SPACE;
14775584Sru}
14875584Sru
14975584Sruinline int token::stretchable_space()
15075584Sru{
15175584Sru  return type == TOKEN_STRETCHABLE_SPACE;
15275584Sru}
15375584Sru
154104862Sruinline int token::unstretchable_space()
155104862Sru{
156104862Sru  return type == TOKEN_UNSTRETCHABLE_SPACE;
157104862Sru}
158104862Sru
15975584Sruinline int token::special()
16075584Sru{
16175584Sru  return type == TOKEN_SPECIAL;
16275584Sru}
16375584Sru
16475584Sruinline int token::nspaces()
16575584Sru{
16675584Sru  if (type == TOKEN_SPACE)
16775584Sru    return 1;
16875584Sru  else
16975584Sru    return 0;
17075584Sru}
17175584Sru
17275584Sruinline int token::white_space()
17375584Sru{
17475584Sru  return type == TOKEN_SPACE || type == TOKEN_TAB;
17575584Sru}
17675584Sru
17775584Sruinline int token::transparent()
17875584Sru{
17975584Sru  return type == TOKEN_TRANSPARENT;
18075584Sru}
18175584Sru
18275584Sruinline int token::page_ejector()
18375584Sru{
18475584Sru  return type == TOKEN_PAGE_EJECTOR;
18575584Sru}
18675584Sru
18775584Sruinline unsigned char token::ch()
18875584Sru{
18975584Sru  return type == TOKEN_CHAR ? c : 0;
19075584Sru}
19175584Sru
19275584Sruinline int token::eof()
19375584Sru{
19475584Sru  return type == TOKEN_EOF;
19575584Sru}
19675584Sru
19775584Sruinline int token::dummy()
19875584Sru{
19975584Sru  return type == TOKEN_DUMMY;
20075584Sru}
20175584Sru
20275584Sruinline int token::transparent_dummy()
20375584Sru{
20475584Sru  return type == TOKEN_TRANSPARENT_DUMMY;
20575584Sru}
20675584Sru
20775584Sruinline int token::left_brace()
20875584Sru{
20975584Sru  return type == TOKEN_LEFT_BRACE;
21075584Sru}
21175584Sru
21275584Sruinline int token::right_brace()
21375584Sru{
21475584Sru  return type == TOKEN_RIGHT_BRACE;
21575584Sru}
21675584Sru
21775584Sruinline int token::tab()
21875584Sru{
21975584Sru  return type == TOKEN_TAB;
22075584Sru}
22175584Sru
22275584Sruinline int token::leader()
22375584Sru{
22475584Sru  return type == TOKEN_LEADER;
22575584Sru}
22675584Sru
22775584Sruinline int token::backspace()
22875584Sru{
22975584Sru  return type == TOKEN_BACKSPACE;
23075584Sru}
23175584Sru
23275584Sruinline int token::hyphen_indicator()
23375584Sru{
23475584Sru  return type == TOKEN_HYPHEN_INDICATOR;
23575584Sru}
23675584Sru
237104862Sruinline int token::zero_width_break()
238104862Sru{
239104862Sru  return type == TOKEN_ZERO_WIDTH_BREAK;
240104862Sru}
241104862Sru
24275584Sruint has_arg();
243