OSDN Git Service

91th Cygnus<->FSF merge
[pf3gnuchains/gcc-fork.git] / gcc / bi-lexer.c
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 }