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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [binutils/] [rcparse.y] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
%{ /* rcparse.y -- parser for Windows rc files
2
   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008
3
   Free Software Foundation, Inc.
4
   Written by Ian Lance Taylor, Cygnus Support.
5
   Extended by Kai Tietz, Onevision.
6
 
7
   This file is part of GNU Binutils.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22
   02110-1301, USA.  */
23
 
24
 
25
/* This is a parser for Windows rc files.  It is based on the parser
26
   by Gunther Ebert .  */
27
 
28
#include "sysdep.h"
29
#include "bfd.h"
30
#include "bucomm.h"
31
#include "libiberty.h"
32
#include "windres.h"
33
#include "safe-ctype.h"
34
 
35
/* The current language.  */
36
 
37
static unsigned short language;
38
 
39
/* The resource information during a sub statement.  */
40
 
41
static rc_res_res_info sub_res_info;
42
 
43
/* Dialog information.  This is built by the nonterminals styles and
44
   controls.  */
45
 
46
static rc_dialog dialog;
47
 
48
/* This is used when building a style.  It is modified by the
49
   nonterminal styleexpr.  */
50
 
51
static unsigned long style;
52
 
53
/* These are used when building a control.  They are set before using
54
   control_params.  */
55
 
56
static rc_uint_type base_style;
57
static rc_uint_type default_style;
58
static rc_res_id class;
59
static rc_res_id res_text_field;
60
static unichar null_unichar;
61
 
62
/* This is used for COMBOBOX, LISTBOX and EDITTEXT which
63
   do not allow resource 'text' field in control definition. */
64
static const rc_res_id res_null_text = { 1, {{0, &null_unichar}}};
65
 
66
%}
67
 
68
%union
69
{
70
  rc_accelerator acc;
71
  rc_accelerator *pacc;
72
  rc_dialog_control *dialog_control;
73
  rc_menuitem *menuitem;
74
  struct
75
  {
76
    rc_rcdata_item *first;
77
    rc_rcdata_item *last;
78
  } rcdata;
79
  rc_rcdata_item *rcdata_item;
80
  rc_fixed_versioninfo *fixver;
81
  rc_ver_info *verinfo;
82
  rc_ver_stringinfo *verstring;
83
  rc_ver_varinfo *vervar;
84
  rc_toolbar_item *toobar_item;
85
  rc_res_id id;
86
  rc_res_res_info res_info;
87
  struct
88
  {
89
    rc_uint_type on;
90
    rc_uint_type off;
91
  } memflags;
92
  struct
93
  {
94
    rc_uint_type val;
95
    /* Nonzero if this number was explicitly specified as long.  */
96
    int dword;
97
  } i;
98
  rc_uint_type il;
99
  rc_uint_type is;
100
  const char *s;
101
  struct
102
  {
103
    rc_uint_type length;
104
    const char *s;
105
  } ss;
106
  unichar *uni;
107
  struct
108
  {
109
    rc_uint_type length;
110
    const unichar *s;
111
  } suni;
112
};
113
 
114
%token BEG END
115
%token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
116
%token BITMAP
117
%token CURSOR
118
%token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
119
%token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
120
%token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
121
%token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
122
%token BEDIT HEDIT IEDIT
123
%token FONT
124
%token ICON
125
%token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
126
%token LANGUAGE CHARACTERISTICS VERSIONK
127
%token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
128
%token MENUBARBREAK MENUBREAK
129
%token MESSAGETABLE
130
%token RCDATA
131
%token STRINGTABLE
132
%token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
133
%token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
134
%token VALUE
135
%token  BLOCK
136
%token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
137
%token NOT
138
%token  QUOTEDUNISTRING
139
%token  QUOTEDSTRING STRING
140
%token  NUMBER
141
%token  SIZEDUNISTRING
142
%token  SIZEDSTRING
143
%token IGNORED_TOKEN
144
 
145
%type  acc_entries
146
%type  acc_entry acc_event
147
%type  control control_params
148
%type  menuitems menuitem menuexitems menuexitem
149
%type  optrcdata_data optrcdata_data_int rcdata_data
150
%type  opt_control_data
151
%type  fixedverinfo
152
%type  verblocks
153
%type  vervals
154
%type  vertrans
155
%type  toolbar_data
156
%type  suboptions memflags_move_discard memflags_move
157
%type  memflag
158
%type  id rcdata_id optresidc resref resid cresid
159
%type  exstyle parennumber
160
%type  numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
161
%type  acc_options acc_option menuitem_flags menuitem_flag
162
%type  file_name
163
%type  res_unicode_string resname res_unicode_string_concat
164
%type  sizedstring
165
%type  sizedunistring
166
%type  sizednumexpr sizedposnumexpr
167
 
168
%left '|'
169
%left '^'
170
%left '&'
171
%left '+' '-'
172
%left '*' '/' '%'
173
%right '~' NEG
174
 
175
%%
176
 
177
input:
178
          /* empty */
179
        | input accelerator
180
        | input bitmap
181
        | input cursor
182
        | input dialog
183
        | input font
184
        | input icon
185
        | input language
186
        | input menu
187
        | input menuex
188
        | input messagetable
189
        | input stringtable
190
        | input toolbar
191
        | input user
192
        | input versioninfo
193
        | input IGNORED_TOKEN
194
        ;
195
 
196
/* Accelerator resources.  */
197
 
198
accelerator:
199
          id ACCELERATORS suboptions BEG acc_entries END
200
          {
201
            define_accelerator ($1, &$3, $5);
202
            if (yychar != YYEMPTY)
203
              YYERROR;
204
            rcparse_discard_strings ();
205
          }
206
        ;
207
 
208
acc_entries:
209
          /* empty */
210
          {
211
            $$ = NULL;
212
          }
213
        | acc_entries acc_entry
214
          {
215
            rc_accelerator *a;
216
 
217
            a = (rc_accelerator *) res_alloc (sizeof *a);
218
            *a = $2;
219
            if ($1 == NULL)
220
              $$ = a;
221
            else
222
              {
223
                rc_accelerator **pp;
224
 
225
                for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
226
                  ;
227
                *pp = a;
228
                $$ = $1;
229
              }
230
          }
231
        ;
232
 
233
acc_entry:
234
          acc_event cposnumexpr
235
          {
236
            $$ = $1;
237
            $$.id = $2;
238
          }
239
        | acc_event cposnumexpr ',' acc_options
