home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / m4-1.4-src.tgz / tar.out / fsf / m4 / src / input.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  23KB  |  853 lines

  1. /* GNU m4 -- A simple macro processor
  2.    Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
  3.   
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.   
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.   
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. /* Handling of different input sources, and lexical analysis.  */
  20.  
  21. #include "m4.h"
  22.  
  23. /* Unread input can be either files, that should be read (eg. included
  24.    files), strings, which should be rescanned (eg. macro expansion text),
  25.    or quoted macro definitions (as returned by the builtin "defn").
  26.    Unread input are organised in a stack, implemented with an obstack.
  27.    Each input source is described by a "struct input_block".  The obstack
  28.    is "input_stack".  The top of the input stack is "isp".
  29.    
  30.    The macro "m4wrap" places the text to be saved on another input stack,
  31.    on the obstack "wrapup_stack", whose top is "wsp".  When EOF is seen
  32.    on normal input (eg, when "input_stack" is empty), input is switched
  33.    over to "wrapup_stack".  To make this easier, all references to the
  34.    current input stack, whether it be "input_stack" or "wrapup_stack",
  35.    are done through a pointer "current_input", which points to either
  36.    "input_stack" or "wrapup_stack".
  37.    
  38.    Pushing new input on the input stack is done by push_file (),
  39.    push_string (), push_wrapup () (for wrapup text), and push_macro ()
  40.    (for macro definitions).  Because macro expansion needs direct access
  41.    to the current input obstack (for optimisation), push_string () are
  42.    split in two functions, push_string_init (), which returns a pointer
  43.    to the current input stack, and push_string_finish (), which return a
  44.    pointer to the final text.  The input_block *next is used to manage
  45.    the coordination between the different push routines.
  46.    
  47.    The current file and line number are stored in two global variables,
  48.    for use by the error handling functions in m4.c.  Whenever a file
  49.    input_block is pushed, the current file name and line number is saved
  50.    in the input_block, and the two variables are reset to match the new
  51.    input file.  */
  52.  
  53. #ifdef ENABLE_CHANGEWORD
  54. #include "regex.h"
  55. #endif
  56.  
  57. enum input_type
  58. {
  59.   INPUT_FILE,
  60.   INPUT_STRING,
  61.   INPUT_MACRO
  62. };
  63.  
  64. typedef enum input_type input_type;
  65.  
  66. struct input_block
  67. {
  68.   struct input_block *prev;    /* previous input_block on the input stack */
  69.   input_type type;        /* INPUT_FILE, INPUT_STRING or INPUT_MACRO */
  70.   union
  71.     {
  72.       struct
  73.     {
  74.       char *string;        /* string value */
  75.     }
  76.       u_s;
  77.       struct
  78.     {
  79.       FILE *file;        /* input file handle */
  80.       const char *name;    /* name of PREVIOUS input file */
  81.       int lineno;        /* current line number for do */
  82.       /* Yet another attack of "The curse of global variables" (sic) */
  83.       int out_lineno;    /* current output line number do */
  84.       boolean advance_line;    /* start_of_input_line from next_char () */
  85.     }
  86.       u_f;
  87.       struct
  88.     {
  89.       builtin_func *func;    /* pointer to macros function */
  90.       boolean traced;    /* TRUE iff builtin is traced */
  91.     }
  92.       u_m;
  93.     }
  94.   u;
  95. };
  96.  
  97. typedef struct input_block input_block;
  98.  
  99.  
  100. /* Current input file name.  */
  101. const char *current_file;
  102.  
  103. /* Current input line number.  */
  104. int current_line;
  105.  
  106. /* Obstack for storing individual tokens.  */
  107. static struct obstack token_stack;
  108.  
  109. /* Normal input stack.  */
  110. static struct obstack input_stack;
  111.  
  112. /* Wrapup input stack.  */
  113. static struct obstack wrapup_stack;
  114.  
  115. /* Input or wrapup.  */
  116. static struct obstack *current_input;
  117.  
  118. /* Bottom of token_stack, for obstack_free.  */
  119. static char *token_bottom;
  120.  
  121. /* Pointer to top of current_input.  */
  122. static input_block *isp;
  123.  
  124. /* Pointer to top of wrapup_stack.  */
  125. static input_block *wsp;
  126.  
  127. /* Aux. for handling split push_string ().  */
  128. static input_block *next;
  129.  
  130. /* Flag for next_char () to increment current_line.  */
  131. static boolean start_of_input_line;
  132.  
  133. #define CHAR_EOF    256    /* character return on EOF */
  134. #define CHAR_MACRO    257    /* character return for MACRO token */
  135.  
  136. /* Quote chars.  */
  137. STRING rquote;
  138. STRING lquote;
  139.  
  140. /* Comment chars.  */
  141. STRING bcomm;
  142. STRING ecomm;
  143.  
  144. #ifdef ENABLE_CHANGEWORD
  145.  
  146. #define DEFAULT_WORD_REGEXP "[_a-zA-Z][_a-zA-Z0-9]*"
  147.  
  148. static char *word_start;
  149. static struct re_pattern_buffer word_regexp;
  150. static int default_word_regexp;
  151. static struct re_registers regs;
  152.  
  153. #endif /* ENABLE_CHANGEWORD */
  154.  
  155.  
  156. /*-------------------------------------------------------------------------.
  157. | push_file () pushes an input file on the input stack, saving the current |
  158. | file name and line number.  If next is non-NULL, this push invalidates a |
  159. | call to push_string_init (), whose storage are consequentely released.   |
  160. `-------------------------------------------------------------------------*/
  161.  
  162. void
  163. push_file (FILE *fp, const char *title)
  164. {
  165.   input_block *i;
  166.  
  167.   if (next != NULL)
  168.     {
  169.       obstack_free (current_input, next);
  170.       next = NULL;
  171.     }
  172.  
  173.   if (debug_level & DEBUG_TRACE_INPUT)
  174.     DEBUG_MESSAGE1 ("input read from %s", title);
  175.  
  176.   i = (input_block *) obstack_alloc (current_input,
  177.                      sizeof (struct input_block));
  178.   i->type = INPUT_FILE;
  179.  
  180.   i->u.u_f.name = current_file;
  181.   i->u.u_f.lineno = current_line;
  182.   i->u.u_f.out_lineno = output_current_line;
  183.   i->u.u_f.advance_line = start_of_input_line;
  184.   current_file = obstack_copy0 (current_input, title, strlen (title));
  185.   current_line = 1;
  186.   output_current_line = -1;
  187.  
  188.   i->u.u_f.file = fp;
  189.   i->prev = isp;
  190.   isp = i;
  191. }
  192.  
  193. /*-------------------------------------------------------------------------.
  194. | push_macro () pushes a builtin macros definition on the input stack.  If |
  195. | next is non-NULL, this push invalidates a call to push_string_init (),   |
  196. | whose storage are consequentely released.                   |
  197. `-------------------------------------------------------------------------*/
  198.  
  199. void
  200. push_macro (builtin_func *func, boolean traced)
  201. {
  202.   input_block *i;
  203.  
  204.   if (next != NULL)
  205.     {
  206.       obstack_free (current_input, next);
  207.       next = NULL;
  208.     }
  209.  
  210.   i = (input_block *) obstack_alloc (current_input,
  211.                      sizeof (struct input_block));
  212.   i->type = INPUT_MACRO;
  213.  
  214.   i->u.u_m.func = func;
  215.   i->u.u_m.traced = traced;
  216.   i->prev = isp;
  217.   isp = i;
  218. }
  219.  
  220. /*------------------------------------------------------------------.
  221. | First half of push_string ().  The pointer next points to the new |
  222. | input_block.                                |
  223. `------------------------------------------------------------------*/
  224.  
  225. struct obstack *
  226. push_string_init (void)
  227. {
  228.   if (next != NULL)
  229.     {
  230.       M4ERROR ((warning_status, 0,
  231.         "INTERNAL ERROR: Recursive push_string!"));
  232.       abort ();
  233.     }
  234.  
  235.   next = (input_block *) obstack_alloc (current_input,
  236.                         sizeof (struct input_block));
  237.   next->type = INPUT_STRING;
  238.   return current_input;
  239. }
  240.  
  241. /*------------------------------------------------------------------------.
  242. | Last half of push_string ().  If next is now NULL, a call to push_file  |
  243. | () has invalidated the previous call to push_string_init (), so we just |
  244. | give up.  If the new object is void, we do not push it.  The function      |
  245. | push_string_finish () returns a pointer to the finished object.  This      |
  246. | pointer is only for temporary use, since reading the next token might      |
  247. | release the memory used for the object.                  |
  248. `------------------------------------------------------------------------*/
  249.  
  250. const char *
  251. push_string_finish (void)
  252. {
  253.   const char *ret = NULL;
  254.  
  255.   if (next == NULL)
  256.     return NULL;
  257.  
  258.   if (obstack_object_size (current_input) > 0)
  259.     {
  260.       obstack_1grow (current_input, '\0');
  261.       next->u.u_s.string = obstack_finish (current_input);
  262.       next->prev = isp;
  263.       isp = next;
  264.       ret = isp->u.u_s.string;    /* for immediate use only */
  265.     }
  266.   else
  267.     obstack_free (current_input, next); /* people might leave garbage on it. */
  268.   next = NULL;
  269.   return ret;
  270. }
  271.  
  272. /*--------------------------------------------------------------------------.
  273. | The function push_wrapup () pushes a string on the wrapup stack.  When    |
  274. | he normal input stack gets empty, the wrapup stack will become the input  |
  275. | stack, and push_string () and push_file () will operate on wrapup_stack.  |
  276. | Push_wrapup should be done as push_string (), but this will suffice, as   |
  277. | long as arguments to m4_m4wrap () are moderate in size.            |
  278. `--------------------------------------------------------------------------*/
  279.  
  280. void
  281. push_wrapup (const char *s)
  282. {
  283.   input_block *i = (input_block *) obstack_alloc (&wrapup_stack,
  284.                           sizeof (struct input_block));
  285.   i->prev = wsp;
  286.   i->type = INPUT_STRING;
  287.   i->u.u_s.string = obstack_copy0 (&wrapup_stack, s, strlen (s));
  288.   wsp = i;
  289. }
  290.  
  291.  
  292. /*-------------------------------------------------------------------------.
  293. | The function pop_input () pops one level of input sources.  If the       |
  294. | popped input_block is a file, current_file and current_line are reset to |
  295. | the saved values before the memory for the input_block are released.       |
  296. `-------------------------------------------------------------------------*/
  297.  
  298. static void
  299. pop_input (void)
  300. {
  301.   input_block *tmp = isp->prev;
  302.  
  303.   switch (isp->type)
  304.     {
  305.     case INPUT_STRING:
  306.     case INPUT_MACRO:
  307.       break;
  308.  
  309.     case INPUT_FILE:
  310.       if (debug_level & DEBUG_TRACE_INPUT)
  311.     DEBUG_MESSAGE2 ("input reverted to %s, line %d",
  312.             isp->u.u_f.name, isp->u.u_f.lineno);
  313.  
  314.       fclose (isp->u.u_f.file);
  315.       current_file = isp->u.u_f.name;
  316.       current_line = isp->u.u_f.lineno;
  317.       output_current_line = isp->u.u_f.out_lineno;
  318.       start_of_input_line = isp->u.u_f.advance_line;
  319.       if (tmp != NULL)
  320.     output_current_line = -1;
  321.       break;
  322.  
  323.     default:
  324.       M4ERROR ((warning_status, 0,
  325.         "INTERNAL ERROR: Input stack botch in pop_input ()"));
  326.       abort ();
  327.     }
  328.   obstack_free (current_input, isp);
  329.   next = NULL;            /* might be set in push_string_init () */
  330.  
  331.   isp = tmp;
  332. }
  333.  
  334. /*------------------------------------------------------------------------.
  335. | To switch input over to the wrapup stack, main () calls pop_wrapup ().  |
  336. | Since wrapup text can install new wrapup text, pop_wrapup () returns      |
  337. | FALSE when there is no wrapup text on the stack, and TRUE otherwise.      |
  338. `------------------------------------------------------------------------*/
  339.  
  340. boolean
  341. pop_wrapup (void)
  342. {
  343.   if (wsp == NULL)
  344.     return FALSE;
  345.  
  346.   current_input = &wrapup_stack;
  347.   isp = wsp;
  348.   wsp = NULL;
  349.  
  350.   return TRUE;
  351. }
  352.  
  353. /*--------------------------------------------------------------------.
  354. | When a MACRO token is seen, next_token () uses init_macro_token () to |
  355. | retrieve the value of the function pointer.                  |
  356. `--------------------------------------------------------------------*/
  357.  
  358. static void
  359. init_macro_token (token_data *td)
  360. {
  361.   if (isp->type != INPUT_MACRO)
  362.     {
  363.       M4ERROR ((warning_status, 0,
  364.         "INTERNAL ERROR: Bad call to init_macro_token ()"));
  365.       abort ();
  366.     }
  367.  
  368.   TOKEN_DATA_TYPE (td) = TOKEN_FUNC;
  369.   TOKEN_DATA_FUNC (td) = isp->u.u_m.func;
  370.   TOKEN_DATA_FUNC_TRACED (td) = isp->u.u_m.traced;
  371. }
  372.  
  373.  
  374. /*------------------------------------------------------------------------.
  375. | Low level input is done a character at a time.  The function peek_input |
  376. | () is used to look at the next character in the input stream.  At any      |
  377. | given time, it reads from the input_block on the top of the current      |
  378. | input stack.                                  |
  379. `------------------------------------------------------------------------*/
  380.  
  381. int
  382. peek_input (void)
  383. {
  384.   register int ch;
  385.  
  386.   while (1)
  387.     {
  388.       if (isp == NULL)
  389.     return CHAR_EOF;
  390.  
  391.       switch (isp->type)
  392.     {
  393.     case INPUT_STRING:
  394.       ch = isp->u.u_s.string[0];
  395.       if (ch != '\0')
  396.         return ch;
  397.       break;
  398.  
  399.     case INPUT_FILE:
  400.       ch = getc (isp->u.u_f.file);
  401.       if (ch != EOF)
  402.         {
  403.           ungetc (ch, isp->u.u_f.file);
  404.           return ch;
  405.         }
  406.       break;
  407.  
  408.     case INPUT_MACRO:
  409.       return CHAR_MACRO;
  410.  
  411.     default:
  412.       M4ERROR ((warning_status, 0,
  413.             "INTERNAL ERROR: Input stack botch in peek_input ()"));
  414.       abort ();
  415.     }
  416.       /* End of input source --- pop one level.  */
  417.       pop_input ();
  418.     }
  419. }
  420.  
  421. /*-------------------------------------------------------------------------.
  422. | The function next_char () is used to read and advance the input to the   |
  423. | next character.  It also manages line numbers for error messages, so       |
  424. | they do not get wrong, due to lookahead.  The token consisting of a       |
  425. | newline alone is taken as belonging to the line it ends, and the current |
  426. | line number is not incremented until the next character is read.       |
  427. `-------------------------------------------------------------------------*/
  428.  
  429. static int
  430. next_char (void)
  431. {
  432.   register int ch;
  433.  
  434.   if (start_of_input_line)
  435.     {
  436.       start_of_input_line = FALSE;
  437.       current_line++;
  438.     }
  439.  
  440.   while (1)
  441.     {
  442.       if (isp == NULL)
  443.     return CHAR_EOF;
  444.  
  445.       switch (isp->type)
  446.     {
  447.     case INPUT_STRING:
  448.       ch = *isp->u.u_s.string++;
  449.       if (ch != '\0')
  450.         return ch;
  451.       break;
  452.  
  453.     case INPUT_FILE:
  454.       ch = getc (isp->u.u_f.file);
  455.       if (ch != EOF)
  456.         {
  457.           if (ch == '\n')
  458.         start_of_input_line = TRUE;
  459.           return ch;
  460.         }
  461.       break;
  462.  
  463.     case INPUT_MACRO:
  464.       pop_input ();        /* INPUT_MACRO input sources has only one
  465.                    token */
  466.       return CHAR_MACRO;
  467.  
  468.     default:
  469.       M4ERROR ((warning_status, 0,
  470.             "INTERNAL ERROR: Input stack botch in next_char ()"));
  471.       abort ();
  472.     }
  473.  
  474.       /* End of input source --- pop one level.  */
  475.       pop_input ();
  476.     }
  477. }
  478.  
  479. /*------------------------------------------------------------------------.
  480. | skip_line () simply discards all immediately following characters, upto |
  481. | the first newline.  It is only used from m4_dnl ().              |
  482. `------------------------------------------------------------------------*/
  483.  
  484. void
  485. skip_line (void)
  486. {
  487.   int ch;
  488.  
  489.   while ((ch = next_char ()) != CHAR_EOF && ch != '\n')
  490.     ;
  491. }
  492.  
  493.  
  494. /*----------------------------------------------------------------------.
  495. | This function is for matching a string against a prefix of the input  |
  496. | stream.  If the string matches the input, the input is discarded,     |
  497. | otherwise the characters read are pushed back again.  The function is |
  498. | used only when multicharacter quotes or comment delimiters are used.  |
  499. `----------------------------------------------------------------------*/
  500.  
  501. static int
  502. match_input (const char *s)
  503. {
  504.   int n;            /* number of characters matched */
  505.   int ch;            /* input character */
  506.   const char *t;
  507.  
  508.   ch = peek_input ();
  509.   if (ch != *s)
  510.     return 0;            /* fail */
  511.   (void) next_char ();
  512.  
  513.   if (s[1] == '\0')
  514.     return 1;            /* short match */
  515.  
  516.   for (n = 1, t = s++; (ch = peek_input ()) == *s++; n++)
  517.     {
  518.       (void) next_char ();
  519.       if (*s == '\0')        /* long match */
  520.     return 1;
  521.     }
  522.  
  523.   /* Failed, push back input.  */
  524.   obstack_grow (push_string_init (), t, n);
  525.   push_string_finish ();
  526.   return 0;
  527. }
  528.  
  529. /*------------------------------------------------------------------------.
  530. | The macro MATCH() is used to match a string against the input.  The      |
  531. | first character is handled inline, for speed.  Hopefully, this will not |
  532. | hurt efficiency too much when single character quotes and comment      |
  533. | delimiters are used.                              |
  534. `------------------------------------------------------------------------*/
  535.  
  536. #define MATCH(ch, s) \
  537.   ((s)[0] == (ch) \
  538.    && (ch) != '\0' \
  539.    && ((s)[1] == '\0' \
  540.        || (match_input ((s) + 1) ? (ch) = peek_input (), 1 : 0)))
  541.  
  542.  
  543. /*----------------------------------------------------------.
  544. | Inititialise input stacks, and quote/comment characters.  |
  545. `----------------------------------------------------------*/
  546.  
  547. void
  548. input_init (void)
  549. {
  550.   current_file = "NONE";
  551.   current_line = 0;
  552.  
  553.   obstack_init (&token_stack);
  554.   obstack_init (&input_stack);
  555.   obstack_init (&wrapup_stack);
  556.  
  557.   current_input = &input_stack;
  558.  
  559.   obstack_1grow (&token_stack, '\0');
  560.   token_bottom = obstack_finish (&token_stack);
  561.  
  562.   isp = NULL;
  563.   wsp = NULL;
  564.   next = NULL;
  565.  
  566.   start_of_input_line = FALSE;
  567.  
  568.   lquote.string = xstrdup (DEF_LQUOTE);
  569.   lquote.length = strlen (lquote.string);
  570.   rquote.string = xstrdup (DEF_RQUOTE);
  571.   rquote.length = strlen (rquote.string);
  572.   bcomm.string = xstrdup (DEF_BCOMM);
  573.   bcomm.length = strlen (bcomm.string);
  574.   ecomm.string = xstrdup (DEF_ECOMM);
  575.   ecomm.length = strlen (ecomm.string);
  576.  
  577. #ifdef ENABLE_CHANGEWORD
  578.   if (user_word_regexp)
  579.     set_word_regexp (user_word_regexp);
  580.   else
  581.     set_word_regexp (DEFAULT_WORD_REGEXP);
  582. #endif
  583. }
  584.  
  585.  
  586. /*--------------------------------------------------------------.
  587. | Functions for setting quotes and comment delimiters.  Used by |
  588. | m4_changecom () and m4_changequote ().                |
  589. `--------------------------------------------------------------*/
  590.  
  591. void
  592. set_quotes (const char *lq, const char *rq)
  593. {
  594.   xfree (lquote.string);
  595.   xfree (rquote.string);
  596.  
  597.   lquote.string = xstrdup (lq ? lq : DEF_LQUOTE);
  598.   lquote.length = strlen (lquote.string);
  599.   rquote.string = xstrdup (rq ? rq : DEF_RQUOTE);
  600.   rquote.length = strlen (rquote.string);
  601. }
  602.  
  603. void
  604. set_comment (const char *bc, const char *ec)
  605. {
  606.   xfree (bcomm.string);
  607.   xfree (ecomm.string);
  608.  
  609.   bcomm.string = xstrdup (bc ? bc : DEF_BCOMM);
  610.   bcomm.length = strlen (bcomm.string);
  611.   ecomm.string = xstrdup (ec ? ec : DEF_ECOMM);
  612.   ecomm.length = strlen (ecomm.string);
  613. }
  614.  
  615. #ifdef ENABLE_CHANGEWORD
  616.  
  617. void
  618. set_word_regexp (const char *regexp)
  619. {
  620.   int i;
  621.   char test[2];
  622.   const char *msg;
  623.  
  624.   if (!strcmp (regexp, DEFAULT_WORD_REGEXP))
  625.     {
  626.       default_word_regexp = TRUE;
  627.       return;
  628.     }
  629.  
  630.   default_word_regexp = FALSE;
  631.  
  632.   msg = re_compile_pattern (regexp, strlen (regexp), &word_regexp);
  633.  
  634.   if (msg != NULL)
  635.     {
  636.       M4ERROR ((warning_status, 0,
  637.         "Bad regular expression `%s': %s", regexp, msg));
  638.       return;
  639.     }
  640.  
  641.   if (word_start == NULL)
  642.     word_start = xmalloc (256);
  643.  
  644.   word_start[0] = '\0';
  645.   test[1] = '\0';
  646.   for (i = 1; i < 256; i++)
  647.     {
  648.       test[0] = i;
  649.       if (re_search (&word_regexp, test, 1, 0, 0, ®s) >= 0)
  650.     strcat (word_start, test);
  651.     }
  652. }
  653.  
  654. #endif /* ENABLE_CHANGEWORD */
  655.  
  656.  
  657. /*-------------------------------------------------------------------------.
  658. | Parse and return a single token from the input stream.  A token can       |
  659. | either be TOKEN_EOF, if the input_stack is empty; it can be TOKEN_STRING |
  660. | for a quoted string; TOKEN_WORD for something that is a potential macro  |
  661. | name; and TOKEN_SIMPLE for any single character that is not a part of       |
  662. | any of the previous types.                           |
  663. |                                        |
  664. | Next_token () return the token type, and passes back a pointer to the       |
  665. | token data through TD.  The token text is collected on the obstack       |
  666. | token_stack, which never contains more than one token text at a time.       |
  667. | The storage pointed to by the fields in TD is therefore subject to       |
  668. | change the next time next_token () is called.                   |
  669. `-------------------------------------------------------------------------*/
  670.  
  671. token_type
  672. next_token (token_data *td)
  673. {
  674.   int ch;
  675.   int quote_level;
  676.   token_type type;
  677. #ifdef ENABLE_CHANGEWORD
  678.   int startpos;
  679.   char *orig_text = 0;
  680. #endif
  681.  
  682.   obstack_free (&token_stack, token_bottom);
  683.   obstack_1grow (&token_stack, '\0');
  684.   token_bottom = obstack_finish (&token_stack);
  685.  
  686.   ch = peek_input ();
  687.   if (ch == CHAR_EOF)
  688.     {
  689.       return TOKEN_EOF;
  690. #ifdef DEBUG_INPUT
  691.       fprintf (stderr, "next_token -> EOF\n");
  692. #endif
  693.     }
  694.   if (ch == CHAR_MACRO)
  695.     {
  696.       init_macro_token (td);
  697.       (void) next_char ();
  698.       return TOKEN_MACDEF;
  699.     }
  700.  
  701.   (void) next_char ();
  702.   if (MATCH (ch, bcomm.string))
  703.     {
  704.       obstack_grow (&token_stack, bcomm.string, bcomm.length);
  705.       while ((ch = next_char ()) != CHAR_EOF && !MATCH (ch, ecomm.string))
  706.     obstack_1grow (&token_stack, ch);
  707.       if (ch != CHAR_EOF)
  708.     obstack_grow (&token_stack, ecomm.string, ecomm.length);
  709.       type = TOKEN_STRING;
  710.     }
  711. #ifdef ENABLE_CHANGEWORD
  712.   else if (default_word_regexp && (isalpha (ch) || ch == '_'))
  713. #else
  714.   else if (isalpha (ch) || ch == '_')
  715. #endif
  716.     {
  717.       obstack_1grow (&token_stack, ch);
  718.       while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_'))
  719.     {
  720.       obstack_1grow (&token_stack, ch);
  721.       (void) next_char ();
  722.     }
  723.       type = TOKEN_WORD;
  724.     }
  725.  
  726. #ifdef ENABLE_CHANGEWORD
  727.  
  728.   else if (!default_word_regexp && strchr (word_start, ch))
  729.     {
  730.       obstack_1grow (&token_stack, ch);
  731.       while (1)
  732.         {
  733.       ch = peek_input ();
  734.       if (ch == CHAR_EOF)
  735.         break;
  736.       obstack_1grow (&token_stack, ch);
  737.       startpos = re_search (&word_regexp, obstack_base (&token_stack),
  738.                 obstack_object_size (&token_stack), 0, 0,
  739.                 ®s);
  740.       if (startpos != 0 ||
  741.           regs.end [0] != obstack_object_size (&token_stack))
  742.         {
  743.           *(((char *) obstack_base (&token_stack)
  744.          + obstack_object_size (&token_stack)) - 1) = '\0';
  745.           break;
  746.         }
  747.       next_char ();
  748.     }
  749.  
  750.       obstack_1grow (&token_stack, '\0');
  751.       orig_text = obstack_finish (&token_stack);
  752.  
  753.       if (regs.start[1] != -1)
  754.     obstack_grow (&token_stack,orig_text + regs.start[1],
  755.               regs.end[1] - regs.start[1]);
  756.       else
  757.     obstack_grow (&token_stack, orig_text,regs.end[0]);
  758.  
  759.       type = TOKEN_WORD;
  760.     }
  761.  
  762. #endif /* ENABLE_CHANGEWORD */
  763.  
  764.   else if (!MATCH (ch, lquote.string))
  765.     {
  766.       type = TOKEN_SIMPLE;
  767.       obstack_1grow (&token_stack, ch);
  768.     }
  769.   else
  770.     {
  771.       quote_level = 1;
  772.       while (1)
  773.     {
  774.       ch = next_char ();
  775.       if (ch == CHAR_EOF)
  776.         M4ERROR ((EXIT_FAILURE, 0,
  777.               "ERROR: EOF in string"));
  778.  
  779.       if (MATCH (ch, rquote.string))
  780.         {
  781.           if (--quote_level == 0)
  782.         break;
  783.           obstack_grow (&token_stack, rquote.string, rquote.length);
  784.         }
  785.       else if (MATCH (ch, lquote.string))
  786.         {
  787.           quote_level++;
  788.           obstack_grow (&token_stack, lquote.string, lquote.length);
  789.         }
  790.       else
  791.         obstack_1grow (&token_stack, ch);
  792.     }
  793.       type = TOKEN_STRING;
  794.     }
  795.  
  796.   obstack_1grow (&token_stack, '\0');
  797.  
  798.   TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
  799.   TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack);
  800. #ifdef ENABLE_CHANGEWORD
  801.   if (orig_text == NULL)
  802.     orig_text = TOKEN_DATA_TEXT (td);
  803.   TOKEN_DATA_ORIG_TEXT (td) = orig_text;
  804. #endif
  805. #ifdef DEBUG_INPUT
  806.   fprintf (stderr, "next_token -> %d (%s)\n", type, TOKEN_DATA_TEXT (td));
  807. #endif
  808.   return type;
  809. }
  810.  
  811.  
  812. #ifdef DEBUG_INPUT
  813.  
  814. static void
  815. print_token (const char *s, token_type t, token_data *td)
  816. {
  817.   fprintf (stderr, "%s: ", s);
  818.   switch (t)
  819.     {                /* TOKSW */
  820.     case TOKEN_SIMPLE:
  821.       fprintf (stderr, "char:");
  822.       break;
  823.  
  824.     case TOKEN_WORD:
  825.       fprintf (stderr, "word:");
  826.       break;
  827.  
  828.     case TOKEN_STRING:
  829.       fprintf (stderr, "string:");
  830.       break;
  831.  
  832.     case TOKEN_MACDEF:
  833.       fprintf (stderr, "macro: 0x%x\n", TOKEN_DATA_FUNC (td));
  834.       break;
  835.  
  836.     case TOKEN_EOF:
  837.       fprintf (stderr, "eof\n");
  838.       break;
  839.     }
  840.   fprintf (stderr, "\t\"%s\"\n", TOKEN_DATA_TEXT (td));
  841. }
  842.  
  843. static void
  844. lex_debug (void)
  845. {
  846.   token_type t;
  847.   token_data td;
  848.  
  849.   while ((t = next_token (&td)) != NULL)
  850.     print_token ("lex", t, &td);
  851. }
  852. #endif
  853.