1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of GNU Binutils.
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.
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.
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
22 /* This is a parser for Windows rc files. It is based on the parser
23 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
27 #include "libiberty.h"
29 #include "safe-ctype.h"
31 /* The current language. */
33 static unsigned short language;
35 /* The resource information during a sub statement. */
37 static struct res_res_info sub_res_info;
39 /* Dialog information. This is built by the nonterminals styles and
42 static struct dialog dialog;
44 /* This is used when building a style. It is modified by the
45 nonterminal styleexpr. */
47 static unsigned long style;
49 /* These are used when building a control. They are set before using
52 static unsigned long base_style;
53 static unsigned long default_style;
54 static unsigned long class;
60 struct accelerator acc;
61 struct accelerator *pacc;
62 struct dialog_control *dialog_control;
63 struct menuitem *menuitem;
66 struct rcdata_item *first;
67 struct rcdata_item *last;
69 struct rcdata_item *rcdata_item;
70 struct stringtable_data *stringtable;
71 struct fixed_versioninfo *fixver;
72 struct ver_info *verinfo;
73 struct ver_stringinfo *verstring;
74 struct ver_varinfo *vervar;
76 struct res_res_info res_info;
85 /* Nonzero if this number was explicitly specified as long. */
99 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
102 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
103 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
104 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
105 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
106 %token BEDIT HEDIT IEDIT
109 %token LANGUAGE CHARACTERISTICS VERSIONK
110 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
111 %token MENUBARBREAK MENUBREAK
115 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
116 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
119 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
121 %token <s> QUOTEDSTRING STRING
123 %token <ss> SIZEDSTRING
126 %type <pacc> acc_entries
127 %type <acc> acc_entry acc_event
128 %type <dialog_control> control control_params
129 %type <menuitem> menuitems menuitem menuexitems menuexitem
130 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
131 %type <rcdata_item> opt_control_data
132 %type <fixver> fixedverinfo
133 %type <verinfo> verblocks
134 %type <verstring> vervals
135 %type <vervar> vertrans
136 %type <res_info> suboptions memflags_move_discard memflags_move
137 %type <memflags> memflag
139 %type <il> exstyle parennumber
140 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
141 %type <is> acc_options acc_option menuitem_flags menuitem_flag
142 %type <s> optstringc file_name resname
143 %type <i> sizednumexpr sizedposnumexpr
156 | input newcmd accelerator
157 | input newcmd bitmap
158 | input newcmd cursor
159 | input newcmd dialog
162 | input newcmd language
164 | input newcmd menuex
165 | input newcmd messagetable
166 | input newcmd rcdata
167 | input newcmd stringtable
169 | input newcmd versioninfo
170 | input newcmd IGNORED_TOKEN
176 rcparse_discard_strings ();
180 /* Accelerator resources. */
183 id ACCELERATORS suboptions BEG acc_entries END
185 define_accelerator ($1, &$3, $5);
194 | acc_entries acc_entry
196 struct accelerator *a;
198 a = (struct accelerator *) res_alloc (sizeof *a);
204 struct accelerator **pp;
206 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
215 acc_event cposnumexpr
220 | acc_event cposnumexpr ',' acc_options
225 if (($$.flags & ACC_VIRTKEY) == 0
226 && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0)
227 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
244 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
251 rcparse_warning (_("accelerator should only be one character"));
267 | acc_options ',' acc_option
271 /* I've had one report that the comma is optional. */
272 | acc_options acc_option
285 /* This is just the absence of VIRTKEY. */
306 /* Bitmap resources. */
309 id BITMAP memflags_move file_name
311 define_bitmap ($1, &$3, $4);
315 /* Cursor resources. */
318 id CURSOR memflags_move_discard file_name
320 define_cursor ($1, &$3, $4);
324 /* Dialog resources. */
327 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
330 memset (&dialog, 0, sizeof dialog);
335 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
337 dialog.menu.named = 1;
338 dialog.class.named = 1;
341 dialog.controls = NULL;
345 styles BEG controls END
347 define_dialog ($1, &sub_res_info, &dialog);
349 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
352 memset (&dialog, 0, sizeof dialog);
357 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
359 dialog.menu.named = 1;
360 dialog.class.named = 1;
362 dialog.ex = ((struct dialog_ex *)
363 res_alloc (sizeof (struct dialog_ex)));
364 memset (dialog.ex, 0, sizeof (struct dialog_ex));
365 dialog.controls = NULL;
369 styles BEG controls END
371 define_dialog ($1, &sub_res_info, &dialog);
373 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
376 memset (&dialog, 0, sizeof dialog);
381 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
383 dialog.menu.named = 1;
384 dialog.class.named = 1;
386 dialog.ex = ((struct dialog_ex *)
387 res_alloc (sizeof (struct dialog_ex)));
388 memset (dialog.ex, 0, sizeof (struct dialog_ex));
389 dialog.ex->help = $9;
390 dialog.controls = NULL;
394 styles BEG controls END
396 define_dialog ($1, &sub_res_info, &dialog);
405 | EXSTYLE '=' numexpr
413 | styles CAPTION QUOTEDSTRING
415 dialog.style |= WS_CAPTION;
417 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
426 dialog.style = style;
428 | styles EXSTYLE numexpr
432 | styles CLASS QUOTEDSTRING
434 res_string_to_id (& dialog.class, $3);
436 | styles FONT numexpr ',' QUOTEDSTRING
438 dialog.style |= DS_SETFONT;
440 dialog.pointsize = $3;
441 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
442 if (dialog.ex != NULL)
444 dialog.ex->weight = 0;
445 dialog.ex->italic = 0;
446 dialog.ex->charset = 1;
449 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr
451 dialog.style |= DS_SETFONT;
453 dialog.pointsize = $3;
454 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
455 if (dialog.ex == NULL)
456 rcparse_warning (_("extended FONT requires DIALOGEX"));
459 dialog.ex->weight = $6;
460 dialog.ex->italic = 0;
461 dialog.ex->charset = 1;
464 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
466 dialog.style |= DS_SETFONT;
468 dialog.pointsize = $3;
469 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
470 if (dialog.ex == NULL)
471 rcparse_warning (_("extended FONT requires DIALOGEX"));
474 dialog.ex->weight = $6;
475 dialog.ex->italic = $7;
476 dialog.ex->charset = 1;
479 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
481 dialog.style |= DS_SETFONT;
483 dialog.pointsize = $3;
484 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
485 if (dialog.ex == NULL)
486 rcparse_warning (_("extended FONT requires DIALOGEX"));
489 dialog.ex->weight = $6;
490 dialog.ex->italic = $7;
491 dialog.ex->charset = $8;
498 | styles CHARACTERISTICS numexpr
500 sub_res_info.characteristics = $3;
502 | styles LANGUAGE numexpr cnumexpr
504 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
506 | styles VERSIONK numexpr
508 sub_res_info.version = $3;
516 struct dialog_control **pp;
518 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
527 default_style = BS_AUTO3STATE | WS_TABSTOP;
528 base_style = BS_AUTO3STATE;
537 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
538 base_style = BS_AUTOCHECKBOX;
547 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
548 base_style = BS_AUTORADIOBUTTON;
557 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
558 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
564 if (dialog.ex == NULL)
565 rcparse_warning (_("BEDIT requires DIALOGEX"));
566 res_string_to_id (&$$->class, "BEDIT");
570 default_style = BS_CHECKBOX | WS_TABSTOP;
571 base_style = BS_CHECKBOX | WS_TABSTOP;
580 default_style = CBS_SIMPLE | WS_TABSTOP;
582 class = CTL_COMBOBOX;
588 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
589 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
591 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
594 if (dialog.ex == NULL)
595 rcparse_warning (_("control data requires DIALOGEX"));
599 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
600 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
602 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
603 if (dialog.ex == NULL)
604 rcparse_warning (_("help ID requires DIALOGEX"));
608 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
609 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
611 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
614 if (dialog.ex == NULL)
615 rcparse_warning ("control data requires DIALOGEX");
619 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
621 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
622 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
624 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
625 if (dialog.ex == NULL)
626 rcparse_warning ("help ID requires DIALOGEX");
630 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
634 default_style = SS_CENTER | WS_GROUP;
635 base_style = SS_CENTER;
644 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
645 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
654 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
655 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
664 default_style = BS_GROUPBOX;
665 base_style = BS_GROUPBOX;
674 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
675 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
681 if (dialog.ex == NULL)
682 rcparse_warning (_("IEDIT requires DIALOGEX"));
683 res_string_to_id (&$$->class, "HEDIT");
685 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
687 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
690 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
693 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
696 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
697 icon_styleexpr optcnumexpr opt_control_data
699 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
702 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
703 icon_styleexpr cnumexpr cnumexpr opt_control_data
705 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
710 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
711 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
717 if (dialog.ex == NULL)
718 rcparse_warning (_("IEDIT requires DIALOGEX"));
719 res_string_to_id (&$$->class, "IEDIT");
723 default_style = LBS_NOTIFY | WS_BORDER;
724 base_style = LBS_NOTIFY | WS_BORDER;
733 default_style = SS_LEFT | WS_GROUP;
734 base_style = SS_LEFT;
743 default_style = BS_PUSHBOX | WS_TABSTOP;
744 base_style = BS_PUSHBOX;
753 default_style = BS_PUSHBUTTON | WS_TABSTOP;
754 base_style = BS_PUSHBUTTON | WS_TABSTOP;
763 default_style = BS_RADIOBUTTON | WS_TABSTOP;
764 base_style = BS_RADIOBUTTON;
773 default_style = SS_RIGHT | WS_GROUP;
774 base_style = SS_RIGHT;
783 default_style = SBS_HORZ;
785 class = CTL_SCROLLBAR;
793 default_style = BS_3STATE | WS_TABSTOP;
794 base_style = BS_3STATE;
801 | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
802 numexpr ',' numexpr ','
803 { style = WS_CHILD | WS_VISIBLE; }
804 styleexpr optcnumexpr
806 $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
811 /* Parameters for a control. The static variables DEFAULT_STYLE,
812 BASE_STYLE, and CLASS must be initialized before this nonterminal
813 is used. DEFAULT_STYLE is the style to use if no style expression
814 is specified. BASE_STYLE is the base style to use if a style
815 expression is specified; the style expression modifies the base
816 style. CLASS is the class of the control. */
819 optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
822 $$ = define_control ($1, $2, $3, $4, $5, $6, class,
823 default_style | WS_CHILD | WS_VISIBLE, 0);
826 if (dialog.ex == NULL)
827 rcparse_warning (_("control data requires DIALOGEX"));
831 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
832 control_params_styleexpr optcnumexpr opt_control_data
834 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
837 if (dialog.ex == NULL)
838 rcparse_warning (_("control data requires DIALOGEX"));
842 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
843 control_params_styleexpr cnumexpr cnumexpr opt_control_data
845 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
846 if (dialog.ex == NULL)
847 rcparse_warning (_("help ID requires DIALOGEX"));
873 | BEG optrcdata_data END
879 /* These only exist to parse a reduction out of a common case. */
883 { style = WS_CHILD | WS_VISIBLE; }
889 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
893 control_params_styleexpr:
895 { style = base_style | WS_CHILD | WS_VISIBLE; }
899 /* Font resources. */
902 id FONT memflags_move_discard file_name
904 define_font ($1, &$3, $4);
908 /* Icon resources. */
911 id ICON memflags_move_discard file_name
913 define_icon ($1, &$3, $4);
917 /* Language command. This changes the static variable language, which
918 affects all subsequent resources. */
921 LANGUAGE numexpr cnumexpr
923 language = $2 | ($3 << SUBLANG_SHIFT);
927 /* Menu resources. */
930 id MENU suboptions BEG menuitems END
932 define_menu ($1, &$3, $5);
947 struct menuitem **pp;
949 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
958 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
960 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
964 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
966 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
968 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
977 | menuitem_flags ',' menuitem_flag
981 | menuitem_flags menuitem_flag
990 $$ = MENUITEM_CHECKED;
994 $$ = MENUITEM_GRAYED;
1002 $$ = MENUITEM_INACTIVE;
1006 $$ = MENUITEM_MENUBARBREAK;
1010 $$ = MENUITEM_MENUBREAK;
1014 /* Menuex resources. */
1017 id MENUEX suboptions BEG menuexitems END
1019 define_menu ($1, &$3, $5);
1028 | menuexitems menuexitem
1034 struct menuitem **pp;
1036 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1045 MENUITEM QUOTEDSTRING
1047 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1049 | MENUITEM QUOTEDSTRING cnumexpr
1051 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1053 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1055 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1057 | MENUITEM SEPARATOR
1059 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1061 | POPUP QUOTEDSTRING BEG menuexitems END
1063 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1065 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1067 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1069 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1071 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1073 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1076 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1080 /* Messagetable resources. */
1083 id MESSAGETABLE memflags_move file_name
1085 define_messagetable ($1, &$3, $4);
1089 /* Rcdata resources. */
1092 id RCDATA suboptions BEG optrcdata_data END
1094 define_rcdata ($1, &$3, $5.first);
1098 /* We use a different lexing algorithm, because rcdata strings may
1099 contain embedded null bytes, and we need to know the length to use. */
1127 struct rcdata_item *ri;
1129 ri = define_rcdata_string ($1.s, $1.length);
1135 struct rcdata_item *ri;
1137 ri = define_rcdata_number ($1.val, $1.dword);
1141 | rcdata_data ',' SIZEDSTRING
1143 struct rcdata_item *ri;
1145 ri = define_rcdata_string ($3.s, $3.length);
1146 $$.first = $1.first;
1150 | rcdata_data ',' sizednumexpr
1152 struct rcdata_item *ri;
1154 ri = define_rcdata_number ($3.val, $3.dword);
1155 $$.first = $1.first;
1161 /* Stringtable resources. */
1164 STRINGTABLE suboptions BEG
1165 { sub_res_info = $2; }
1171 | string_data numexpr QUOTEDSTRING
1173 define_stringtable (&sub_res_info, $2, $3);
1175 | string_data numexpr ',' QUOTEDSTRING
1177 define_stringtable (&sub_res_info, $2, $4);
1181 /* User defined resources. We accept general suboptions in the
1182 file_name case to keep the parser happy. */
1185 id id suboptions BEG optrcdata_data END
1187 define_user_data ($1, $2, &$3, $5.first);
1189 | id id suboptions file_name
1191 define_user_file ($1, $2, &$3, $4);
1195 /* Versioninfo resources. */
1198 id VERSIONINFO fixedverinfo BEG verblocks END
1200 define_versioninfo ($1, language, $3, $5);
1207 $$ = ((struct fixed_versioninfo *)
1208 res_alloc (sizeof (struct fixed_versioninfo)));
1209 memset ($$, 0, sizeof (struct fixed_versioninfo));
1211 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1213 $1->file_version_ms = ($3 << 16) | $4;
1214 $1->file_version_ls = ($5 << 16) | $6;
1217 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1219 $1->product_version_ms = ($3 << 16) | $4;
1220 $1->product_version_ls = ($5 << 16) | $6;
1223 | fixedverinfo FILEFLAGSMASK numexpr
1225 $1->file_flags_mask = $3;
1228 | fixedverinfo FILEFLAGS numexpr
1230 $1->file_flags = $3;
1233 | fixedverinfo FILEOS numexpr
1238 | fixedverinfo FILETYPE numexpr
1243 | fixedverinfo FILESUBTYPE numexpr
1245 $1->file_subtype = $3;
1250 /* To handle verblocks successfully, the lexer handles BLOCK
1251 specially. A BLOCK "StringFileInfo" is returned as
1252 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1253 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1254 with the string as the value. */
1261 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1263 $$ = append_ver_stringfileinfo ($1, $4, $6);
1265 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1267 $$ = append_ver_varfileinfo ($1, $5, $6);
1276 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1278 $$ = append_verval ($1, $3, $5);
1287 | vertrans cnumexpr cnumexpr
1289 $$ = append_vertrans ($1, $2, $3);
1293 /* A resource ID. */
1305 /* It seems that resource ID's are forced to upper case. */
1306 copy = xstrdup ($1);
1307 for (s = copy; *s != '\0'; s++)
1309 res_string_to_id (&$$, copy);
1314 /* A resource reference. */
1342 /* It seems that resource ID's are forced to upper case. */
1343 copy = xstrdup ($1);
1344 for (s = copy; *s != '\0'; s++)
1346 res_string_to_id (&$$, copy);
1351 /* Generic suboptions. These may appear before the BEGIN in any
1352 multiline statement. */
1357 memset (&$$, 0, sizeof (struct res_res_info));
1358 $$.language = language;
1359 /* FIXME: Is this the right default? */
1360 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE;
1362 | suboptions memflag
1365 $$.memflags |= $2.on;
1366 $$.memflags &=~ $2.off;
1368 | suboptions CHARACTERISTICS numexpr
1371 $$.characteristics = $3;
1373 | suboptions LANGUAGE numexpr cnumexpr
1376 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1378 | suboptions VERSIONK numexpr
1385 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1387 memflags_move_discard:
1390 memset (&$$, 0, sizeof (struct res_res_info));
1391 $$.language = language;
1392 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1394 | memflags_move_discard memflag
1397 $$.memflags |= $2.on;
1398 $$.memflags &=~ $2.off;
1402 /* Memory flags which default to MOVEABLE. */
1407 memset (&$$, 0, sizeof (struct res_res_info));
1408 $$.language = language;
1409 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE;
1411 | memflags_move memflag
1414 $$.memflags |= $2.on;
1415 $$.memflags &=~ $2.off;
1419 /* Memory flags. This returns a struct with two integers, because we
1420 sometimes want to set bits and we sometimes want to clear them. */
1425 $$.on = MEMFLAG_MOVEABLE;
1431 $$.off = MEMFLAG_MOVEABLE;
1435 $$.on = MEMFLAG_PURE;
1441 $$.off = MEMFLAG_PURE;
1445 $$.on = MEMFLAG_PRELOAD;
1451 $$.off = MEMFLAG_PRELOAD;
1455 $$.on = MEMFLAG_DISCARDABLE;
1473 /* A style expression. This changes the static variable STYLE. We do
1474 it this way because rc appears to permit a style to be set to
1476 WS_GROUP | NOT WS_TABSTOP
1477 to mean that a default of WS_TABSTOP should be removed. Anything
1478 which wants to accept a style must first set STYLE to the default
1479 value. The styleexpr nonterminal will change STYLE as specified by
1480 the user. Note that we do not accept arbitrary expressions here,
1481 just numbers separated by '|'. */
1492 | styleexpr '|' parennumber
1496 | styleexpr '|' NOT parennumber
1513 /* An optional expression with a leading comma. */
1526 /* An expression with a leading comma. */
1535 /* A possibly negated numeric expression. */
1544 /* A possibly negated expression with a size. */
1551 | '(' sizednumexpr ')'
1555 | '~' sizednumexpr %prec '~'
1558 $$.dword = $2.dword;
1560 | '-' sizednumexpr %prec NEG
1563 $$.dword = $2.dword;
1565 | sizednumexpr '*' sizednumexpr
1567 $$.val = $1.val * $3.val;
1568 $$.dword = $1.dword || $3.dword;
1570 | sizednumexpr '/' sizednumexpr
1572 $$.val = $1.val / $3.val;
1573 $$.dword = $1.dword || $3.dword;
1575 | sizednumexpr '%' sizednumexpr
1577 $$.val = $1.val % $3.val;
1578 $$.dword = $1.dword || $3.dword;
1580 | sizednumexpr '+' sizednumexpr
1582 $$.val = $1.val + $3.val;
1583 $$.dword = $1.dword || $3.dword;
1585 | sizednumexpr '-' sizednumexpr
1587 $$.val = $1.val - $3.val;
1588 $$.dword = $1.dword || $3.dword;
1590 | sizednumexpr '&' sizednumexpr
1592 $$.val = $1.val & $3.val;
1593 $$.dword = $1.dword || $3.dword;
1595 | sizednumexpr '^' sizednumexpr
1597 $$.val = $1.val ^ $3.val;
1598 $$.dword = $1.dword || $3.dword;
1600 | sizednumexpr '|' sizednumexpr
1602 $$.val = $1.val | $3.val;
1603 $$.dword = $1.dword || $3.dword;
1607 /* An expression with a leading comma which does not use unary
1617 /* An expression which does not use unary negation. */
1626 /* An expression which does not use unary negation. We separate unary
1627 negation to avoid parsing conflicts when two numeric expressions
1628 appear consecutively. */
1635 | '(' sizednumexpr ')'
1639 | '~' sizednumexpr %prec '~'
1642 $$.dword = $2.dword;
1644 | sizedposnumexpr '*' sizednumexpr
1646 $$.val = $1.val * $3.val;
1647 $$.dword = $1.dword || $3.dword;
1649 | sizedposnumexpr '/' sizednumexpr
1651 $$.val = $1.val / $3.val;
1652 $$.dword = $1.dword || $3.dword;
1654 | sizedposnumexpr '%' sizednumexpr
1656 $$.val = $1.val % $3.val;
1657 $$.dword = $1.dword || $3.dword;
1659 | sizedposnumexpr '+' sizednumexpr
1661 $$.val = $1.val + $3.val;
1662 $$.dword = $1.dword || $3.dword;
1664 | sizedposnumexpr '-' sizednumexpr
1666 $$.val = $1.val - $3.val;
1667 $$.dword = $1.dword || $3.dword;
1669 | sizedposnumexpr '&' sizednumexpr
1671 $$.val = $1.val & $3.val;
1672 $$.dword = $1.dword || $3.dword;
1674 | sizedposnumexpr '^' sizednumexpr
1676 $$.val = $1.val ^ $3.val;
1677 $$.dword = $1.dword || $3.dword;
1679 | sizedposnumexpr '|' sizednumexpr
1681 $$.val = $1.val | $3.val;
1682 $$.dword = $1.dword || $3.dword;
1688 /* Set the language from the command line. */
1691 rcparse_set_language (lang)