PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/mingw-w64-v2.0.999/binutils/src/binutils/rcparse.y

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