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