OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [rclex.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 khays
/* rclex.c -- lexer for Windows rc files parser  */
2
 
3
/* Copyright 1997, 1998, 1999, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
 
6
   Written by Kai Tietz, Onevision.
7
 
8
   This file is part of GNU Binutils.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23
   02110-1301, USA.  */
24
 
25
 
26
/* This is a lexer used by the Windows rc file parser.  It basically
27
   just recognized a bunch of keywords.  */
28
 
29
#include "sysdep.h"
30
#include "bfd.h"
31
#include "bucomm.h"
32
#include "libiberty.h"
33
#include "safe-ctype.h"
34
#include "windres.h"
35
#include "rcparse.h"
36
 
37
#include <assert.h>
38
 
39
/* Whether we are in rcdata mode, in which we returns the lengths of
40
   strings.  */
41
 
42
static int rcdata_mode;
43
 
44
/* Whether we are supressing lines from cpp (including windows.h or
45
   headers from your C sources may bring in externs and typedefs).
46
   When active, we return IGNORED_TOKEN, which lets us ignore these
47
   outside of resource constructs.  Thus, it isn't required to protect
48
   all the non-preprocessor lines in your header files with #ifdef
49
   RC_INVOKED.  It also means your RC file can't include other RC
50
   files if they're named "*.h".  Sorry.  Name them *.rch or whatever.  */
51
 
52
static int suppress_cpp_data;
53
 
54
#define IGNORE_CPP(x) (suppress_cpp_data ? IGNORED_TOKEN : (x))
55
 
56
/* The first filename we detect in the cpp output.  We use this to
57
   tell included files from the original file.  */
58
 
59
static char *initial_fn;
60
 
61
/* List of allocated strings.  */
62
 
63
struct alloc_string
64
{
65
  struct alloc_string *next;
66
  char *s;
67
};
68
 
69
static struct alloc_string *strings;
70
 
71
struct rclex_keywords
72
{
73
  const char *name;
74
  int tok;
75
};
76
 
77
#define K(KEY)  { #KEY, KEY }
78
#define KRT(KEY)  { #KEY, RT_##KEY }
79
 
80
static const struct rclex_keywords keywds[] =
81
{
82
  K(ACCELERATORS), K(ALT), K(ANICURSOR), K(ANIICON), K(ASCII),
83
  K(AUTO3STATE), K(AUTOCHECKBOX), K(AUTORADIOBUTTON),
84
  K(BEDIT), { "BEGIN", BEG }, K(BITMAP), K(BLOCK), K(BUTTON),
85
  K(CAPTION), K(CHARACTERISTICS), K(CHECKBOX), K(CHECKED),
86
  K(CLASS), K(COMBOBOX), K(CONTROL), K(CTEXT), K(CURSOR),
87
  K(DEFPUSHBUTTON), K(DIALOG), K(DIALOGEX), K(DISCARDABLE),
88
  K(DLGINCLUDE), K(DLGINIT),
89
  K(EDITTEXT), K(END), K(EXSTYLE),
90
  K(FILEFLAGS), K(FILEFLAGSMASK), K(FILEOS), K(FILESUBTYPE),
91
  K(FILETYPE), K(FILEVERSION), K(FIXED), K(FONT), K(FONTDIR),
92
  K(GRAYED), KRT(GROUP_CURSOR), KRT(GROUP_ICON), K(GROUPBOX),
93
  K(HEDIT), K(HELP), K(HTML),
94
  K(ICON), K(IEDIT), K(IMPURE), K(INACTIVE),
95
  K(LANGUAGE), K(LISTBOX), K(LOADONCALL), K(LTEXT),
96
  K(MANIFEST), K(MENU), K(MENUBARBREAK), K(MENUBREAK),
97
  K(MENUEX), K(MENUITEM), K(MESSAGETABLE), K(MOVEABLE),
98
  K(NOINVERT), K(NOT),
99
  K(PLUGPLAY), K(POPUP), K(PRELOAD), K(PRODUCTVERSION),
100
  K(PURE), K(PUSHBOX), K(PUSHBUTTON),
101
  K(RADIOBUTTON), K(RCDATA), K(RTEXT),
102
  K(SCROLLBAR), K(SEPARATOR), K(SHIFT), K(STATE3),
103
  K(STRINGTABLE), K(STYLE),
104
  K(TOOLBAR),
105
  K(USERBUTTON),
106
  K(VALUE), { "VERSION", VERSIONK }, K(VERSIONINFO),
107
  K(VIRTKEY), K(VXD),
108
  { NULL, 0 },
109
};
110
 
111
/* External input stream from resrc */
112
extern FILE *cpp_pipe;
113
 
114
/* Lexical scanner helpers.  */
115
static int rclex_lastch = -1;
116
static size_t rclex_tok_max = 0;
117
static size_t rclex_tok_pos = 0;
118
static char *rclex_tok = NULL;
119
 
120
static int
121
rclex_translatekeyword (const char *key)
122
{
123
  if (key && ISUPPER (key[0]))
124
    {
125
      const struct rclex_keywords *kw = &keywds[0];
126
 
127
      do
128
        {
129
          if (! strcmp (kw->name, key))
130
            return kw->tok;
131
          ++kw;
132
        }
133
      while (kw->name != NULL);
134
    }
135
  return STRING;
136
}
137
 
138
/* Handle a C preprocessor line.  */
139
 
140
static void
141
cpp_line (void)
142
{
143
  const char *s = rclex_tok;
144
  int line;
145
  char *send, *fn;
146
  size_t len, mlen;
147
 
148
  ++s;
149
  while (ISSPACE (*s))
150
    ++s;
151
 
152
  /* Check for #pragma code_page ( DEFAULT | <nr>).  */
153
  len = strlen (s);
154
  mlen = strlen ("pragma");
155
  if (len > mlen && memcmp (s, "pragma", mlen) == 0 && ISSPACE (s[mlen]))
156
    {
157
      const char *end;
158
 
159
      s += mlen + 1;
160
      while (ISSPACE (*s))
161
        ++s;
162
      len = strlen (s);
163
      mlen = strlen ("code_page");
164
      if (len <= mlen || memcmp (s, "code_page", mlen) != 0)
165
        /* FIXME: We ought to issue a warning message about an unrecognised pragma.  */
166
        return;
167
      s += mlen;
168
      while (ISSPACE (*s))
169
        ++s;
170
      if (*s != '(')
171
        /* FIXME: We ought to issue an error message about a malformed pragma.  */
172
        return;
173
      ++s;
174
      while (ISSPACE (*s))
175
        ++s;
176
      if (*s == 0 || (end = strchr (s, ')')) == NULL)
177
        /* FIXME: We ought to issue an error message about a malformed pragma.  */
178
        return;
179
      len = (size_t) (end - s);
180
      fn = xmalloc (len + 1);
181
      if (len)
182
        memcpy (fn, s, len);
183
      fn[len] = 0;
184
      while (len > 0 && (fn[len - 1] > 0 && fn[len - 1] <= 0x20))
185
        fn[--len] = 0;
186
      if (! len || (len == strlen ("DEFAULT") && strcasecmp (fn, "DEFAULT") == 0))
187
        wind_current_codepage = wind_default_codepage;
188
      else if (len > 0)
189
        {
190
          rc_uint_type ncp;
191
 
192
          if (fn[0] == '0' && (fn[1] == 'x' || fn[1] == 'X'))
193
              ncp = (rc_uint_type) strtol (fn + 2, NULL, 16);
194
          else
195
              ncp = (rc_uint_type) strtol (fn, NULL, 10);
196
          if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
197
            fatal (_("invalid value specified for pragma code_page.\n"));
198
          wind_current_codepage = ncp;
199
        }
200
      free (fn);
201
      return;
202
    }
203
 
204
  line = strtol (s, &send, 0);
205
  if (*send != '\0' && ! ISSPACE (*send))
206
    return;
207
 
208
  /* Subtract 1 because we are about to count the newline.  */
209
  rc_lineno = line - 1;
210
 
211
  s = send;
212
  while (ISSPACE (*s))
213
    ++s;
214
 
215
  if (*s != '"')
216
    return;
217
 
218
  ++s;
219
  send = strchr (s, '"');
220
  if (send == NULL)
221
    return;
222
 
223
  fn = xmalloc (send - s + 1);
224
  strncpy (fn, s, send - s);
225
  fn[send - s] = '\0';
226
 
227
  free (rc_filename);
228
  rc_filename = fn;
229
 
230
  if (! initial_fn)
231
    {
232
      initial_fn = xmalloc (strlen (fn) + 1);
233
      strcpy (initial_fn, fn);
234
    }
235
 
236
  /* Allow the initial file, regardless of name.  Suppress all other
237
     files if they end in ".h" (this allows included "*.rc").  */
238
  if (strcmp (initial_fn, fn) == 0
239
      || strcmp (fn + strlen (fn) - 2, ".h") != 0)
240
    suppress_cpp_data = 0;
241
  else
242
    suppress_cpp_data = 1;
243
}
244
 
245
/* Allocate a string of a given length.  */
246
 
247
static char *
248
get_string (int len)
249
{
250
  struct alloc_string *as;
251
 
252
  as = xmalloc (sizeof *as);
253
  as->s = xmalloc (len);
254
 
255
  as->next = strings;
256
  strings = as;
257
 
258
  return as->s;
259
}
260
 
261
/* Handle a quoted string.  The quotes are stripped.  A pair of quotes
262
   in a string are turned into a single quote.  Adjacent strings are
263
   merged separated by whitespace are merged, as in C.  */
264
 
265
static char *
266
handle_quotes (rc_uint_type *len)
267
{
268
  const char *input = rclex_tok;
269
  char *ret, *s;
270
  const char *t;
271
  int ch;
272
  int num_xdigits;
273
 
274
  ret = get_string (strlen (input) + 1);
275
 
276
  s = ret;
277
  t = input;
278
  if (*t == '"')
279
    ++t;
280
  while (*t != '\0')
281
    {
282
      if (*t == '\\')
283
        {
284
          ++t;
285
          switch (*t)
286
            {
287
            case '\0':
288
              rcparse_warning ("backslash at end of string");
289
              break;
290
 
291
            case '\"':
292
              rcparse_warning ("use \"\" to put \" in a string");
293
              *s++ = '"';
294
              ++t;
295
              break;
296
 
297
            case 'a':
298
              *s++ = ESCAPE_B; /* Strange, but true...  */
299
              ++t;
300
              break;
301
 
302
            case 'b':
303
              *s++ = ESCAPE_B;
304
              ++t;
305
              break;
306
 
307
            case 'f':
308
              *s++ = ESCAPE_F;
309
              ++t;
310
              break;
311
 
312
            case 'n':
313
              *s++ = ESCAPE_N;
314
              ++t;
315
              break;
316
 
317
            case 'r':
318
              *s++ = ESCAPE_R;
319
              ++t;
320
              break;
321
 
322
            case 't':
323
              *s++ = ESCAPE_T;
324
              ++t;
325
              break;
326
 
327
            case 'v':
328
              *s++ = ESCAPE_V;
329
              ++t;
330
              break;
331
 
332
            case '\\':
333
              *s++ = *t++;
334
              break;
335
 
336
            case '0': case '1': case '2': case '3':
337
            case '4': case '5': case '6': case '7':
338
              ch = *t - '0';
339
              ++t;
340
              if (*t >= '0' && *t <= '7')
341
                {
342
                  ch = (ch << 3) | (*t - '0');
343
                  ++t;
344
                  if (*t >= '0' && *t <= '7')
345
                    {
346
                      ch = (ch << 3) | (*t - '0');
347
                      ++t;
348
                    }
349
                }
350
              *s++ = ch;
351
              break;
352
 
353
            case 'x': case 'X':
354
              ++t;
355
              ch = 0;
356
              /* We only handle single byte chars here.  Make sure
357
                 we finish an escape sequence like "/xB0ABC" after
358
                 the first two digits.  */
359
              num_xdigits = 2;
360
              while (num_xdigits--)
361
                {
362
                  if (*t >= '0' && *t <= '9')
363
                    ch = (ch << 4) | (*t - '0');
364
                  else if (*t >= 'a' && *t <= 'f')
365
                    ch = (ch << 4) | (*t - 'a' + 10);
366
                  else if (*t >= 'A' && *t <= 'F')
367
                    ch = (ch << 4) | (*t - 'A' + 10);
368
                  else
369
                    break;
370
                  ++t;
371
                }
372
              *s++ = ch;
373
              break;
374
 
375
            default:
376
              rcparse_warning ("unrecognized escape sequence");
377
              *s++ = '\\';
378
              *s++ = *t++;
379
              break;
380
            }
381
        }
382
      else if (*t != '"')
383
        *s++ = *t++;
384
      else if (t[1] == '\0')
385
        break;
386
      else if (t[1] == '"')
387
        {
388
          *s++ = '"';
389
          t += 2;
390
        }
391
      else
392
        {
393
          ++t;
394
          if (! ISSPACE (*t))
395
            rcparse_warning ("unexpected character after '\"'");
396
          while (ISSPACE (*t))
397
            {
398
              if ((*t) == '\n')
399
                ++rc_lineno;
400
              ++t;
401
            }
402
          if (*t == '\0')
403
            break;
404
          assert (*t == '"');
405
          ++t;
406
        }
407
    }
408
 
409
  *s = '\0';
410
 
411
  *len = s - ret;
412
 
413
  return ret;
414
}
415
 
416
/* Allocate a unicode string of a given length.  */
417
 
418
static unichar *
419
get_unistring (int len)
420
{
421
  return (unichar *) get_string (len * sizeof (unichar));
422
}
423
 
424
/* Handle a quoted unicode string.  The quotes are stripped.  A pair of quotes
425
   in a string are turned into a single quote.  Adjacent strings are
426
   merged separated by whitespace are merged, as in C.  */
427
 
428
static unichar *
429
handle_uniquotes (rc_uint_type *len)
430
{
431
  const char *input = rclex_tok;
432
  unichar *ret, *s;
433
  const char *t;
434
  int ch;
435
  int num_xdigits;
436
 
437
  ret = get_unistring (strlen (input) + 1);
438
 
439
  s = ret;
440
  t = input;
441
  if ((*t == 'L' || *t == 'l') && t[1] == '"')
442
    t += 2;
443
  else if (*t == '"')
444
    ++t;
445
  while (*t != '\0')
446
    {
447
      if (*t == '\\')
448
        {
449
          ++t;
450
          switch (*t)
451
            {
452
            case '\0':
453
              rcparse_warning ("backslash at end of string");
454
              break;
455
 
456
            case '\"':
457
              rcparse_warning ("use \"\" to put \" in a string");
458
              break;
459
 
460
            case 'a':
461
              *s++ = ESCAPE_B; /* Strange, but true...  */
462
              ++t;
463
              break;
464
 
465
            case 'b':
466
              *s++ = ESCAPE_B;
467
              ++t;
468
              break;
469
 
470
            case 'f':
471
              *s++ = ESCAPE_F;
472
              ++t;
473
              break;
474
 
475
            case 'n':
476
              *s++ = ESCAPE_N;
477
              ++t;
478
              break;
479
 
480
            case 'r':
481
              *s++ = ESCAPE_R;
482
              ++t;
483
              break;
484
 
485
            case 't':
486
              *s++ = ESCAPE_T;
487
              ++t;
488
              break;
489
 
490
            case 'v':
491
              *s++ = ESCAPE_V;
492
              ++t;
493
              break;
494
 
495
            case '\\':
496
              *s++ = (unichar) *t++;
497
              break;
498
 
499
            case '0': case '1': case '2': case '3':
500
            case '4': case '5': case '6': case '7':
501
              ch = *t - '0';
502
              ++t;
503
              if (*t >= '0' && *t <= '7')
504
                {
505
                  ch = (ch << 3) | (*t - '0');
506
                  ++t;
507
                  if (*t >= '0' && *t <= '7')
508
                    {
509
                      ch = (ch << 3) | (*t - '0');
510
                      ++t;
511
                    }
512
                }
513
              *s++ = (unichar) ch;
514
              break;
515
 
516
            case 'x': case 'X':
517
              ++t;
518
              ch = 0;
519
              /* We only handle two byte chars here.  Make sure
520
                 we finish an escape sequence like "/xB0ABC" after
521
                 the first two digits.  */
522
              num_xdigits = 4;
523
              while (num_xdigits--)
524
                {
525
                  if (*t >= '0' && *t <= '9')
526
                    ch = (ch << 4) | (*t - '0');
527
                  else if (*t >= 'a' && *t <= 'f')
528
                    ch = (ch << 4) | (*t - 'a' + 10);
529
                  else if (*t >= 'A' && *t <= 'F')
530
                    ch = (ch << 4) | (*t - 'A' + 10);
531
                  else
532
                    break;
533
                  ++t;
534
                }
535
              *s++ = (unichar) ch;
536
              break;
537
 
538
            default:
539
              rcparse_warning ("unrecognized escape sequence");
540
              *s++ = '\\';
541
              *s++ = (unichar) *t++;
542
              break;
543
            }
544
        }
545
      else if (*t != '"')
546
        *s++ = (unichar) *t++;
547
      else if (t[1] == '\0')
548
        break;
549
      else if (t[1] == '"')
550
        {
551
          *s++ = '"';
552
          t += 2;
553
        }
554
      else
555
        {
556
          ++t;
557
          assert (ISSPACE (*t));
558
          while (ISSPACE (*t))
559
            {
560
              if ((*t) == '\n')
561
                ++rc_lineno;
562
              ++t;
563
            }
564
          if (*t == '\0')
565
            break;
566
          assert (*t == '"');
567
          ++t;
568
        }
569
    }
570
 
571
  *s = '\0';
572
 
573
  *len = s - ret;
574
 
575
  return ret;
576
}
577
 
578
/* Discard all the strings we have allocated.  The parser calls this
579
   when it no longer needs them.  */
580
 
581
void
582
rcparse_discard_strings (void)
583
{
584
  struct alloc_string *as;
585
 
586
  as = strings;
587
  while (as != NULL)
588
    {
589
      struct alloc_string *n;
590
 
591
      free (as->s);
592
      n = as->next;
593
      free (as);
594
      as = n;
595
    }
596
 
597
  strings = NULL;
598
}
599
 
600
/* Enter rcdata mode.  */
601
void
602
rcparse_rcdata (void)
603
{
604
  rcdata_mode = 1;
605
}
606
 
607
/* Go back to normal mode from rcdata mode.  */
608
void
609
rcparse_normal (void)
610
{
611
  rcdata_mode = 0;
612
}
613
 
614
static void
615
rclex_tok_add_char (int ch)
616
{
617
  if (! rclex_tok || rclex_tok_max <= rclex_tok_pos)
618
    {
619
      char *h = xmalloc (rclex_tok_max + 9);
620
 
621
      if (! h)
622
        abort ();
623
      if (rclex_tok)
624
        {
625
          memcpy (h, rclex_tok, rclex_tok_pos + 1);
626
          free (rclex_tok);
627
        }
628
      else
629
        rclex_tok_pos = 0;
630
      rclex_tok_max += 8;
631
      rclex_tok = h;
632
    }
633
  if (ch != -1)
634
    rclex_tok[rclex_tok_pos++] = (char) ch;
635
  rclex_tok[rclex_tok_pos] = 0;
636
}
637
 
638
static int
639
rclex_readch (void)
640
{
641
  int r = -1;
642
 
643
  if ((r = rclex_lastch) != -1)
644
    rclex_lastch = -1;
645
  else
646
    {
647
      char ch;
648
      do
649
        {
650
          if (! cpp_pipe || feof (cpp_pipe)
651
              || fread (&ch, 1, 1,cpp_pipe) != 1)
652
            break;
653
          r = ((int) ch) & 0xff;
654
        }
655
      while (r == 0 || r == '\r');
656
  }
657
  rclex_tok_add_char (r);
658
  return r;
659
}
660
 
661
static int
662
rclex_peekch (void)
663
{
664
  int r;
665
 
666
  if ((r = rclex_lastch) == -1)
667
    {
668
      if ((r = rclex_readch ()) != -1)
669
        {
670
          rclex_lastch = r;
671
          if (rclex_tok_pos > 0)
672
            rclex_tok[--rclex_tok_pos] = 0;
673
        }
674
    }
675
  return r;
676
}
677
 
678
static void
679
rclex_string (void)
680
{
681
  int c;
682
 
683
  while ((c = rclex_peekch ()) != -1)
684
    {
685
      if (c == '\n')
686
        break;
687
      if (c == '\\')
688
        {
689
          rclex_readch ();
690
          if ((c = rclex_peekch ()) == -1 || c == '\n')
691
            break;
692
          rclex_readch ();
693
        }
694
      else if (rclex_readch () == '"')
695
        {
696
          /* PR 6714
697
             Skip any whitespace after the end of the double quotes.  */
698
          do
699
            {
700
              c = rclex_peekch ();
701
              if (ISSPACE (c))
702
                rclex_readch ();
703
              else
704
                c = -1;
705
            }
706
          while (c != -1);
707
 
708
          if (rclex_peekch () == '"')
709
            rclex_readch ();
710
          else
711
            break;
712
        }
713
    }
714
}
715
 
716
static rc_uint_type
717
read_digit (int ch)
718
{
719
  rc_uint_type base = 10;
720
  rc_uint_type ret, val;
721
  int warned = 0;
722
 
723
  ret = 0;
724
  if (ch == '0')
725
    {
726
      base = 8;
727
      switch (rclex_peekch ())
728
        {
729
        case 'o': case 'O':
730
          rclex_readch ();
731
          base = 8;
732
          break;
733
 
734
        case 'x': case 'X':
735
          rclex_readch ();
736
          base = 16;
737
          break;
738
        }
739
    }
740
  else
741
    ret = (rc_uint_type) (ch - '0');
742
  while ((ch = rclex_peekch ()) != -1)
743
    {
744
      if (ISDIGIT (ch))
745
        val = (rc_uint_type) (ch - '0');
746
      else if (ch >= 'a' && ch <= 'f')
747
        val = (rc_uint_type) ((ch - 'a') + 10);
748
      else if (ch >= 'A' && ch <= 'F')
749
        val = (rc_uint_type) ((ch - 'A') + 10);
750
      else
751
        break;
752
      rclex_readch ();
753
      if (! warned && val >= base)
754
        {
755
          warned = 1;
756
          rcparse_warning ("digit exceeds base");
757
        }
758
      ret *= base;
759
      ret += val;
760
    }
761
  return ret;
762
}
763
 
764
/* yyparser entry method.  */
765
 
766
int
767
yylex (void)
768
{
769
  char *s;
770
  unichar *us;
771
  rc_uint_type length;
772
  int ch;
773
 
774
  /* Make sure that rclex_tok is initialized.  */
775
  if (! rclex_tok)
776
    rclex_tok_add_char (-1);
777
 
778
  do
779
    {
780
      do
781
        {
782
          /* Clear token.  */
783
          rclex_tok_pos = 0;
784
          rclex_tok[0] = 0;
785
 
786
          if ((ch = rclex_readch ()) == -1)
787
            return -1;
788
          if (ch == '\n')
789
            ++rc_lineno;
790
        }
791
      while (ch <= 0x20);
792
 
793
      switch (ch)
794
        {
795
        case '#':
796
          while ((ch = rclex_peekch ()) != -1 && ch != '\n')
797
            rclex_readch ();
798
          cpp_line ();
799
          ch = IGNORED_TOKEN;
800
          break;
801
 
802
        case '{':
803
          ch = IGNORE_CPP (BEG);
804
          break;
805
 
806
        case '}':
807
          ch = IGNORE_CPP (END);
808
          break;
809
 
810
        case '0': case '1': case '2': case '3': case '4':
811
        case '5': case '6': case '7': case '8': case '9':
812
          yylval.i.val = read_digit (ch);
813
          yylval.i.dword = 0;
814
          switch (rclex_peekch ())
815
            {
816
            case 'l': case 'L':
817
              rclex_readch ();
818
              yylval.i.dword = 1;
819
              break;
820
            }
821
          ch = IGNORE_CPP (NUMBER);
822
          break;
823
        case '"':
824
          rclex_string ();
825
          ch = IGNORE_CPP ((! rcdata_mode ? QUOTEDSTRING : SIZEDSTRING));
826
          if (ch == IGNORED_TOKEN)
827
            break;
828
          s = handle_quotes (&length);
829
          if (! rcdata_mode)
830
            yylval.s = s;
831
          else
832
            {
833
              yylval.ss.length = length;
834
              yylval.ss.s = s;
835
          }
836
          break;
837
        case 'L': case 'l':
838
          if (rclex_peekch () == '"')
839
            {
840
              rclex_readch ();
841
              rclex_string ();
842
              ch = IGNORE_CPP ((! rcdata_mode ? QUOTEDUNISTRING : SIZEDUNISTRING));
843
              if (ch == IGNORED_TOKEN)
844
                break;
845
              us = handle_uniquotes (&length);
846
              if (! rcdata_mode)
847
                yylval.uni = us;
848
              else
849
                {
850
                  yylval.suni.length = length;
851
                  yylval.suni.s = us;
852
              }
853
              break;
854
            }
855
          /* Fall through.  */
856
        default:
857
          if (ISIDST (ch) || ch=='$')
858
            {
859
              while ((ch = rclex_peekch ()) != -1
860
                     && (ISIDNUM (ch) || ch == '$' || ch == '.'
861
                         || ch == ':' || ch == '\\' || ch == '/'
862
                         || ch == '_' || ch == '-')
863
                    )
864
                rclex_readch ();
865
              ch = IGNORE_CPP (rclex_translatekeyword (rclex_tok));
866
              if (ch == STRING)
867
                {
868
                  s = get_string (strlen (rclex_tok) + 1);
869
                  strcpy (s, rclex_tok);
870
                  yylval.s = s;
871
                }
872
              else if (ch == BLOCK)
873
                {
874
                  const char *hs = NULL;
875
 
876
                  switch (yylex ())
877
                  {
878
                  case STRING:
879
                  case QUOTEDSTRING:
880
                    hs = yylval.s;
881
                    break;
882
                  case SIZEDSTRING:
883
                    hs = yylval.s = yylval.ss.s;
884
                    break;
885
                  }
886
                  if (! hs)
887
                    {
888
                      rcparse_warning ("BLOCK expects a string as argument.");
889
                      ch = IGNORED_TOKEN;
890
                    }
891
                  else if (! strcmp (hs, "StringFileInfo"))
892
                    ch = BLOCKSTRINGFILEINFO;
893
                  else if (! strcmp (hs, "VarFileInfo"))
894
                    ch = BLOCKVARFILEINFO;
895
                }
896
              break;
897
            }
898
          ch = IGNORE_CPP (ch);
899
          break;
900
        }
901
    }
902
  while (ch == IGNORED_TOKEN);
903
 
904
  return ch;
905
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.