240
          {
241
            $$ = $1;
242
            $$.id = $2;
243
            $$.flags |= $4;
244
            if (($$.flags & ACC_VIRTKEY) == 0
245
                && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
246
              rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
247
          }
248
        ;
249
 
250
acc_event:
251
          QUOTEDSTRING
252
          {
253
            const char *s = $1;
254
            char ch;
255
 
256
            $$.next = NULL;
257
            $$.id = 0;
258
            ch = *s;
259
            if (ch != '^')
260
              $$.flags = 0;
261
            else
262
              {
263
                $$.flags = ACC_CONTROL | ACC_VIRTKEY;
264
                ++s;
265
                ch = TOUPPER (s[0]);
266
              }
267
            $$.key = ch;
268
            if (s[1] != '\0')
269
              rcparse_warning (_("accelerator should only be one character"));
270
          }
271
        | posnumexpr
272
          {
273
            $$.next = NULL;
274
            $$.flags = 0;
275
            $$.id = 0;
276
            $$.key = $1;
277
          }
278
        ;
279
 
280
acc_options:
281
          acc_option
282
          {
283
            $$ = $1;
284
          }
285
        | acc_options ',' acc_option
286
          {
287
            $$ = $1 | $3;
288
          }
289
        /* I've had one report that the comma is optional.  */
290
        | acc_options acc_option
291
          {
292
            $$ = $1 | $2;
293
          }
294
        ;
295
 
296
acc_option:
297
          VIRTKEY
298
          {
299
            $$ = ACC_VIRTKEY;
300
          }
301
        | ASCII
302
          {
303
            /* This is just the absence of VIRTKEY.  */
304
            $$ = 0;
305
          }
306
        | NOINVERT
307
          {
308
            $$ = ACC_NOINVERT;
309
          }
310
        | SHIFT
311
          {
312
            $$ = ACC_SHIFT;
313
          }
314
        | CONTROL
315
          {
316
            $$ = ACC_CONTROL;
317
          }
318
        | ALT
319
          {
320
            $$ = ACC_ALT;
321
          }
322
        ;
323
 
324
/* Bitmap resources.  */
325
 
326
bitmap:
327
          id BITMAP memflags_move file_name
328
          {
329
            define_bitmap ($1, &$3, $4);
330
            if (yychar != YYEMPTY)
331
              YYERROR;
332
            rcparse_discard_strings ();
333
          }
334
        ;
335
 
336
/* Cursor resources.  */
337
 
338
cursor:
339
          id CURSOR memflags_move_discard file_name
340
          {
341
            define_cursor ($1, &$3, $4);
342
            if (yychar != YYEMPTY)
343
              YYERROR;
344
            rcparse_discard_strings ();
345
          }
346
        ;
347
 
348
/* Dialog resources.  */
349
 
350
dialog:
351
          id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
352
            cnumexpr
353
            {
354
              memset (&dialog, 0, sizeof dialog);
355
              dialog.x = $5;
356
              dialog.y = $6;
357
              dialog.width = $7;
358
              dialog.height = $8;
359
              dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
360
              dialog.exstyle = $4;
361
              dialog.menu.named = 1;
362
              dialog.class.named = 1;
363
              dialog.font = NULL;
364
              dialog.ex = NULL;
365
              dialog.controls = NULL;
366
              sub_res_info = $3;
367
              style = 0;
368
            }
369
            styles BEG controls END
370
          {
371
            define_dialog ($1, &sub_res_info, &dialog);
372
            if (yychar != YYEMPTY)
373
              YYERROR;
374
            rcparse_discard_strings ();
375
          }
376
        | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
377
            cnumexpr
378
            {
379
              memset (&dialog, 0, sizeof dialog);
380
              dialog.x = $5;
381
              dialog.y = $6;
382
              dialog.width = $7;
383
              dialog.height = $8;
384
              dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
385
              dialog.exstyle = $4;
386
              dialog.menu.named = 1;
387
              dialog.class.named = 1;
388
              dialog.font = NULL;
389
              dialog.ex = ((rc_dialog_ex *)
390
                           res_alloc (sizeof (rc_dialog_ex)));
391
              memset (dialog.ex, 0, sizeof (rc_dialog_ex));
392
              dialog.controls = NULL;
393
              sub_res_info = $3;
394
              style = 0;
395
            }
396
            styles BEG controls END
397
          {
398
            define_dialog ($1, &sub_res_info, &dialog);
399
            if (yychar != YYEMPTY)
400
              YYERROR;
401
            rcparse_discard_strings ();
402
          }
403
        | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
404
            cnumexpr cnumexpr
405
            {
406
              memset (&dialog, 0, sizeof dialog);
407
              dialog.x = $5;
408
              dialog.y = $6;
409
              dialog.width = $7;
410
              dialog.height = $8;
411
              dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
412
              dialog.exstyle = $4;
413
              dialog.menu.named = 1;
414
              dialog.class.named = 1;
415
              dialog.font = NULL;
416
              dialog.ex = ((rc_dialog_ex *)
417
                           res_alloc (sizeof (rc_dialog_ex)));
418
              memset (dialog.ex, 0, sizeof (rc_dialog_ex));
419
              dialog.ex->help = $9;
420
              dialog.controls = NULL;
421
              sub_res_info = $3;
422
              style = 0;
423
            }
424
            styles BEG controls END
425
          {
426
            define_dialog ($1, &sub_res_info, &dialog);
427
            if (yychar != YYEMPTY)
428
              YYERROR;
429
            rcparse_discard_strings ();
430
          }
431
        ;
432
 
433
exstyle:
434
          /* empty */
435
          {
436
            $$ = 0;
437
          }
438
        | EXSTYLE '=' numexpr
439
          {
440
            $$ = $3;
441
          }
442
        ;
443
 
444
styles:
445
          /* empty */
446
        | styles CAPTION res_unicode_string_concat
447
          {
448
            dialog.style |= WS_CAPTION;
449
            style |= WS_CAPTION;
450
            dialog.caption = $3;
451
          }
452
        | styles CLASS id
453
          {
454
            dialog.class = $3;
455
          }
456
        | styles STYLE
457
            styleexpr
458
          {
459
            dialog.style = style;
460
          }
461
        | styles EXSTYLE numexpr
462
          {
463
            dialog.exstyle = $3;
464
          }
465
        | styles CLASS res_unicode_string_concat
466
          {
467
            res_unistring_to_id (& dialog.class, $3);
468
          }
469
        | styles FONT numexpr ',' res_unicode_string_concat
470
          {
471
            dialog.style |= DS_SETFONT;
472
            style |= DS_SETFONT;
473
            dialog.pointsize = $3;
474
            dialog.font = $5;
475
            if (dialog.ex != NULL)
476
              {
477
                dialog.ex->weight = 0;
478
                dialog.ex->italic = 0;
479
                dialog.ex->charset = 1;
480
              }
481
          }
482
        | styles FONT numexpr ',' res_unicode_string_concat cnumexpr
483
          {
484
            dialog.style |= DS_SETFONT;
485
            style |= DS_SETFONT;
486
            dialog.pointsize = $3;
487
            dialog.font = $5;
488
            if (dialog.ex == NULL)
489
              rcparse_warning (_("extended FONT requires DIALOGEX"));
490
            else
491
              {
492
                dialog.ex->weight = $6;
493
                dialog.ex->italic = 0;
494
                dialog.ex->charset = 1;
495
              }
496
          }
497
        | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
498
          {
499
            dialog.style |= DS_SETFONT;
500
            style |= DS_SETFONT;
501
            dialog.pointsize = $3;
502
            dialog.font = $5;
503
            if (dialog.ex == NULL)
504
              rcparse_warning (_("extended FONT requires DIALOGEX"));
505
            else
506
              {
507
                dialog.ex->weight = $6;
508
                dialog.ex->italic = $7;
509
                dialog.ex->charset = 1;
510
              }
511
          }
512
        | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
513
          {
514
            dialog.style |= DS_SETFONT;
515
            style |= DS_SETFONT;
516
            dialog.pointsize = $3;
517
            dialog.font = $5;
518
            if (dialog.ex == NULL)
519
              rcparse_warning (_("extended FONT requires DIALOGEX"));
520
            else
521
              {
522
                dialog.ex->weight = $6;
523
                dialog.ex->italic = $7;
524
                dialog.ex->charset = $8;
525
              }
526
          }
527
        | styles MENU id
528
          {
529
            dialog.menu = $3;
530
          }
531
        | styles CHARACTERISTICS numexpr
532
          {
533
            sub_res_info.characteristics = $3;
534
          }
535
        | styles LANGUAGE numexpr cnumexpr
536
          {
537
            sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
538
          }
539
        | styles VERSIONK numexpr
540
          {
541
            sub_res_info.version = $3;
542
          }
543
        ;
544
 
545
controls:
546
          /* empty */
547
        | controls control
548
          {
549
            rc_dialog_control **pp;
550
 
551
            for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
552
              ;
553
            *pp = $2;
554
          }
555
        ;
556
 
557
control:
558
          AUTO3STATE optresidc
559
            {
560
              default_style = BS_AUTO3STATE | WS_TABSTOP;
561
              base_style = BS_AUTO3STATE;
562
              class.named = 0;
563
              class.u.id = CTL_BUTTON;
564
              res_text_field = $2;
565
            }
566
            control_params
567
          {
568
            $$ = $4;
569
          }
570
        | AUTOCHECKBOX optresidc
571
            {
572
              default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
573
              base_style = BS_AUTOCHECKBOX;
574
              class.named = 0;
575
              class.u.id = CTL_BUTTON;
576
              res_text_field = $2;
577
            }
578
            control_params
579
          {
580
            $$ = $4;
581
          }
582
        | AUTORADIOBUTTON optresidc
583
            {
584
              default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
585
              base_style = BS_AUTORADIOBUTTON;
586
              class.named = 0;
587
              class.u.id = CTL_BUTTON;
588
              res_text_field = $2;
589
            }
590
            control_params
591
          {
592
            $$ = $4;
593
          }
594
        | BEDIT optresidc
595
            {
596
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
597
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
598
              class.named = 0;
599
              class.u.id = CTL_EDIT;
600
              res_text_field = $2;
601
            }
602
            control_params
603
          {
604
            $$ = $4;
605
            if (dialog.ex == NULL)
606
              rcparse_warning (_("BEDIT requires DIALOGEX"));
607
            res_string_to_id (&$$->class, "BEDIT");
608
          }
609
        | CHECKBOX optresidc
610
            {
611
              default_style = BS_CHECKBOX | WS_TABSTOP;
612
              base_style = BS_CHECKBOX | WS_TABSTOP;
613
              class.named = 0;
614
              class.u.id = CTL_BUTTON;
615
              res_text_field = $2;
616
            }
617
            control_params
618
          {
619
            $$ = $4;
620
          }
621
        | COMBOBOX
622
            {
623
              /* This is as per MSDN documentation.  With some (???)
624
                 versions of MS rc.exe their is no default style.  */
625
              default_style = CBS_SIMPLE | WS_TABSTOP;
626
              base_style = 0;
627
              class.named = 0;
628
              class.u.id = CTL_COMBOBOX;
629
              res_text_field = res_null_text;
630
            }
631
            control_params
632
          {
633
            $$ = $3;
634
          }
635
        | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
636
            cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
637
          {
638
            $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
639
            if ($11 != NULL)
640
              {
641
                if (dialog.ex == NULL)
642
                  rcparse_warning (_("control data requires DIALOGEX"));
643
                $$->data = $11;
644
              }
645
          }
646
        | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
647
            cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
648
          {
649
            $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
650
            if (dialog.ex == NULL)
651
              rcparse_warning (_("help ID requires DIALOGEX"));
652
            $$->help = $11;
653
            $$->data = $12;
654
          }
655
        | CTEXT optresidc
656
            {
657
              default_style = SS_CENTER | WS_GROUP;
658
              base_style = SS_CENTER;
659
              class.named = 0;
660
              class.u.id = CTL_STATIC;
661
              res_text_field = $2;
662
            }
663
            control_params
664
          {
665
            $$ = $4;
666
          }
667
        | DEFPUSHBUTTON optresidc
668
            {
669
              default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
670
              base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
671
              class.named = 0;
672
              class.u.id = CTL_BUTTON;
673
              res_text_field = $2;
674
            }
675
            control_params
676
          {
677
            $$ = $4;
678
          }
679
        | EDITTEXT
680
            {
681
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
682
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
683
              class.named = 0;
684
              class.u.id = CTL_EDIT;
685
              res_text_field = res_null_text;
686
            }
687
            control_params
688
          {
689
            $$ = $3;
690
          }
691
        | GROUPBOX optresidc
692
            {
693
              default_style = BS_GROUPBOX;
694
              base_style = BS_GROUPBOX;
695
              class.named = 0;
696
              class.u.id = CTL_BUTTON;
697
              res_text_field = $2;
698
            }
699
            control_params
700
          {
701
            $$ = $4;
702
          }
703
        | HEDIT optresidc
704
            {
705
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
706
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
707
              class.named = 0;
708
              class.u.id = CTL_EDIT;
709
              res_text_field = $2;
710
            }
711
            control_params
712
          {
713
            $$ = $4;
714
            if (dialog.ex == NULL)
715
              rcparse_warning (_("IEDIT requires DIALOGEX"));
716
            res_string_to_id (&$$->class, "HEDIT");
717
          }
718
        | ICON resref numexpr cnumexpr cnumexpr opt_control_data
719
          {
720
            $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
721
                                      dialog.ex);
722
          }
