xref: /netbsd-src/external/gpl3/binutils.old/dist/binutils/mcparse.y (revision e992f068c547fd6e84b3f104dc2340adcc955732)
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