]>
Commit | Line | Data |
---|---|---|
6a94387c | 1 | /* Lexer for scanner of bytecode definition file. |
f4bef7f6 | 2 | Copyright (C) 1993, 1995 Free Software Foundation, Inc. |
6a94387c JB |
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 | |
940d9d63 RK |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
19 | Boston, MA 02111-1307, USA. */ | |
6a94387c JB |
20 | |
21 | #include <stdio.h> | |
a2c18d49 | 22 | #include "hconfig.h" |
6a94387c JB |
23 | #include "bi-parser.h" |
24 | ||
6a94387c | 25 | |
ddd5a7c1 | 26 | /* Safely allocate NBYTES bytes of memory. Returns pointer to block of |
0f41302f | 27 | memory. */ |
6a94387c JB |
28 | |
29 | static char * | |
30 | xmalloc (nbytes) | |
31 | int nbytes; | |
32 | { | |
e4f316db | 33 | char *tmp = (char *) malloc (nbytes); |
6a94387c JB |
34 | |
35 | if (!tmp) | |
36 | { | |
37 | fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes); | |
6026c19c | 38 | exit (FATAL_EXIT_CODE); |
6a94387c JB |
39 | } |
40 | ||
41 | return tmp; | |
42 | } | |
43 | ||
44 | ||
45 | /* Safely reallocate BLOCK so its size becomes NBYTES. | |
0f41302f | 46 | The block returned may be different from the one supplied. */ |
6a94387c JB |
47 | |
48 | static char * | |
49 | xrealloc (block, nbytes) | |
50 | char *block; | |
51 | int nbytes; | |
52 | { | |
e4f316db RS |
53 | char *tmp = (block |
54 | ? (char *) realloc (block, nbytes) | |
55 | : (char *) malloc (nbytes)); | |
6a94387c JB |
56 | |
57 | if (!tmp) | |
58 | { | |
59 | fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes); | |
6026c19c | 60 | exit (FATAL_EXIT_CODE); |
6a94387c JB |
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 | |
0f41302f | 71 | that the first character has already been checked by the main loop. */ |
6a94387c JB |
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); | |
56ae2659 | 91 | if (!buffer) |
6a94387c JB |
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 | } |