723
        | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
724
            opt_control_data
725
          {
726
            $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
727
                                      dialog.ex);
728
          }
729
        | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
730
            icon_styleexpr optcnumexpr opt_control_data
731
          {
732
            $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
733
                                      dialog.ex);
734
          }
735
        | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
736
            icon_styleexpr cnumexpr cnumexpr opt_control_data
737
          {
738
            $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
739
                                      dialog.ex);
740
          }
741
        | IEDIT optresidc
742
            {
743
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
744
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
745
              class.named = 0;
746
              class.u.id = CTL_EDIT;
747
              res_text_field = $2;
748
            }
749
            control_params
750
          {
751
            $$ = $4;
752
            if (dialog.ex == NULL)
753
              rcparse_warning (_("IEDIT requires DIALOGEX"));
754
            res_string_to_id (&$$->class, "IEDIT");
755
          }
756
        | LISTBOX
757
            {
758
              default_style = LBS_NOTIFY | WS_BORDER;
759
              base_style = LBS_NOTIFY | WS_BORDER;
760
              class.named = 0;
761
              class.u.id = CTL_LISTBOX;
762
              res_text_field = res_null_text;
763
            }
764
            control_params
765
          {
766
            $$ = $3;
767
          }
768
        | LTEXT optresidc
769
            {
770
              default_style = SS_LEFT | WS_GROUP;
771
              base_style = SS_LEFT;
772
              class.named = 0;
773
              class.u.id = CTL_STATIC;
774
              res_text_field = $2;
775
            }
