Add v850e version of breakpoint. Make v850 breakpoint unique.
[deliverable/binutils-gdb.git] / binutils / rclex.l
CommitLineData
1d371d35
ILT
1%{ /* rclex.l -- lexer for Windows rc files parser */
2/* Copyright 1997 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22/* This is a lex input file which generates a lexer used by the
23 Windows rc file parser. It basically just recognized a bunch of
24 keywords. */
25
26#include "bfd.h"
27#include "bucomm.h"
28#include "libiberty.h"
29#include "windres.h"
30#include "rcparse.h"
31
32#include <ctype.h>
33#include <assert.h>
34
662cc41e
ILT
35/* Whether we are in rcdata mode, in which we returns the lengths of
36 strings. */
37
38static int rcdata_mode;
39
40/* List of allocated strings. */
41
42struct alloc_string
43{
44 struct alloc_string *next;
45 char *s;
46};
47
48static struct alloc_string *strings;
49
50/* Local functions. */
51
1d371d35 52static void cpp_line PARAMS ((const char *));
662cc41e
ILT
53static char *handle_quotes PARAMS ((const char *, unsigned long *));
54static char *get_string PARAMS ((int));
1d371d35
ILT
55
56%}
57
58%%
59
60"BEGIN" { return BEG; }
61"END" { return END; }
62"ACCELERATORS" { return ACCELERATORS; }
63"VIRTKEY" { return VIRTKEY; }
64"ASCII" { return ASCII; }
65"NOINVERT" { return NOINVERT; }
66"SHIFT" { return SHIFT; }
67"CONTROL" { return CONTROL; }
68"ALT" { return ALT; }
69"BITMAP" { return BITMAP; }
70"CURSOR" { return CURSOR; }
71"DIALOG" { return DIALOG; }
72"DIALOGEX" { return DIALOGEX; }
73"EXSTYLE" { return EXSTYLE; }
74"CAPTION" { return CAPTION; }
75"CLASS" { return CLASS; }
76"STYLE" { return STYLE; }
77"AUTO3STATE" { return AUTO3STATE; }
78"AUTOCHECKBOX" { return AUTOCHECKBOX; }
79"AUTORADIOBUTTON" { return AUTORADIOBUTTON; }
80"CHECKBOX" { return CHECKBOX; }
81"COMBOBOX" { return COMBOBOX; }
82"CTEXT" { return CTEXT; }
83"DEFPUSHBUTTON" { return DEFPUSHBUTTON; }
84"EDITTEXT" { return EDITTEXT; }
85"GROUPBOX" { return GROUPBOX; }
86"LISTBOX" { return LISTBOX; }
87"LTEXT" { return LTEXT; }
88"PUSHBOX" { return PUSHBOX; }
89"PUSHBUTTON" { return PUSHBUTTON; }
90"RADIOBUTTON" { return RADIOBUTTON; }
91"RTEXT" { return RTEXT; }
92"SCROLLBAR" { return SCROLLBAR; }
93"STATE3" { return STATE3; }
94"USERBUTTON" { return USERBUTTON; }
95"BEDIT" { return BEDIT; }
96"HEDIT" { return HEDIT; }
97"IEDIT" { return IEDIT; }
98"FONT" { return FONT; }
99"ICON" { return ICON; }
100"LANGUAGE" { return LANGUAGE; }
101"CHARACTERISTICS" { return CHARACTERISTICS; }
e5b3abe4 102"VERSION" { return VERSIONK; }
1d371d35
ILT
103"MENU" { return MENU; }
104"MENUEX" { return MENUEX; }
105"MENUITEM" { return MENUITEM; }
106"SEPARATOR" { return SEPARATOR; }
107"POPUP" { return POPUP; }
108"CHECKED" { return CHECKED; }
109"GRAYED" { return GRAYED; }
110"HELP" { return HELP; }
111"INACTIVE" { return INACTIVE; }
112"MENUBARBREAK" { return MENUBARBREAK; }
113"MENUBREAK" { return MENUBREAK; }
114"MESSAGETABLE" { return MESSAGETABLE; }
115"RCDATA" { return RCDATA; }
116"STRINGTABLE" { return STRINGTABLE; }
117"VERSIONINFO" { return VERSIONINFO; }
118"FILEVERSION" { return FILEVERSION; }
119"PRODUCTVERSION" { return PRODUCTVERSION; }
120"FILEFLAGSMASK" { return FILEFLAGSMASK; }
121"FILEFLAGS" { return FILEFLAGS; }
122"FILEOS" { return FILEOS; }
123"FILETYPE" { return FILETYPE; }
124"FILESUBTYPE" { return FILESUBTYPE; }
125"VALUE" { return VALUE; }
126"MOVEABLE" { return MOVEABLE; }
127"FIXED" { return FIXED; }
128"PURE" { return PURE; }
129"IMPURE" { return IMPURE; }
130"PRELOAD" { return PRELOAD; }
131"LOADONCALL" { return LOADONCALL; }
132"DISCARDABLE" { return DISCARDABLE; }
133"NOT" { return NOT; }
134
135"BLOCK"[ \t\n]*"\""[^\#\n]*"\"" {
136 char *s, *send;
137
138 /* This is a hack to let us parse version
139 information easily. */
140
141 s = strchr (yytext, '"');
142 ++s;
143 send = strchr (s, '"');
144 if (strncmp (s, "StringFileInfo",
145 sizeof "StringFileInfo" - 1) == 0
146 && s + sizeof "StringFileInfo" - 1 == send)
147 return BLOCKSTRINGFILEINFO;
148 else if (strncmp (s, "VarFileInfo",
149 sizeof "VarFileInfo" - 1) == 0
150 && s + sizeof "VarFileInfo" - 1 == send)
151 return BLOCKVARFILEINFO;
152 else
153 {
662cc41e
ILT
154 char *r;
155
156 r = get_string (send - s + 1);
157 strncpy (r, s, send - s);
158 r[send - s] = '\0';
159 yylval.s = r;
1d371d35
ILT
160 return BLOCK;
161 }
162 }
163
164"#"[^\n]* {
165 cpp_line (yytext);
166 }
167
168[0-9][x0-9A-Fa-f]*L {
169 yylval.i.val = strtoul (yytext, 0, 0);
170 yylval.i.dword = 1;
171 return NUMBER;
172 }
173
174[0-9][x0-9A-Fa-f]* {
175 yylval.i.val = strtoul (yytext, 0, 0);
176 yylval.i.dword = 0;
177 return NUMBER;
178 }
179
180("\""[^\"\n]*"\""[ \t]*)+ {
662cc41e
ILT
181 char *s;
182 unsigned long length;
183
184 s = handle_quotes (yytext, &length);
185 if (! rcdata_mode)
186 {
187 yylval.s = s;
188 return QUOTEDSTRING;
189 }
190 else
191 {
192 yylval.ss.length = length;
193 yylval.ss.s = s;
194 return SIZEDSTRING;
195 }
1d371d35
ILT
196 }
197
198[A-Za-z][^ \t\r\n]* {
662cc41e
ILT
199 char *s;
200
201 s = get_string (strlen (yytext) + 1);
202 strcpy (s, yytext);
203 yylval.s = s;
1d371d35
ILT
204 return STRING;
205 }
206
207[\n] { ++rc_lineno; }
208[ \t\r]+ { /* ignore whitespace */ }
209. { return *yytext; }
210
211%%
212#ifndef yywrap
213/* This is needed for some versions of lex. */
214int yywrap ()
215{
216 return 1;
217}
218#endif
219
220/* Handle a C preprocessor line. */
221
222static void
223cpp_line (s)
224 const char *s;
225{
226 int line;
227 char *send, *fn;
228
229 ++s;
230 while (isspace (*s))
231 ++s;
232
233 line = strtol (s, &send, 0);
234 if (*send != '\0' && ! isspace (*send))
235 return;
236
237 /* Subtract 1 because we are about to count the newline. */
238 rc_lineno = line - 1;
239
240 s = send;
241 while (isspace (*s))
242 ++s;
243
244 if (*s != '"')
245 return;
246
247 ++s;
248 send = strchr (s, '"');
249 if (send == NULL)
250 return;
251
252 fn = (char *) xmalloc (send - s + 1);
253 strncpy (fn, s, send - s);
254 fn[send - s] = '\0';
255
256 free (rc_filename);
257 rc_filename = fn;
258}
259
260/* Handle a quoted string. The quotes are stripped. A pair of quotes
261 in a string are turned into a single quote. Adjacent strings are
262 merged separated by whitespace are merged, as in C. */
263
264static char *
662cc41e 265handle_quotes (input, len)
1d371d35 266 const char *input;
662cc41e 267 unsigned long *len;
1d371d35
ILT
268{
269 char *ret, *s;
270 const char *t;
271 int ch;
272
662cc41e 273 ret = get_string (strlen (input) + 1);
1d371d35
ILT
274
275 s = ret;
276 t = input;
277 if (*t == '"')
278 ++t;
279 while (*t != '\0')
280 {
281 if (*t == '\\')
282 {
283 ++t;
284 switch (*t)
285 {
286 case '\0':
287 rcparse_warning ("backslash at end of string");
288 break;
289
290 case '\"':
291 rcparse_warning ("use \"\" to put \" in a string");
292 break;
293
294 case '\\':
295 *s++ = *t++;
296 break;
297
298 case '0': case '1': case '2': case '3':
299 case '4': case '5': case '6': case '7':
300 ch = *t - '0';
301 ++t;
302 if (*t >= '0' && *t <= '7')
303 {
304 ch = (ch << 3) | (*t - '0');
305 ++t;
306 if (*t >= '0' && *t <= '7')
307 {
308 ch = (ch << 3) | (*t - '0');
309 ++t;
310 }
311 }
312 *s++ = ch;
313 break;
314
315 case 'x':
316 ++t;
317 ch = 0;
318 while (1)
319 {
320 if (*t >= '0' && *t <= '9')
321 ch = (ch << 4) | (*t - '0');
322 else if (*t >= 'a' && *t <= 'f')
323 ch = (ch << 4) | (*t - 'a');
324 else if (*t >= 'A' && *t <= 'F')
325 ch = (ch << 4) | (*t - 'A');
326 else
327 break;
328 ++t;
329 }
330 *s++ = ch;
331 break;
332 }
333 }
334 else if (*t != '"')
335 *s++ = *t++;
336 else if (t[1] == '\0')
337 break;
338 else if (t[1] == '"')
339 {
340 *s++ = '"';
341 t += 2;
342 }
343 else
344 {
345 ++t;
346 assert (isspace (*t));
347 while (isspace (*t))
348 ++t;
349 if (*t == '\0')
350 break;
351 assert (*t == '"');
352 ++t;
353 }
354 }
355
356 *s = '\0';
357
662cc41e
ILT
358 *len = s - ret;
359
1d371d35
ILT
360 return ret;
361}
662cc41e
ILT
362
363/* Allocate a string of a given length. */
364
365static char *
366get_string (len)
367 int len;
368{
369 struct alloc_string *as;
370
371 as = (struct alloc_string *) xmalloc (sizeof *as);
372 as->s = xmalloc (len);
373
374 as->next = strings;
375 strings = as->next;
376
377 return as->s;
378}
379
380/* Discard all the strings we have allocated. The parser calls this
381 when it no longer needs them. */
382
383void
384rcparse_discard_strings ()
385{
386 struct alloc_string *as;
387
388 as = strings;
389 while (as != NULL)
390 {
391 struct alloc_string *n;
392
393 free (as->s);
394 n = as->next;
395 free (as);
396 as = n;
397 }
398
399 strings = NULL;
400}
401
402/* Enter rcdata mode. */
403
404void
405rcparse_rcdata ()
406{
407 rcdata_mode = 1;
408}
409
410/* Go back to normal mode from rcdata mode. */
411
412void
413rcparse_normal ()
414{
415 rcdata_mode = 0;
416}
This page took 0.07223 seconds and 4 git commands to generate.