175fd0b74Schristos %{ /* mcparse.y -- parser for Windows mc files 2*e992f068Schristos Copyright (C) 2007-2022 Free Software Foundation, Inc. 375fd0b74Schristos 475fd0b74Schristos Parser for Windows mc files 575fd0b74Schristos Written by Kai Tietz, Onevision. 675fd0b74Schristos 775fd0b74Schristos This file is part of GNU Binutils. 875fd0b74Schristos 975fd0b74Schristos This program is free software; you can redistribute it and/or modify 1075fd0b74Schristos it under the terms of the GNU General Public License as published by 1175fd0b74Schristos the Free Software Foundation; either version 3 of the License, or 1275fd0b74Schristos (at your option) any later version. 1375fd0b74Schristos 1475fd0b74Schristos This program is distributed in the hope that it will be useful, 1575fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1675fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1775fd0b74Schristos GNU General Public License for more details. 1875fd0b74Schristos 1975fd0b74Schristos You should have received a copy of the GNU General Public License 2075fd0b74Schristos along with this program; if not, write to the Free Software 2175fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 2275fd0b74Schristos 02110-1301, USA. */ 2375fd0b74Schristos 2475fd0b74Schristos /* This is a parser for Windows rc files. It is based on the parser 2575fd0b74Schristos by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */ 2675fd0b74Schristos 2775fd0b74Schristos #include "sysdep.h" 2875fd0b74Schristos #include "bfd.h" 2975fd0b74Schristos #include "bucomm.h" 3075fd0b74Schristos #include "libiberty.h" 3175fd0b74Schristos #include "windmc.h" 3275fd0b74Schristos #include "safe-ctype.h" 3375fd0b74Schristos 3475fd0b74Schristos static rc_uint_type mc_last_id = 0; 3575fd0b74Schristos static rc_uint_type mc_sefa_val = 0; 3675fd0b74Schristos static unichar *mc_last_symbol = NULL; 3775fd0b74Schristos static const mc_keyword *mc_cur_severity = NULL; 3875fd0b74Schristos static const mc_keyword *mc_cur_facility = NULL; 3975fd0b74Schristos static mc_node *cur_node = NULL; 4075fd0b74Schristos 4175fd0b74Schristos %} 4275fd0b74Schristos 4375fd0b74Schristos %union 4475fd0b74Schristos { 4575fd0b74Schristos rc_uint_type ival; 4675fd0b74Schristos unichar *ustr; 4775fd0b74Schristos const mc_keyword *tok; 4875fd0b74Schristos mc_node *nod; 4975fd0b74Schristos }; 5075fd0b74Schristos 5175fd0b74Schristos %start input 5275fd0b74Schristos 5375fd0b74Schristos %token NL 5475fd0b74Schristos %token<ustr> MCIDENT MCFILENAME MCLINE MCCOMMENT 5575fd0b74Schristos %token<tok> MCTOKEN 5675fd0b74Schristos %token MCENDLINE 5775fd0b74Schristos %token MCLANGUAGENAMES MCFACILITYNAMES MCSEVERITYNAMES MCOUTPUTBASE MCMESSAGEIDTYPEDEF 5875fd0b74Schristos %token MCLANGUAGE MCMESSAGEID MCSEVERITY MCFACILITY MCSYMBOLICNAME 5975fd0b74Schristos %token <ival> MCNUMBER 6075fd0b74Schristos 6175fd0b74Schristos %type<ival> id vid sefasy_def 6275fd0b74Schristos %type<ustr> alias_name token lines comments 6375fd0b74Schristos %type<tok> lang 6475fd0b74Schristos 6575fd0b74Schristos %% 6675fd0b74Schristos input: entities 6775fd0b74Schristos ; 6875fd0b74Schristos 6975fd0b74Schristos entities: 7075fd0b74Schristos /* empty */ 7175fd0b74Schristos | entities entity 7275fd0b74Schristos ; 7375fd0b74Schristos entity: global_section 7475fd0b74Schristos | message 7575fd0b74Schristos | comments 7675fd0b74Schristos { 7775fd0b74Schristos cur_node = mc_add_node (); 7875fd0b74Schristos cur_node->user_text = $1; 7975fd0b74Schristos } 8075fd0b74Schristos | error { mc_fatal ("syntax error"); } 8175fd0b74Schristos ; 8275fd0b74Schristos 8375fd0b74Schristos global_section: 8475fd0b74Schristos MCSEVERITYNAMES '=' '(' severitymaps ')' 8575fd0b74Schristos | MCSEVERITYNAMES '=' '(' severitymaps error { mc_fatal ("missing ')' in SeverityNames"); } 8675fd0b74Schristos | MCSEVERITYNAMES '=' error { mc_fatal ("missing '(' in SeverityNames"); } 8775fd0b74Schristos | MCSEVERITYNAMES error { mc_fatal ("missing '=' for SeverityNames"); } 8875fd0b74Schristos | MCLANGUAGENAMES '=' '(' langmaps ')' 8975fd0b74Schristos | MCLANGUAGENAMES '=' '(' langmaps error { mc_fatal ("missing ')' in LanguageNames"); } 9075fd0b74Schristos | MCLANGUAGENAMES '=' error { mc_fatal ("missing '(' in LanguageNames"); } 9175fd0b74Schristos | MCLANGUAGENAMES error { mc_fatal ("missing '=' for LanguageNames"); } 9275fd0b74Schristos | MCFACILITYNAMES '=' '(' facilitymaps ')' 9375fd0b74Schristos | MCFACILITYNAMES '=' '(' facilitymaps error { mc_fatal ("missing ')' in FacilityNames"); } 9475fd0b74Schristos | MCFACILITYNAMES '=' error { mc_fatal ("missing '(' in FacilityNames"); } 9575fd0b74Schristos | MCFACILITYNAMES error { mc_fatal ("missing '=' for FacilityNames"); } 9675fd0b74Schristos | MCOUTPUTBASE '=' MCNUMBER 9775fd0b74Schristos { 9875fd0b74Schristos if ($3 != 10 && $3 != 16) 9975fd0b74Schristos mc_fatal ("OutputBase allows 10 or 16 as value"); 10075fd0b74Schristos mcset_out_values_are_decimal = ($3 == 10 ? 1 : 0); 10175fd0b74Schristos } 10275fd0b74Schristos | MCMESSAGEIDTYPEDEF '=' MCIDENT 10375fd0b74Schristos { 10475fd0b74Schristos mcset_msg_id_typedef = $3; 10575fd0b74Schristos } 10675fd0b74Schristos | MCMESSAGEIDTYPEDEF '=' error 10775fd0b74Schristos { 10875fd0b74Schristos mc_fatal ("MessageIdTypedef expects an identifier"); 10975fd0b74Schristos } 11075fd0b74Schristos | MCMESSAGEIDTYPEDEF error 11175fd0b74Schristos { 11275fd0b74Schristos mc_fatal ("missing '=' for MessageIdTypedef"); 11375fd0b74Schristos } 11475fd0b74Schristos ; 11575fd0b74Schristos 11675fd0b74Schristos severitymaps: 11775fd0b74Schristos severitymap 11875fd0b74Schristos | severitymaps severitymap 11975fd0b74Schristos | error { mc_fatal ("severity ident missing"); } 12075fd0b74Schristos ; 12175fd0b74Schristos 12275fd0b74Schristos severitymap: 12375fd0b74Schristos token '=' MCNUMBER alias_name 12475fd0b74Schristos { 12575fd0b74Schristos mc_add_keyword ($1, MCTOKEN, "severity", $3, $4); 12675fd0b74Schristos } 12775fd0b74Schristos | token '=' error { mc_fatal ("severity number missing"); } 12875fd0b74Schristos | token error { mc_fatal ("severity missing '='"); } 12975fd0b74Schristos ; 13075fd0b74Schristos 13175fd0b74Schristos facilitymaps: 13275fd0b74Schristos facilitymap 13375fd0b74Schristos | facilitymaps facilitymap 13475fd0b74Schristos | error { mc_fatal ("missing ident in FacilityNames"); } 13575fd0b74Schristos ; 13675fd0b74Schristos 13775fd0b74Schristos facilitymap: 13875fd0b74Schristos token '=' MCNUMBER alias_name 13975fd0b74Schristos { 14075fd0b74Schristos mc_add_keyword ($1, MCTOKEN, "facility", $3, $4); 14175fd0b74Schristos } 14275fd0b74Schristos | token '=' error { mc_fatal ("facility number missing"); } 14375fd0b74Schristos | token error { mc_fatal ("facility missing '='"); } 14475fd0b74Schristos ; 14575fd0b74Schristos 14675fd0b74Schristos langmaps: 14775fd0b74Schristos langmap 14875fd0b74Schristos | langmaps langmap 14975fd0b74Schristos | error { mc_fatal ("missing ident in LanguageNames"); } 15075fd0b74Schristos ; 15175fd0b74Schristos 15275fd0b74Schristos langmap: 15375fd0b74Schristos token '=' MCNUMBER lex_want_filename ':' MCFILENAME 15475fd0b74Schristos { 15575fd0b74Schristos mc_add_keyword ($1, MCTOKEN, "language", $3, $6); 15675fd0b74Schristos } 15775fd0b74Schristos | token '=' MCNUMBER lex_want_filename ':' error { mc_fatal ("missing filename in LanguageNames"); } 15875fd0b74Schristos | token '=' MCNUMBER error { mc_fatal ("missing ':' in LanguageNames"); } 15975fd0b74Schristos | token '=' error { mc_fatal ("missing language code in LanguageNames"); } 16075fd0b74Schristos | token error { mc_fatal ("missing '=' for LanguageNames"); } 16175fd0b74Schristos ; 16275fd0b74Schristos 16375fd0b74Schristos alias_name: 16475fd0b74Schristos /* empty */ 16575fd0b74Schristos { 16675fd0b74Schristos $$ = NULL; 16775fd0b74Schristos } 16875fd0b74Schristos | ':' MCIDENT 16975fd0b74Schristos { 17075fd0b74Schristos $$ = $2; 17175fd0b74Schristos } 17275fd0b74Schristos | ':' error { mc_fatal ("illegal token in identifier"); $$ = NULL; } 17375fd0b74Schristos ; 17475fd0b74Schristos 17575fd0b74Schristos message: 17675fd0b74Schristos id sefasy_def 17775fd0b74Schristos { 17875fd0b74Schristos cur_node = mc_add_node (); 17975fd0b74Schristos cur_node->symbol = mc_last_symbol; 18075fd0b74Schristos cur_node->facility = mc_cur_facility; 18175fd0b74Schristos cur_node->severity = mc_cur_severity; 18275fd0b74Schristos cur_node->id = ($1 & 0xffffUL); 18375fd0b74Schristos cur_node->vid = ($1 & 0xffffUL) | mc_sefa_val; 184*e992f068Schristos cur_node->id_typecast = mcset_msg_id_typedef; 18575fd0b74Schristos mc_last_id = $1; 18675fd0b74Schristos } 18775fd0b74Schristos lang_entities 18875fd0b74Schristos ; 18975fd0b74Schristos 19075fd0b74Schristos id: MCMESSAGEID '=' vid { $$ = $3; } 19175fd0b74Schristos | MCMESSAGEID '=' error { mc_fatal ("missing number in MessageId"); $$ = 0; } 19275fd0b74Schristos | MCMESSAGEID error { mc_fatal ("missing '=' for MessageId"); $$ = 0; } 19375fd0b74Schristos ; 19475fd0b74Schristos 19575fd0b74Schristos vid: /* empty */ 19675fd0b74Schristos { 19775fd0b74Schristos $$ = ++mc_last_id; 19875fd0b74Schristos } 19975fd0b74Schristos | MCNUMBER 20075fd0b74Schristos { 20175fd0b74Schristos $$ = $1; 20275fd0b74Schristos } 20375fd0b74Schristos | '+' MCNUMBER 20475fd0b74Schristos { 20575fd0b74Schristos $$ = mc_last_id + $2; 20675fd0b74Schristos } 20775fd0b74Schristos | '+' error { mc_fatal ("missing number after MessageId '+'"); } 20875fd0b74Schristos ; 20975fd0b74Schristos 21075fd0b74Schristos sefasy_def: 21175fd0b74Schristos /* empty */ 21275fd0b74Schristos { 21375fd0b74Schristos $$ = 0; 21475fd0b74Schristos mc_sefa_val = (mcset_custom_bit ? 1 : 0) << 29; 21575fd0b74Schristos mc_last_symbol = NULL; 21675fd0b74Schristos mc_cur_severity = NULL; 21775fd0b74Schristos mc_cur_facility = NULL; 21875fd0b74Schristos } 21975fd0b74Schristos | sefasy_def severity 22075fd0b74Schristos { 22175fd0b74Schristos if ($1 & 1) 22275fd0b74Schristos mc_warn (_("duplicate definition of Severity")); 22375fd0b74Schristos $$ = $1 | 1; 22475fd0b74Schristos } 22575fd0b74Schristos | sefasy_def facility 22675fd0b74Schristos { 22775fd0b74Schristos if ($1 & 2) 22875fd0b74Schristos mc_warn (_("duplicate definition of Facility")); 22975fd0b74Schristos $$ = $1 | 2; 23075fd0b74Schristos } 23175fd0b74Schristos | sefasy_def symbol 23275fd0b74Schristos { 23375fd0b74Schristos if ($1 & 4) 23475fd0b74Schristos mc_warn (_("duplicate definition of SymbolicName")); 23575fd0b74Schristos $$ = $1 | 4; 23675fd0b74Schristos } 23775fd0b74Schristos ; 23875fd0b74Schristos 23975fd0b74Schristos severity: MCSEVERITY '=' MCTOKEN 24075fd0b74Schristos { 24175fd0b74Schristos mc_sefa_val &= ~ (0x3UL << 30); 24275fd0b74Schristos mc_sefa_val |= (($3->nval & 0x3UL) << 30); 24375fd0b74Schristos mc_cur_severity = $3; 24475fd0b74Schristos } 24575fd0b74Schristos ; 24675fd0b74Schristos 24775fd0b74Schristos facility: MCFACILITY '=' MCTOKEN 24875fd0b74Schristos { 24975fd0b74Schristos mc_sefa_val &= ~ (0xfffUL << 16); 25075fd0b74Schristos mc_sefa_val |= (($3->nval & 0xfffUL) << 16); 25175fd0b74Schristos mc_cur_facility = $3; 25275fd0b74Schristos } 25375fd0b74Schristos ; 25475fd0b74Schristos 25575fd0b74Schristos symbol: MCSYMBOLICNAME '=' MCIDENT 25675fd0b74Schristos { 25775fd0b74Schristos mc_last_symbol = $3; 25875fd0b74Schristos } 25975fd0b74Schristos ; 26075fd0b74Schristos 26175fd0b74Schristos lang_entities: 26275fd0b74Schristos lang_entity 26375fd0b74Schristos | lang_entities lang_entity 26475fd0b74Schristos ; 26575fd0b74Schristos 26675fd0b74Schristos lang_entity: 26775fd0b74Schristos lang lex_want_line lines MCENDLINE 26875fd0b74Schristos { 26975fd0b74Schristos mc_node_lang *h; 27075fd0b74Schristos h = mc_add_node_lang (cur_node, $1, cur_node->vid); 27175fd0b74Schristos h->message = $3; 27275fd0b74Schristos if (mcset_max_message_length != 0 && unichar_len (h->message) > mcset_max_message_length) 27375fd0b74Schristos mc_warn ("message length to long"); 27475fd0b74Schristos } 27575fd0b74Schristos ; 27675fd0b74Schristos 27775fd0b74Schristos lines: MCLINE 27875fd0b74Schristos { 27975fd0b74Schristos $$ = $1; 28075fd0b74Schristos } 28175fd0b74Schristos | lines MCLINE 28275fd0b74Schristos { 28375fd0b74Schristos unichar *h; 28475fd0b74Schristos rc_uint_type l1,l2; 28575fd0b74Schristos l1 = unichar_len ($1); 28675fd0b74Schristos l2 = unichar_len ($2); 28775fd0b74Schristos h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); 28875fd0b74Schristos if (l1) memcpy (h, $1, l1 * sizeof (unichar)); 28975fd0b74Schristos if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar)); 29075fd0b74Schristos h[l1 + l2] = 0; 29175fd0b74Schristos $$ = h; 29275fd0b74Schristos } 29375fd0b74Schristos | error { mc_fatal ("missing end of message text"); $$ = NULL; } 29475fd0b74Schristos | lines error { mc_fatal ("missing end of message text"); $$ = $1; } 29575fd0b74Schristos ; 29675fd0b74Schristos 29775fd0b74Schristos comments: MCCOMMENT { $$ = $1; } 29875fd0b74Schristos | comments MCCOMMENT 29975fd0b74Schristos { 30075fd0b74Schristos unichar *h; 30175fd0b74Schristos rc_uint_type l1,l2; 30275fd0b74Schristos l1 = unichar_len ($1); 30375fd0b74Schristos l2 = unichar_len ($2); 30475fd0b74Schristos h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); 30575fd0b74Schristos if (l1) memcpy (h, $1, l1 * sizeof (unichar)); 30675fd0b74Schristos if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar)); 30775fd0b74Schristos h[l1 + l2] = 0; 30875fd0b74Schristos $$ = h; 30975fd0b74Schristos } 31075fd0b74Schristos ; 31175fd0b74Schristos 31275fd0b74Schristos lang: MCLANGUAGE lex_want_nl '=' MCTOKEN NL 31375fd0b74Schristos { 31475fd0b74Schristos $$ = $4; 31575fd0b74Schristos } 31675fd0b74Schristos | MCLANGUAGE lex_want_nl '=' MCIDENT NL 31775fd0b74Schristos { 31875fd0b74Schristos $$ = NULL; 31975fd0b74Schristos mc_fatal (_("undeclared language identifier")); 32075fd0b74Schristos } 32175fd0b74Schristos | MCLANGUAGE lex_want_nl '=' token error 32275fd0b74Schristos { 32375fd0b74Schristos $$ = NULL; 32475fd0b74Schristos mc_fatal ("missing newline after Language"); 32575fd0b74Schristos } 32675fd0b74Schristos | MCLANGUAGE lex_want_nl '=' error 32775fd0b74Schristos { 32875fd0b74Schristos $$ = NULL; 32975fd0b74Schristos mc_fatal ("missing ident for Language"); 33075fd0b74Schristos } 33175fd0b74Schristos | MCLANGUAGE error 33275fd0b74Schristos { 33375fd0b74Schristos $$ = NULL; 33475fd0b74Schristos mc_fatal ("missing '=' for Language"); 33575fd0b74Schristos } 33675fd0b74Schristos ; 33775fd0b74Schristos 33875fd0b74Schristos token: MCIDENT { $$ = $1; } 33975fd0b74Schristos | MCTOKEN { $$ = $1->usz; } 34075fd0b74Schristos ; 34175fd0b74Schristos 34275fd0b74Schristos lex_want_nl: 34375fd0b74Schristos /* Empty */ { mclex_want_nl = 1; } 34475fd0b74Schristos ; 34575fd0b74Schristos 34675fd0b74Schristos lex_want_line: 34775fd0b74Schristos /* Empty */ { mclex_want_line = 1; } 34875fd0b74Schristos ; 34975fd0b74Schristos 35075fd0b74Schristos lex_want_filename: 35175fd0b74Schristos /* Empty */ { mclex_want_filename = 1; } 35275fd0b74Schristos ; 35375fd0b74Schristos 35475fd0b74Schristos %% 35575fd0b74Schristos 35675fd0b74Schristos /* Something else. */ 357