home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / bi-lexer.c < prev    next >
C/C++ Source or Header  |  1995-12-29  |  4KB  |  168 lines

  1. /* Lexer for scanner of bytecode definition file.
  2.    Copyright (C) 1993, 1995 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21. #include <stdio.h>
  22. #include "hconfig.h"
  23. #include "bi-parser.h"
  24.  
  25.  
  26. /* Safely allocate NBYTES bytes of memory.  Returns pointer to block of
  27.    memory. */
  28.  
  29. static char *
  30. xmalloc (nbytes)
  31.      int nbytes;
  32. {
  33.   char *tmp = (char *) malloc (nbytes);
  34.  
  35.   if (!tmp)
  36.     {
  37.       fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
  38.       exit (FATAL_EXIT_CODE);
  39.     }
  40.  
  41.   return tmp;
  42. }
  43.  
  44.  
  45. /* Safely reallocate BLOCK so its size becomes NBYTES.
  46.    The block returned may be different from the one supplied. */
  47.  
  48. static char *
  49. xrealloc (block, nbytes)
  50.      char *block;
  51.      int nbytes;
  52. {
  53.   char *tmp = (block
  54.            ? (char *) realloc (block, nbytes)
  55.            : (char *) malloc (nbytes));
  56.  
  57.   if (!tmp)
  58.     {
  59.       fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes);
  60.       exit (FATAL_EXIT_CODE);
  61.     }
  62.  
  63.   return tmp;
  64. }
  65.  
  66.  
  67. /* Scan for string token on standard input.  A string is, for our
  68.    purposes here, a sequence of characters that starts with the regexp
  69.    ``[^ #\t\n(),]'' and is then followed by the regexp ``[^#(),]*''. Any
  70.    character is accepted if preceded by a backslash, "\\".  It is assumed
  71.    that the first character has already been checked by the main loop. */
  72.  
  73. static char *
  74. scan_string ()
  75. {
  76.   char *buffer = NULL;
  77.   char *point = NULL;
  78.   int buffer_size = 0;
  79.   int c;
  80.  
  81.   while ((c = getc (stdin)) != EOF
  82.      && c != '#' && c != '(' && c != ')' && c != ',')
  83.     {
  84.       /* Extend buffer, if necessary (minus two so there's room for the NUL
  85.      trailer as well as another character if this one is a backslash).  */
  86.       if (!buffer_size || (point - buffer >= buffer_size-2))
  87.     {
  88.       int previous_point_index = point - buffer;
  89.  
  90.       buffer_size = (!buffer_size ? 32 : buffer_size * 2);
  91.       if (!buffer)
  92.         buffer = xmalloc (buffer_size);
  93.       else
  94.         buffer = xrealloc (buffer, buffer_size);
  95.       
  96.       point = buffer + previous_point_index;
  97.     }
  98.       *point++ = c & 0xff;
  99.  
  100.       if (c == '\\')
  101.     {
  102.       c = getc (stdin);
  103.  
  104.       /* Catch special case: backslash at end of file */
  105.       if (c == EOF)
  106.         break;
  107.  
  108.       *point++ = c;
  109.     }
  110.     }
  111.   *point = 0;
  112.  
  113.   if (c != EOF)
  114.     ungetc (c, stdin);
  115.  
  116.   return buffer;
  117. }
  118.  
  119.  
  120. int
  121. yylex ()
  122. {
  123.   int c;
  124.   char *token;
  125.  
  126.  
  127.   /* First char determines what token we're looking at */
  128.   for (;;)
  129.     {
  130.       c = getc (stdin);
  131.  
  132.       switch (c)
  133.     {
  134.     case EOF:
  135.       return 0;
  136.       
  137.     case ' ':
  138.     case '\t':
  139.     case '\n':
  140.       /* Ignore whitespace */
  141.       continue;
  142.       
  143.     case '#':
  144.       /* Comments advance to next line */
  145.       while ((c = getc (stdin)) != '\n' && c != EOF);
  146.       continue;
  147.       
  148.     default:
  149.       if (c != '(' && c != ')' && c != '\\' && c != ',')
  150.         {
  151.           ungetc (c, stdin);
  152.           yylval.string = scan_string ();
  153.  
  154.           /* Check if string is "define_operator"; if so, return
  155.          a DEFOP token instead.  */
  156.           if (!strcmp (yylval.string, "define_operator"))
  157.         {
  158.           free (yylval.string);
  159.           yylval.string = 0;
  160.           return DEFOP;
  161.         }
  162.           return STRING;
  163.         }
  164.       return c & 0xff;
  165.     }
  166.     }
  167. }
  168.