776
            control_params
777
          {
778
            $$ = $4;
779
          }
780
        | PUSHBOX optresidc
781
            {
782
              default_style = BS_PUSHBOX | WS_TABSTOP;
783
              base_style = BS_PUSHBOX;
784
              class.named = 0;
785
              class.u.id = CTL_BUTTON;
786
            }
787
            control_params
788
          {
789
            $$ = $4;
790
          }
791
        | PUSHBUTTON optresidc
792
            {
793
              default_style = BS_PUSHBUTTON | WS_TABSTOP;
794
              base_style = BS_PUSHBUTTON | WS_TABSTOP;
795
              class.named = 0;
796
              class.u.id = CTL_BUTTON;
797
              res_text_field = $2;
798
            }
799
            control_params
800
          {
801
            $$ = $4;
802
          }
803
        | RADIOBUTTON optresidc
804
            {
805
              default_style = BS_RADIOBUTTON | WS_TABSTOP;
806
              base_style = BS_RADIOBUTTON;
807
              class.named = 0;
808
              class.u.id = CTL_BUTTON;
809
              res_text_field = $2;
810
            }
811
            control_params
812
          {
813
            $$ = $4;
814
          }
815
        | RTEXT optresidc
816
            {
817
              default_style = SS_RIGHT | WS_GROUP;
818
              base_style = SS_RIGHT;
819
              class.named = 0;
820
              class.u.id = CTL_STATIC;
821
              res_text_field = $2;
822
            }
823
            control_params
824
          {
825
            $$ = $4;
826
          }
827
        | SCROLLBAR
828
            {
829
              default_style = SBS_HORZ;
830
              base_style = 0;
831
              class.named = 0;
832
              class.u.id = CTL_SCROLLBAR;
833
              res_text_field = res_null_text;
834
            }
835
            control_params
836
          {
837
            $$ = $3;
838
          }
839
        | STATE3 optresidc
840
            {
841
              default_style = BS_3STATE | WS_TABSTOP;
842
              base_style = BS_3STATE;
843
              class.named = 0;
844
              class.u.id = CTL_BUTTON;
845
              res_text_field = $2;
846
            }
847
            control_params
848
          {
849
            $$ = $4;
850
          }
851
        | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
852
            numexpr ',' numexpr ','
853
            { style = WS_CHILD | WS_VISIBLE; }
854
            styleexpr optcnumexpr
855
          {
856
            rc_res_id cid;
857
            cid.named = 0;
858
            cid.u.id = CTL_BUTTON;
859
            $$ = define_control ($2, $3, $5, $7, $9, $11, cid,
860
                                 style, $15);
861
          }
862
        ;
863
 
864
/* Parameters for a control.  The static variables DEFAULT_STYLE,
865
   BASE_STYLE, and CLASS must be initialized before this nonterminal
866
   is used.  DEFAULT_STYLE is the style to use if no style expression
867
   is specified.  BASE_STYLE is the base style to use if a style
868
   expression is specified; the style expression modifies the base
869
   style.  CLASS is the class of the control.  */
870
 
871
control_params:
872
          numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
873
          {
874
            $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
875
                                 default_style | WS_CHILD | WS_VISIBLE, 0);
876
            if ($6 != NULL)
877
              {
878
                if (dialog.ex == NULL)
879
                  rcparse_warning (_("control data requires DIALOGEX"));
880
                $$->data = $6;
881
              }
882
          }
883
        | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
884
            control_params_styleexpr optcnumexpr opt_control_data
885
          {
886
            $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
887
            if ($8 != NULL)
888
              {
889
                if (dialog.ex == NULL)
890
                  rcparse_warning (_("control data requires DIALOGEX"));
891
                $$->data = $8;
892
              }
893
          }
894
        | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
895
            control_params_styleexpr cnumexpr cnumexpr opt_control_data
896
          {
897
            $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
898
            if (dialog.ex == NULL)
899
              rcparse_warning (_("help ID requires DIALOGEX"));
900
            $$->help = $8;
901
            $$->data = $9;
902
          }
903
        ;
904
 
905
cresid:
906
          ',' resid
907
          {
908
            if ($2.named)
909
              res_unistring_to_id (&$$, $2.u.n.name);
910
            else
911
              $$=$2;
912
          }
913
        ;
914
 
915
optresidc:
916
          /* empty */
917
          {
918
            res_string_to_id (&$$, "");
919
          }
920
        | resid ',' { $$=$1; }
921
        ;
922
 
923
resid:
924
          posnumexpr
925
          {
926
            $$.named = 0;
927
            $$.u.id = $1;
928
          }
929
        | res_unicode_string_concat
930
          {
931
            $$.named = 1;
932
            $$.u.n.name = $1;
933
            $$.u.n.length = unichar_len ($1);
934
          }
935
        ;
936
 
937
opt_control_data:
938
          /* empty */
939
          {
940
            $$ = NULL;
941
          }
942
        | BEG optrcdata_data END
943
          {
944
            $$ = $2.first;
945
          }
946
        ;
947
 
948
/* These only exist to parse a reduction out of a common case.  */
949
 
950
control_styleexpr:
951
          ','
952
          { style = WS_CHILD | WS_VISIBLE; }
953
          styleexpr
954
        ;
955
 
956
icon_styleexpr:
957
          ','
