LCOV - code coverage report
Current view: top level - roff/troff - token.h (source / functions) Hit Total Coverage
Test: GNU roff Lines: 46 46 100.0 %
Date: 2026-01-16 17:51:41 Functions: 20 20 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 1989-2020 Free Software Foundation, Inc.
       2             :              2021-2025 G. Branden Robinson
       3             : 
       4             :      Written by James Clark (jjc@jclark.com)
       5             : 
       6             : This file is part of groff, the GNU roff typesetting system.
       7             : 
       8             : groff is free software; you can redistribute it and/or modify it under
       9             : the terms of the GNU General Public License as published by the Free
      10             : Software Foundation, either version 3 of the License, or
      11             : (at your option) any later version.
      12             : 
      13             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16             : for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : 
      25             : #include <assert.h>
      26             : 
      27             : class charinfo;
      28             : struct node;
      29             : 
      30             : enum delimiter_context {
      31             :   DELIMITER_GROFF_EXPRESSION,
      32             :   DELIMITER_ATT_STRING_EXPRESSION,
      33             :   DELIMITER_ATT_NUMERIC_EXPRESSION,
      34             :   DELIMITER_ATT_OUTPUT_COMPARISON_EXPRESSION
      35             : };
      36             : 
      37             : class token {
      38             :   symbol nm;
      39             :   node *nd;
      40             :   unsigned char c;
      41             :   int val;
      42             :   units dim;
      43             :   enum token_type {
      44             :     TOKEN_BACKSPACE,            // ^H
      45             :     TOKEN_BEGIN_TRAP,
      46             :     TOKEN_CHAR,                 // ordinary character
      47             :     TOKEN_DELIMITED_HORIZONTAL_MOTION,  // \h
      48             :     TOKEN_DELIMITED_SPECIAL_CHAR,       // \C
      49             :     TOKEN_DUMMY,                // dummy character: \&
      50             :     TOKEN_EMPTY,                // this is the initial value
      51             :     TOKEN_END_TRAP,
      52             :     TOKEN_EOF,                  // end of file
      53             :     TOKEN_ESCAPE,               // \e
      54             :     TOKEN_HORIZONTAL_MOTION,    // fixed horizontal motion: \|, \^, \0
      55             :     TOKEN_HYPHEN_INDICATOR,     // \%
      56             :     TOKEN_INDEXED_CHAR,         // \N
      57             :     TOKEN_INTERRUPT,            // \c
      58             :     TOKEN_ITALIC_CORRECTION,    // \/
      59             :     TOKEN_LEADER,               // ^A
      60             :     TOKEN_LEFT_BRACE,           // \{
      61             :     TOKEN_MARK_INPUT,           // \k
      62             :     TOKEN_NEWLINE,              // ^J
      63             :     TOKEN_NODE,
      64             :     TOKEN_PAGE_EJECTOR,
      65             :     TOKEN_REQUEST,
      66             :     TOKEN_RIGHT_BRACE,          // \}
      67             :     TOKEN_SPACE,                // ' ' -- ordinary space
      68             :     TOKEN_SPECIAL_CHAR,         // \(, \[
      69             :     TOKEN_SPREAD,               // \p -- break and spread output line
      70             :     TOKEN_STRETCHABLE_SPACE,    // \~
      71             :     TOKEN_TAB,                  // ^I
      72             :     TOKEN_TRANSPARENT,          // \!
      73             :     TOKEN_TRANSPARENT_DUMMY,    // \)
      74             :     TOKEN_UNSTRETCHABLE_SPACE,  // '\ '
      75             :     TOKEN_ZERO_WIDTH_BREAK      // \:
      76             :   } type;
      77             : public:
      78             :   token();
      79             :   ~token();
      80             :   token(const token &);
      81             :   void operator=(const token &);
      82             :   void next();
      83             :   void process();
      84             :   void skip_spaces();
      85             :   void diagnose_non_character();
      86             :   int nspaces();                // is_space() as integer
      87             :   bool is_node();
      88             :   bool is_eof();
      89             :   bool is_space();
      90             :   bool is_stretchable_space();
      91             :   bool is_unstretchable_space();
      92             :   bool is_horizontal_motion();
      93             :   bool is_horizontal_whitespace();
      94             :   bool is_any_character();
      95             :   // XXX: Do we need a `is_ordinary_character()`?
      96             :   bool is_special_character();
      97             :   bool is_indexed_character();
      98             :   bool is_newline();
      99             :   bool is_tab();
     100             :   bool is_leader();
     101             :   bool is_backspace();
     102             :   bool is_usable_as_delimiter(bool /* report_error */ = false,
     103             :     enum delimiter_context /* context */ = DELIMITER_GROFF_EXPRESSION);
     104             :   bool is_dummy();
     105             :   bool is_transparent_dummy();
     106             :   bool is_transparent();
     107             :   bool is_left_brace();
     108             :   bool is_right_brace();
     109             :   bool is_page_ejector();
     110             :   bool is_hyphen_indicator();
     111             :   bool is_zero_width_break();
     112             :   bool operator==(const token &); // for delimiters & conditional exprs
     113             :   bool operator!=(const token &); // ditto
     114             :   unsigned char ch();
     115             :   int character_index();
     116             :   charinfo *get_charinfo(bool /* required */ = false,
     117             :                          bool /* suppress_creation */ = false);
     118             :   bool add_to_zero_width_node_list(node **);
     119             :   void make_space();
     120             :   void make_newline();
     121             :   void describe_node(char * /* buf */, size_t /* bufsz */);
     122             :   const char *description();
     123             : 
     124             :   friend void process_input_stack();
     125             :   friend node *do_overstrike();
     126             : };
     127             : 
     128             : extern token tok;               // the current token
     129             : 
     130             : extern bool has_arg(bool /* want_peek */ = false);
     131             : extern void skip_line();
     132             : extern symbol read_identifier(bool /* required */ = false);
     133             : extern symbol read_long_identifier(bool /* required */ = false);
     134             : extern void handle_initial_title();
     135             : extern charinfo *read_character(); // TODO?: bool /* required */ = false
     136             : extern char *read_rest_of_line_as_argument();
     137             : 
     138             : enum char_mode {
     139             :   CHAR_NORMAL,
     140             :   CHAR_FALLBACK,
     141             :   CHAR_FONT_SPECIFIC_FALLBACK,
     142             :   CHAR_SPECIAL_FALLBACK
     143             : };
     144             : 
     145             : extern void define_character(char_mode,
     146             :                              const char * /* font_name */ = 0 /* nullptr */);
     147             : 
     148             : class hunits;
     149             : extern void read_title_parts(node **part, hunits *part_width);
     150             : 
     151             : extern bool read_measurement(units * /* result */,
     152             :                              unsigned char /* scale indicator */,
     153             :                              bool /* is_mandatory */ = false);
     154             : extern bool read_integer(int *result);
     155             : 
     156             : extern bool read_measurement(units *result, unsigned char si,
     157             :                              units prev_value);
     158             : extern bool read_integer(int *result, int prev_value);
     159             : 
     160             : extern void interpolate_register(symbol, int);
     161             : 
     162    93421550 : inline bool token::is_newline()
     163             : {
     164    93421550 :   return (TOKEN_NEWLINE == type);
     165             : }
     166             : 
     167   123045884 : inline bool token::is_space()
     168             : {
     169   123045884 :   return (TOKEN_SPACE == type);
     170             : }
     171             : 
     172      177469 : inline bool token::is_stretchable_space()
     173             : {
     174      177469 :   return (TOKEN_STRETCHABLE_SPACE == type);
     175             : }
     176             : 
     177         445 : inline bool token::is_unstretchable_space()
     178             : {
     179         445 :   return (TOKEN_UNSTRETCHABLE_SPACE == type);
     180             : }
     181             : 
     182         220 : inline bool token::is_horizontal_motion()
     183             : {
     184         220 :   return ((TOKEN_HORIZONTAL_MOTION == type)
     185         220 :           || (TOKEN_DELIMITED_HORIZONTAL_MOTION == type));
     186             : }
     187             : 
     188         236 : inline bool token::is_special_character()
     189             : {
     190         236 :   return ((TOKEN_SPECIAL_CHAR == type)
     191         236 :           || (TOKEN_DELIMITED_SPECIAL_CHAR == type));
     192             : }
     193             : 
     194        4586 : inline int token::nspaces()
     195             : {
     196        4586 :   return int(TOKEN_SPACE == type);
     197             : }
     198             : 
     199    30957471 : inline bool token::is_horizontal_whitespace()
     200             : {
     201    30957471 :   return (TOKEN_SPACE == type || TOKEN_TAB == type);
     202             : }
     203             : 
     204             : inline bool token::is_transparent()
     205             : {
     206             :   return (TOKEN_TRANSPARENT == type);
     207             : }
     208             : 
     209             : inline bool token::is_page_ejector()
     210             : {
     211             :   return (TOKEN_PAGE_EJECTOR == type);
     212             : }
     213             : 
     214   233483604 : inline unsigned char token::ch()
     215             : {
     216   233483604 :   return ((TOKEN_CHAR == type) ? c : 0U); // TODO: grochar
     217             : }
     218             : 
     219        9462 : inline bool token::is_any_character()
     220             : {
     221        9462 :   return ((TOKEN_CHAR == type)
     222        5449 :           || (TOKEN_SPECIAL_CHAR == type)
     223           4 :           || (TOKEN_DELIMITED_SPECIAL_CHAR == type)
     224       14911 :           || (TOKEN_INDEXED_CHAR == type));
     225             : }
     226             : 
     227          11 : inline bool token::is_indexed_character()
     228             : {
     229          11 :   return (TOKEN_INDEXED_CHAR == type);
     230             : }
     231             : 
     232           1 : inline int token::character_index()
     233             : {
     234           1 :   assert(TOKEN_INDEXED_CHAR == type);
     235           1 :   return val;
     236             : }
     237             : 
     238             : inline bool token::is_node()
     239             : {
     240             :   return (TOKEN_NODE == type);
     241             : }
     242             : 
     243    58194407 : inline bool token::is_eof()
     244             : {
     245    58194407 :   return (TOKEN_EOF == type);
     246             : }
     247             : 
     248     1645419 : inline bool token::is_dummy()
     249             : {
     250     1645419 :   return (TOKEN_DUMMY == type);
     251             : }
     252             : 
     253         288 : inline bool token::is_transparent_dummy()
     254             : {
     255         288 :   return (TOKEN_TRANSPARENT_DUMMY == type);
     256             : }
     257             : 
     258     6369661 : inline bool token::is_left_brace()
     259             : {
     260     6369661 :   return (TOKEN_LEFT_BRACE == type);
     261             : }
     262             : 
     263     2503279 : inline bool token::is_right_brace()
     264             : {
     265     2503279 :   return (TOKEN_RIGHT_BRACE == type);
     266             : }
     267             : 
     268     3244497 : inline bool token::is_tab()
     269             : {
     270     3244497 :   return (TOKEN_TAB == type);
     271             : }
     272             : 
     273             : inline bool token::is_leader()
     274             : {
     275             :   return (TOKEN_LEADER == type);
     276             : }
     277             : 
     278             : inline bool token::is_backspace()
     279             : {
     280             :   return (TOKEN_BACKSPACE == type);
     281             : }
     282             : 
     283     1646004 : inline bool token::is_hyphen_indicator()
     284             : {
     285     1646004 :   return (TOKEN_HYPHEN_INDICATOR == type);
     286             : }
     287             : 
     288     1469379 : inline bool token::is_zero_width_break()
     289             : {
     290     1469379 :   return (TOKEN_ZERO_WIDTH_BREAK == type);
     291             : }
     292             : 
     293             : // Local Variables:
     294             : // fill-column: 72
     295             : // mode: C++
     296             : // End:
     297             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14