958
          { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
959
          styleexpr
960
        ;
961
 
962
control_params_styleexpr:
963
          ','
964
          { style = base_style | WS_CHILD | WS_VISIBLE; }
965
          styleexpr
966
        ;
967
 
968
/* Font resources.  */
969
 
970
font:
971
          id FONT memflags_move_discard file_name
972
          {
973
            define_font ($1, &$3, $4);
974
            if (yychar != YYEMPTY)
975
              YYERROR;
976
            rcparse_discard_strings ();
977
          }
978
        ;
979
 
980
/* Icon resources.  */
981
 
982
icon:
983
          id ICON memflags_move_discard file_name
984
          {
985
            define_icon ($1, &$3, $4);
986
            if (yychar != YYEMPTY)
987
              YYERROR;
988
            rcparse_discard_strings ();
989
          }
990
        ;
991
 
992
/* Language command.  This changes the static variable language, which
993
   affects all subsequent resources.  */
994
 
995
language:
996
          LANGUAGE numexpr cnumexpr
997
          {
998
            language = $2 | ($3 << SUBLANG_SHIFT);
999
          }
1000
        ;
1001
 
1002
/* Menu resources.  */
1003
 
1004
menu:
1005
          id MENU suboptions BEG menuitems END
1006
          {
1007
            define_menu ($1, &$3, $5);
1008
            if (yychar != YYEMPTY)
1009
              YYERROR;
1010
            rcparse_discard_strings ();
1011
          }
1012
        ;
1013
 
1014
menuitems:
1015
          /* empty */
1016
          {
1017
            $$ = NULL;
1018
          }
1019
        | menuitems menuitem
1020
          {
1021
            if ($1 == NULL)
1022
              $$ = $2;
1023
            else
1024
              {
1025
                rc_menuitem **pp;
1026
 
1027
                for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1028
                  ;
1029
                *pp = $2;
1030
                $$ = $1;
1031
              }
1032
          }
1033
        ;
1034
 
1035
menuitem:
1036
          MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
1037
          {
1038
            $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
1039
          }
1040
        | MENUITEM SEPARATOR
1041
          {
1042
            $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1043
          }
1044
        | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
1045
          {
1046
            $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1047
          }
1048
        ;
1049
 
1050
menuitem_flags:
1051
          /* empty */
1052
          {
1053
            $$ = 0;
1054
          }
1055
        | menuitem_flags ',' menuitem_flag
1056
          {
1057
            $$ = $1 | $3;
1058
          }
1059
        | menuitem_flags menuitem_flag
1060
          {
1061
            $$ = $1 | $2;
1062
          }
1063
        ;
1064
 
1065
menuitem_flag:
1066
          CHECKED
1067
          {
1068
            $$ = MENUITEM_CHECKED;
1069
          }
1070
        | GRAYED
1071
          {
1072
            $$ = MENUITEM_GRAYED;
1073
          }
1074
        | HELP
1075
          {
1076
            $$ = MENUITEM_HELP;
1077
          }
1078
        | INACTIVE
1079
          {
1080
            $$ = MENUITEM_INACTIVE;
1081
          }
1082
        | MENUBARBREAK
1083
          {
1084
            $$ = MENUITEM_MENUBARBREAK;
1085
          }
1086
        | MENUBREAK
1087
          {
1088
            $$ = MENUITEM_MENUBREAK;
1089
          }
1090
        ;
1091
 
1092
/* Menuex resources.  */
1093
 
1094
menuex:
1095
          id MENUEX suboptions BEG menuexitems END
1096
          {
1097
            define_menu ($1, &$3, $5);
1098
            if (yychar != YYEMPTY)
1099
              YYERROR;
1100
            rcparse_discard_strings ();
1101
          }
1102
        ;
1103
 
1104
menuexitems:
1105
          /* empty */
1106
          {
1107
            $$ = NULL;
1108
          }
1109
        | menuexitems menuexitem
1110
          {
1111
            if ($1 == NULL)
1112
              $$ = $2;
1113
            else
1114
              {
1115
                rc_menuitem **pp;
1116
 
1117
                for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1118
                  ;
1119
                *pp = $2;
1120
                $$ = $1;
1121
              }
1122
          }
1123
        ;
1124
 
1125
menuexitem:
1126
          MENUITEM res_unicode_string_concat
1127
          {
1128
            $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1129
          }
1130
        | MENUITEM res_unicode_string_concat cnumexpr
1131
          {
1132
            $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1133
          }
1134
        | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
1135
          {
1136
            $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1137
          }
1138
        | MENUITEM SEPARATOR
1139
          {
1140
            $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1141
          }
1142
        | POPUP res_unicode_string_concat BEG menuexitems END
1143
          {
1144
            $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1145
          }
1146
        | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
1147
          {
1148
            $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1149
          }
1150
        | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
1151
          {
1152
            $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1153
          }
1154
        | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
1155
            BEG menuexitems END
1156
          {
1157
            $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1158
          }
1159
        ;
1160
 
1161
/* Messagetable resources.  */
1162
 
1163
messagetable:
1164
          id MESSAGETABLE memflags_move file_name
1165
          {
1166
            define_messagetable ($1, &$3, $4);
1167
            if (yychar != YYEMPTY)
1168
              YYERROR;
1169
            rcparse_discard_strings ();
1170
          }
1171
        ;
1172
 
1173
/* We use a different lexing algorithm, because rcdata strings may
1174
   contain embedded null bytes, and we need to know the length to use.  */
1175
 
1176
optrcdata_data:
1177
          {
1178
            rcparse_rcdata ();
1179
          }
1180
          optrcdata_data_int
1181
          {
1182
            rcparse_normal ();
1183
            $$ = $2;
1184
          }
1185
        ;
1186
 
1187
optrcdata_data_int:
1188
          /* empty */
1189
          {
1190
            $$.first = NULL;
1191
            $$.last = NULL;
1192
          }
1193
        | rcdata_data
1194
          {
1195
            $$ = $1;
1196
          }
1197
        ;
1198
 
1199
rcdata_data:
1200
          sizedstring
1201
          {
1202
            rc_rcdata_item *ri;
1203
 
1204
            ri = define_rcdata_string ($1.s, $1.length);
1205
            $$.first = ri;
1206
            $$.last = ri;
1207
          }
1208
        | sizedunistring
1209
          {
1210
            rc_rcdata_item *ri;
1211
 
1212
            ri = define_rcdata_unistring ($1.s, $1.length);
1213
            $$.first = ri;
1214
            $$.last = ri;
1215
          }
1216
        | sizednumexpr
1217
          {
1218
            rc_rcdata_item *ri;
1219
 
1220
            ri = define_rcdata_number ($1.val, $1.dword);
1221
            $$.first = ri;
1222
            $$.last = ri;
1223
          }
1224
        | rcdata_data ',' sizedstring
1225
          {
1226
            rc_rcdata_item *ri;
1227
 
1228
            ri = define_rcdata_string ($3.s, $3.length);
1229
            $$.first = $1.first;
1230
            $1.last->next = ri;
1231
            $$.last = ri;
1232
          }
1233
        | rcdata_data ',' sizedunistring
1234
          {
1235
            rc_rcdata_item *ri;
1236
 
1237
            ri = define_rcdata_unistring ($3.s, $3.length);
1238
            $$.first = $1.first;
1239
            $1.last->next = ri;
1240
            $$.last = ri;
1241
          }
1242
        | rcdata_data ',' sizednumexpr
1243
          {
1244
            rc_rcdata_item *ri;
1245
 
1246
            ri = define_rcdata_number ($3.val, $3.dword);
1247
            $$.first = $1.first;
1248
            $1.last->next = ri;
1249
            $$.last = ri;
1250
          }
1251
        | rcdata_data ','
1252
          {
1253
            $$=$1;
1254
          }
1255
        ;
1256
 
1257
/* Stringtable resources.  */
1258
 
1259
stringtable:
1260
          STRINGTABLE suboptions BEG
1261
            { sub_res_info = $2; }
1262
            string_data END
1263
        ;
1264
 
1265
string_data:
1266
          /* empty */
1267
        | string_data numexpr res_unicode_string_concat
1268
          {
1269
            define_stringtable (&sub_res_info, $2, $3);
1270
            rcparse_discard_strings ();
1271
          }
1272
        | string_data numexpr ',' res_unicode_string_concat
1273
          {
1274
            define_stringtable (&sub_res_info, $2, $4);
1275
            rcparse_discard_strings ();
1276
          }
1277
        | string_data error
1278
          {
1279
            rcparse_warning (_("invalid stringtable resource."));
1280
            abort ();
1281
          }
1282
        ;
1283
 
1284
rcdata_id:
1285
        id
1286
          {
1287
            $$=$1;
1288
          }
1289
      | HTML
1290
        {
1291
          $$.named = 0;
1292
          $$.u.id = 23;
1293
        }
1294
      | RCDATA
1295
        {
1296
          $$.named = 0;
1297
          $$.u.id = RT_RCDATA;
1298
        }
1299
      | MANIFEST
1300
        {
1301
          $$.named = 0;
1302
          $$.u.id = RT_MANIFEST;
1303
        }
1304
      | PLUGPLAY
1305
        {
1306
          $$.named = 0;
1307
          $$.u.id = RT_PLUGPLAY;
1308
        }
1309
      | VXD
1310
        {
1311
          $$.named = 0;
1312
          $$.u.id = RT_VXD;
1313
        }
1314
      | DLGINCLUDE
1315
        {
1316
          $$.named = 0;
1317
          $$.u.id = RT_DLGINCLUDE;
1318
        }
1319
      | DLGINIT
1320
        {
1321
          $$.named = 0;
1322
          $$.u.id = RT_DLGINIT;
1323
        }
1324
      | ANICURSOR
1325
        {
1326
          $$.named = 0;
1327
          $$.u.id = RT_ANICURSOR;
1328
        }
1329
      | ANIICON
1330
        {
1331
          $$.named = 0;
1332
          $$.u.id = RT_ANIICON;
1333
        }
1334
      ;
1335
 
1336
/* User defined resources.  We accept general suboptions in the
1337
   file_name case to keep the parser happy.  */
1338
 
1339
user:
1340
          id rcdata_id suboptions BEG optrcdata_data END
1341
          {
1342
            define_user_data ($1, $2, &$3, $5.first);
1343
            if (yychar != YYEMPTY)
1344
              YYERROR;
1345
            rcparse_discard_strings ();
1346
          }
1347
        | id rcdata_id suboptions file_name
1348
          {
1349
            define_user_file ($1, $2, &$3, $4);
1350
            if (yychar != YYEMPTY)
1351
              YYERROR;
1352
            rcparse_discard_strings ();
1353
          }
1354
        ;
1355
 
1356
toolbar:
1357
        id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
1358
        {
1359
          define_toolbar ($1, &$3, $4, $5, $7);
1360
        }
1361
        ;
1362
 
1363
toolbar_data: /* empty */ { $$= NULL; }
1364
        | toolbar_data BUTTON id
1365
        {
1366
          rc_toolbar_item *c,*n;
1367
          c = $1;
1368
          n= (rc_toolbar_item *)
1369
              res_alloc (sizeof (rc_toolbar_item));
1370
          if (c != NULL)
1371
            while (c->next != NULL)
1372
              c = c->next;
1373
          n->prev = c;
1374
          n->next = NULL;
1375
          if (c != NULL)
1376
            c->next = n;
1377
          n->id = $3;
1378
          if ($1 == NULL)
1379
            $$ = n;
1380
          else
1381
            $$ = $1;
1382
        }
1383
        | toolbar_data SEPARATOR
1384
        {
1385
          rc_toolbar_item *c,*n;
1386
          c = $1;
1387
          n= (rc_toolbar_item *)
1388
              res_alloc (sizeof (rc_toolbar_item));
1389
          if (c != NULL)
1390
            while (c->next != NULL)
1391
              c = c->next;
1392
          n->prev = c;
1393
          n->next = NULL;
1394
          if (c != NULL)
1395
            c->next = n;
1396
          n->id.named = 0;
1397
          n->id.u.id = 0;
1398
          if ($1 == NULL)
1399
            $$ = n;
1400
          else
1401
            $$ = $1;
1402
        }
1403
        ;
1404
 
1405
/* Versioninfo resources.  */
1406
 
1407
versioninfo:
1408
          id VERSIONINFO fixedverinfo BEG verblocks END
1409
          {
1410
            define_versioninfo ($1, language, $3, $5);
1411
            if (yychar != YYEMPTY)
1412
              YYERROR;
1413
            rcparse_discard_strings ();
1414
          }
1415
        ;
1416
 
1417
fixedverinfo:
1418
          /* empty */
1419
          {
1420
            $$ = ((rc_fixed_versioninfo *)
1421
                  res_alloc (sizeof (rc_fixed_versioninfo)));
1422
            memset ($$, 0, sizeof (rc_fixed_versioninfo));
1423
          }
1424
        | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1425
          {
1426
            $1->file_version_ms = ($3 << 16) | $4;
1427
            $1->file_version_ls = ($5 << 16) | $6;
1428
            $$ = $1;
1429
          }
1430
        | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1431
          {
1432
            $1->product_version_ms = ($3 << 16) | $4;
1433
            $1->product_version_ls = ($5 << 16) | $6;
1434
            $$ = $1;
1435
          }
1436
        | fixedverinfo FILEFLAGSMASK numexpr
1437
          {
1438
            $1->file_flags_mask = $3;
1439
            $$ = $1;
1440
          }
1441
        | fixedverinfo FILEFLAGS numexpr
1442
          {
1443
            $1->file_flags = $3;
1444
            $$ = $1;
1445
          }
1446
        | fixedverinfo FILEOS numexpr
1447
          {
1448
            $1->file_os = $3;
1449
            $$ = $1;
1450
          }
1451
        | fixedverinfo FILETYPE numexpr
1452
          {
1453
            $1->file_type = $3;
1454
            $$ = $1;
1455
          }
1456
        | fixedverinfo FILESUBTYPE numexpr
1457
          {
1458
            $1->file_subtype = $3;
1459
            $$ = $1;
1460
          }
1461
        ;
1462
 
1463
/* To handle verblocks successfully, the lexer handles BLOCK
1464
   specially.  A BLOCK "StringFileInfo" is returned as
1465
   BLOCKSTRINGFILEINFO.  A BLOCK "VarFileInfo" is returned as
1466
   BLOCKVARFILEINFO.  A BLOCK with some other string returns BLOCK
1467
   with the string as the value.  */
1468
 
1469
verblocks:
1470
          /* empty */
1471
          {
1472
            $$ = NULL;
1473
          }
1474
        | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1475
          {
1476
            $$ = append_ver_stringfileinfo ($1, $4, $6);
1477
          }
1478
        | verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
1479
          {
1480
            $$ = append_ver_varfileinfo ($1, $5, $6);
1481
          }
1482
        ;
1483
 
1484
vervals:
1485
          /* empty */
1486
          {
1487
            $$ = NULL;
1488
          }
1489
        | vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
1490
          {
1491
            $$ = append_verval ($1, $3, $5);
1492
          }
1493
        ;
1494
 
1495
vertrans:
1496
          /* empty */
1497
          {
1498
            $$ = NULL;
1499
          }
1500
        | vertrans cnumexpr cnumexpr
1501
          {
1502
            $$ = append_vertrans ($1, $2, $3);
1503
          }
1504
        ;
1505
 
1506
/* A resource ID.  */
1507
 
1508
id:
1509
          posnumexpr
1510
          {
1511
            $$.named = 0;
1512
            $$.u.id = $1;
1513
          }
1514
        | resname
1515
          {
1516
            res_unistring_to_id (&$$, $1);
1517
          }
1518
        ;
1519
 
1520
/* A resource reference.  */
1521
 
1522
resname:
1523
          res_unicode_string
1524
          {
1525
            $$ = $1;
1526
          }
1527
        | STRING
1528
          {
1529
            unichar *h = NULL;
1530
            unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1531
            $$ = h;
1532
          }
1533
        ;
1534
 
1535
 
1536
resref:
1537
          posnumexpr ','
1538
          {
1539
            $$.named = 0;
1540
            $$.u.id = $1;
1541
          }
1542
        | resname
1543
          {
1544
            res_unistring_to_id (&$$, $1);
1545
          }
1546
        | resname ','
1547
          {
1548
            res_unistring_to_id (&$$, $1);
1549
          }
1550
        ;
1551
 
1552
/* Generic suboptions.  These may appear before the BEGIN in any
1553
   multiline statement.  */
1554
 
1555
suboptions:
1556
          /* empty */
1557
          {
1558
            memset (&$$, 0, sizeof (rc_res_res_info));
1559
            $$.language = language;
1560
            /* FIXME: Is this the right default?  */
1561
            $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1562
          }
1563
        | suboptions memflag
1564
          {
1565
            $$ = $1;
1566
            $$.memflags |= $2.on;
1567
            $$.memflags &=~ $2.off;
1568
          }
1569
        | suboptions CHARACTERISTICS numexpr
1570
          {
1571
            $$ = $1;
1572
            $$.characteristics = $3;
1573
          }
1574
        | suboptions LANGUAGE numexpr cnumexpr
1575
          {
1576
            $$ = $1;
1577
            $$.language = $3 | ($4 << SUBLANG_SHIFT);
1578
          }
1579
        | suboptions VERSIONK numexpr
1580
          {
1581
            $$ = $1;
1582
            $$.version = $3;
1583
          }
1584
        ;
1585
 
1586
/* Memory flags which default to MOVEABLE and DISCARDABLE.  */
1587
 
1588
memflags_move_discard:
1589
          /* empty */
1590
          {
1591
            memset (&$$, 0, sizeof (rc_res_res_info));
1592
            $$.language = language;
1593
            $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1594
          }
1595
        | memflags_move_discard memflag
1596
          {
1597
            $$ = $1;
1598
            $$.memflags |= $2.on;
1599
            $$.memflags &=~ $2.off;
1600
          }
1601
        ;
1602
 
1603
/* Memory flags which default to MOVEABLE.  */
1604
 
1605
memflags_move:
1606
          /* empty */
1607
          {
1608
            memset (&$$, 0, sizeof (rc_res_res_info));
1609
            $$.language = language;
1610
            $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1611
          }
1612
        | memflags_move memflag
1613
          {
1614
            $$ = $1;
1615
            $$.memflags |= $2.on;
1616
            $$.memflags &=~ $2.off;
1617
          }
1618
        ;
1619
 
1620
/* Memory flags.  This returns a struct with two integers, because we
1621
   sometimes want to set bits and we sometimes want to clear them.  */
1622
 
1623
memflag:
1624
          MOVEABLE
1625
          {
1626
            $$.on = MEMFLAG_MOVEABLE;
1627
            $$.off = 0;
1628
          }
1629
        | FIXED
1630
          {
1631
            $$.on = 0;
1632
            $$.off = MEMFLAG_MOVEABLE;
1633
          }
1634
        | PURE
1635
          {
1636
            $$.on = MEMFLAG_PURE;
1637
            $$.off = 0;
1638
          }
1639
        | IMPURE
1640
          {
1641
            $$.on = 0;
1642
            $$.off = MEMFLAG_PURE;
1643
          }
1644
        | PRELOAD
1645
          {
1646
            $$.on = MEMFLAG_PRELOAD;
1647
            $$.off = 0;
1648
          }
1649
        | LOADONCALL
1650
          {
1651
            $$.on = 0;
1652
            $$.off = MEMFLAG_PRELOAD;
1653
          }
1654
        | DISCARDABLE
1655
          {
1656
            $$.on = MEMFLAG_DISCARDABLE;
1657
            $$.off = 0;
1658
          }
1659
        ;
1660
 
1661
/* A file name.  */
1662
 
1663
file_name:
1664
          QUOTEDSTRING
1665
          {
1666
            $$ = $1;
1667
          }
1668
        | STRING
1669
          {
1670
            $$ = $1;
1671
          }
1672
        ;
1673
 
1674
/* Concat string */
1675
res_unicode_string_concat:
1676
          res_unicode_string
1677
          {
1678
            $$ = $1;
1679
          }
1680
        |
1681
          res_unicode_string_concat res_unicode_string
1682
          {
1683
            rc_uint_type l1 = unichar_len ($1);
1684
            rc_uint_type l2 = unichar_len ($2);
1685
            unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
1686
            if (l1 != 0)
1687
              memcpy (h, $1, l1 * sizeof (unichar));
1688
            if (l2 != 0)
1689
              memcpy (h + l1, $2, l2  * sizeof (unichar));
1690
            h[l1 + l2] = 0;
1691
            $$ = h;
1692
          }
1693
        ;
1694
 
1695
res_unicode_string:
1696
          QUOTEDUNISTRING
1697
          {
1698
            $$ = unichar_dup ($1);
1699
          }
1700
        | QUOTEDSTRING
1701
          {
1702
            unichar *h = NULL;
1703
            unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1704
            $$ = h;
1705
          }
1706
        ;
1707
 
1708
sizedstring:
1709
          SIZEDSTRING
1710
          {
1711
            $$ = $1;
1712
          }
1713
        | sizedstring SIZEDSTRING
1714
          {
1715
            rc_uint_type l = $1.length + $2.length;
1716
            char *h = (char *) res_alloc (l);
1717
            memcpy (h, $1.s, $1.length);
1718
            memcpy (h + $1.length, $2.s, $2.length);
1719
            $$.s = h;
1720
            $$.length = l;
1721
          }
1722
        ;
1723
 
1724
sizedunistring:
1725
          SIZEDUNISTRING
1726
          {
1727
            $$ = $1;
1728
          }
1729
        | sizedunistring SIZEDUNISTRING
1730
          {
1731
            rc_uint_type l = $1.length + $2.length;
1732
            unichar *h = (unichar *) res_alloc (l * sizeof (unichar));
1733
            memcpy (h, $1.s, $1.length * sizeof (unichar));
1734
            memcpy (h + $1.length, $2.s, $2.length  * sizeof (unichar));
1735
            $$.s = h;
1736
            $$.length = l;
1737
          }
1738
        ;
1739
 
1740
/* A style expression.  This changes the static variable STYLE.  We do
1741
   it this way because rc appears to permit a style to be set to
1742
   something like
1743
       WS_GROUP | NOT WS_TABSTOP
1744
   to mean that a default of WS_TABSTOP should be removed.  Anything
1745
   which wants to accept a style must first set STYLE to the default
1746
   value.  The styleexpr nonterminal will change STYLE as specified by
1747
   the user.  Note that we do not accept arbitrary expressions here,
1748
   just numbers separated by '|'.  */
1749
 
1750
styleexpr:
1751
          parennumber
1752
          {
1753
            style |= $1;
1754
          }
1755
        | NOT parennumber
1756
          {
1757
            style &=~ $2;
1758
          }
1759
        | styleexpr '|' parennumber
1760
          {
1761
            style |= $3;
1762
          }
1763
        | styleexpr '|' NOT parennumber
1764
          {
1765
            style &=~ $4;
1766
          }
1767
        ;
1768
 
1769
parennumber:
1770
          NUMBER
1771
          {
1772
            $$ = $1.val;
1773
          }
1774
        | '(' numexpr ')'
1775
          {
1776
            $$ = $2;
1777
          }
1778
        ;
1779
 
1780
/* An optional expression with a leading comma.  */
1781
 
1782
optcnumexpr:
1783
          /* empty */
1784
          {
1785
            $$ = 0;
1786
          }
1787
        | cnumexpr
1788
          {
1789
            $$ = $1;
1790
          }
1791
        ;
1792
 
1793
/* An expression with a leading comma.  */
1794
 
1795
cnumexpr:
1796
          ',' numexpr
1797
          {
1798
            $$ = $2;
1799
          }
1800
        ;
1801
 
1802
/* A possibly negated numeric expression.  */
1803
 
1804
numexpr:
1805
          sizednumexpr
1806
          {
1807
            $$ = $1.val;
1808
          }
1809
        ;
1810
 
1811
/* A possibly negated expression with a size.  */
1812
 
1813
sizednumexpr:
1814
          NUMBER
1815
          {
1816
            $$ = $1;
1817
          }
1818
        | '(' sizednumexpr ')'
1819
          {
1820
            $$ = $2;
1821
          }
1822
        | '~' sizednumexpr %prec '~'
1823
          {
1824
            $$.val = ~ $2.val;
1825
            $$.dword = $2.dword;
1826
          }
1827
        | '-' sizednumexpr %prec NEG
1828
          {
1829
            $$.val = - $2.val;
1830
            $$.dword = $2.dword;
1831
          }
1832
        | sizednumexpr '*' sizednumexpr
1833
          {
1834
            $$.val = $1.val * $3.val;
1835
            $$.dword = $1.dword || $3.dword;
1836
          }
1837
        | sizednumexpr '/' sizednumexpr
1838
          {
1839
            $$.val = $1.val / $3.val;
1840
            $$.dword = $1.dword || $3.dword;
1841
          }
1842
        | sizednumexpr '%' sizednumexpr
1843
          {
1844
            $$.val = $1.val % $3.val;
1845
            $$.dword = $1.dword || $3.dword;
1846
          }
1847
        | sizednumexpr '+' sizednumexpr
1848
          {
1849
            $$.val = $1.val + $3.val;
1850
            $$.dword = $1.dword || $3.dword;
1851
          }
1852
        | sizednumexpr '-' sizednumexpr
1853
          {
1854
            $$.val = $1.val - $3.val;
1855
            $$.dword = $1.dword || $3.dword;
1856
          }
1857
        | sizednumexpr '&' sizednumexpr
1858
          {
1859
            $$.val = $1.val & $3.val;
1860
            $$.dword = $1.dword || $3.dword;
1861
          }
1862
        | sizednumexpr '^' sizednumexpr
1863
          {
1864
            $$.val = $1.val ^ $3.val;
1865
            $$.dword = $1.dword || $3.dword;
1866
          }
1867
        | sizednumexpr '|' sizednumexpr
1868
          {
1869
            $$.val = $1.val | $3.val;
1870
            $$.dword = $1.dword || $3.dword;
1871
          }
1872
        ;
1873
 
1874
/* An expression with a leading comma which does not use unary
1875
   negation.  */
1876
 
1877
cposnumexpr:
1878
          ',' posnumexpr
1879
          {
1880
            $$ = $2;
1881
          }
1882
        ;
1883
 
1884
/* An expression which does not use unary negation.  */
1885
 
1886
posnumexpr:
1887
          sizedposnumexpr
1888
          {
1889
            $$ = $1.val;
1890
          }
1891
        ;
1892
 
1893
/* An expression which does not use unary negation.  We separate unary
1894
   negation to avoid parsing conflicts when two numeric expressions
1895
   appear consecutively.  */
1896
 
1897
sizedposnumexpr:
1898
          NUMBER
1899
          {
1900
            $$ = $1;
1901
          }
1902
        | '(' sizednumexpr ')'
1903
          {
1904
            $$ = $2;
1905
          }
1906
        | '~' sizednumexpr %prec '~'
1907
          {
1908
            $$.val = ~ $2.val;
1909
            $$.dword = $2.dword;
1910
          }
1911
        | sizedposnumexpr '*' sizednumexpr
1912
          {
1913
            $$.val = $1.val * $3.val;
1914
            $$.dword = $1.dword || $3.dword;
1915
          }
1916
        | sizedposnumexpr '/' sizednumexpr
1917
          {
1918
            $$.val = $1.val / $3.val;
1919
            $$.dword = $1.dword || $3.dword;
1920
          }
1921
        | sizedposnumexpr '%' sizednumexpr
1922
          {
1923
            $$.val = $1.val % $3.val;
1924
            $$.dword = $1.dword || $3.dword;
1925
          }
1926
        | sizedposnumexpr '+' sizednumexpr
1927
          {
1928
            $$.val = $1.val + $3.val;
1929
            $$.dword = $1.dword || $3.dword;
1930
          }
1931
        | sizedposnumexpr '-' sizednumexpr
1932
          {
1933
            $$.val = $1.val - $3.val;
1934
            $$.dword = $1.dword || $3.dword;
1935
          }
1936
        | sizedposnumexpr '&' sizednumexpr
1937
          {
1938
            $$.val = $1.val & $3.val;
1939
            $$.dword = $1.dword || $3.dword;
1940
          }
1941
        | sizedposnumexpr '^' sizednumexpr
1942
          {
1943
            $$.val = $1.val ^ $3.val;
1944
            $$.dword = $1.dword || $3.dword;
1945
          }
1946
        | sizedposnumexpr '|' sizednumexpr
1947
          {
1948
            $$.val = $1.val | $3.val;
1949
            $$.dword = $1.dword || $3.dword;
1950
          }
1951
        ;
1952
 
1953
%%
1954
 
1955
/* Set the language from the command line.  */
1956
 
1957
void
1958
rcparse_set_language (int lang)
1959
{
1960
  language = lang;
1961
}

powered by: WebSVN 2.1.0

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