• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/gettext-0.17/gettext-tools/src/
1/* GNU gettext - internationalization aids
2   Copyright (C) 1995-1996, 1998, 2000-2001, 2003, 2005-2006 Free Software Foundation, Inc.
3
4   This file was written by Peter Miller <pmiller@agso.gov.au>
5
6   This program is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
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
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19%{
20#ifdef HAVE_CONFIG_H
21# include "config.h"
22#endif
23
24/* Specification.  */
25#include "po-gram.h"
26
27#include <stdbool.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "str-list.h"
33#include "po-lex.h"
34#include "po-charset.h"
35#include "error.h"
36#include "xalloc.h"
37#include "gettext.h"
38#include "read-catalog-abstract.h"
39
40#define _(str) gettext (str)
41
42/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
43   as well as gratuitiously global symbol names, so we can have multiple
44   yacc generated parsers in the same program.  Note that these are only
45   the variables produced by yacc.  If other parser generators (bison,
46   byacc, etc) produce additional global names that conflict at link time,
47   then those parser generators need to be fixed instead of adding those
48   names to this list. */
49
50#define yymaxdepth po_gram_maxdepth
51#define yyparse po_gram_parse
52#define yylex   po_gram_lex
53#define yyerror po_gram_error
54#define yylval  po_gram_lval
55#define yychar  po_gram_char
56#define yydebug po_gram_debug
57#define yypact  po_gram_pact
58#define yyr1    po_gram_r1
59#define yyr2    po_gram_r2
60#define yydef   po_gram_def
61#define yychk   po_gram_chk
62#define yypgo   po_gram_pgo
63#define yyact   po_gram_act
64#define yyexca  po_gram_exca
65#define yyerrflag po_gram_errflag
66#define yynerrs po_gram_nerrs
67#define yyps    po_gram_ps
68#define yypv    po_gram_pv
69#define yys     po_gram_s
70#define yy_yys  po_gram_yys
71#define yystate po_gram_state
72#define yytmp   po_gram_tmp
73#define yyv     po_gram_v
74#define yy_yyv  po_gram_yyv
75#define yyval   po_gram_val
76#define yylloc  po_gram_lloc
77#define yyreds  po_gram_reds          /* With YYDEBUG defined */
78#define yytoks  po_gram_toks          /* With YYDEBUG defined */
79#define yylhs   po_gram_yylhs
80#define yylen   po_gram_yylen
81#define yydefred po_gram_yydefred
82#define yydgoto po_gram_yydgoto
83#define yysindex po_gram_yysindex
84#define yyrindex po_gram_yyrindex
85#define yygindex po_gram_yygindex
86#define yytable  po_gram_yytable
87#define yycheck  po_gram_yycheck
88
89static long plural_counter;
90
91#define check_obsolete(value1,value2) \
92  if ((value1).obsolete != (value2).obsolete) \
93    po_gram_error_at_line (&(value2).pos, _("inconsistent use of #~"));
94
95static inline void
96do_callback_message (char *msgctxt,
97		     char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
98		     char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
99		     char *prev_msgctxt,
100		     char *prev_msgid, char *prev_msgid_plural,
101		     bool obsolete)
102{
103  /* Test for header entry.  Ignore fuzziness of the header entry.  */
104  if (msgctxt == NULL && msgid[0] == '\0' && !obsolete)
105    po_lex_charset_set (msgstr, gram_pos.file_name);
106
107  po_callback_message (msgctxt,
108		       msgid, msgid_pos, msgid_plural,
109		       msgstr, msgstr_len, msgstr_pos,
110		       prev_msgctxt, prev_msgid, prev_msgid_plural,
111		       false, obsolete);
112}
113
114#define free_message_intro(value) \
115  if ((value).prev_ctxt != NULL)	\
116    free ((value).prev_ctxt);		\
117  if ((value).prev_id != NULL)		\
118    free ((value).prev_id);		\
119  if ((value).prev_id_plural != NULL)	\
120    free ((value).prev_id_plural);	\
121  if ((value).ctxt != NULL)		\
122    free ((value).ctxt);
123
124%}
125
126%token	COMMENT
127%token	DOMAIN
128%token	JUNK
129%token	PREV_MSGCTXT
130%token	PREV_MSGID
131%token	PREV_MSGID_PLURAL
132%token	PREV_STRING
133%token	MSGCTXT
134%token	MSGID
135%token	MSGID_PLURAL
136%token	MSGSTR
137%token	NAME
138%token	'[' ']'
139%token	NUMBER
140%token	STRING
141
142%union
143{
144  struct { char *string; lex_pos_ty pos; bool obsolete; } string;
145  struct { string_list_ty stringlist; lex_pos_ty pos; bool obsolete; } stringlist;
146  struct { long number; lex_pos_ty pos; bool obsolete; } number;
147  struct { lex_pos_ty pos; bool obsolete; } pos;
148  struct { char *ctxt; char *id; char *id_plural; lex_pos_ty pos; bool obsolete; } prev;
149  struct { char *prev_ctxt; char *prev_id; char *prev_id_plural; char *ctxt; lex_pos_ty pos; bool obsolete; } message_intro;
150  struct { struct msgstr_def rhs; lex_pos_ty pos; bool obsolete; } rhs;
151}
152
153%type <string> STRING PREV_STRING COMMENT NAME
154               msg_intro prev_msg_intro msgid_pluralform prev_msgid_pluralform
155%type <stringlist> string_list prev_string_list
156%type <number> NUMBER
157%type <pos> DOMAIN
158            PREV_MSGCTXT PREV_MSGID PREV_MSGID_PLURAL
159            MSGCTXT MSGID MSGID_PLURAL MSGSTR '[' ']'
160%type <prev> prev
161%type <message_intro> message_intro
162%type <rhs> pluralform pluralform_list
163
164%right MSGSTR
165
166%%
167
168po_file
169	: /* empty */
170	| po_file comment
171	| po_file domain
172	| po_file message
173	| po_file error
174	;
175
176
177comment
178	: COMMENT
179		{
180		  po_callback_comment_dispatcher ($1.string);
181		}
182	;
183
184
185domain
186	: DOMAIN STRING
187		{
188		   po_callback_domain ($2.string);
189		}
190	;
191
192
193message
194	: message_intro string_list MSGSTR string_list
195		{
196		  char *string2 = string_list_concat_destroy (&$2.stringlist);
197		  char *string4 = string_list_concat_destroy (&$4.stringlist);
198
199		  check_obsolete ($1, $2);
200		  check_obsolete ($1, $3);
201		  check_obsolete ($1, $4);
202		  if (!$1.obsolete || pass_obsolete_entries)
203		    do_callback_message ($1.ctxt, string2, &$1.pos, NULL,
204					 string4, strlen (string4) + 1, &$3.pos,
205					 $1.prev_ctxt,
206					 $1.prev_id, $1.prev_id_plural,
207					 $1.obsolete);
208		  else
209		    {
210		      free_message_intro ($1);
211		      free (string2);
212		      free (string4);
213		    }
214		}
215	| message_intro string_list msgid_pluralform pluralform_list
216		{
217		  char *string2 = string_list_concat_destroy (&$2.stringlist);
218
219		  check_obsolete ($1, $2);
220		  check_obsolete ($1, $3);
221		  check_obsolete ($1, $4);
222		  if (!$1.obsolete || pass_obsolete_entries)
223		    do_callback_message ($1.ctxt, string2, &$1.pos, $3.string,
224					 $4.rhs.msgstr, $4.rhs.msgstr_len, &$4.pos,
225					 $1.prev_ctxt,
226					 $1.prev_id, $1.prev_id_plural,
227					 $1.obsolete);
228		  else
229		    {
230		      free_message_intro ($1);
231		      free (string2);
232		      free ($3.string);
233		      free ($4.rhs.msgstr);
234		    }
235		}
236	| message_intro string_list msgid_pluralform
237		{
238		  check_obsolete ($1, $2);
239		  check_obsolete ($1, $3);
240		  po_gram_error_at_line (&$1.pos, _("missing `msgstr[]' section"));
241		  free_message_intro ($1);
242		  string_list_destroy (&$2.stringlist);
243		  free ($3.string);
244		}
245	| message_intro string_list pluralform_list
246		{
247		  check_obsolete ($1, $2);
248		  check_obsolete ($1, $3);
249		  po_gram_error_at_line (&$1.pos, _("missing `msgid_plural' section"));
250		  free_message_intro ($1);
251		  string_list_destroy (&$2.stringlist);
252		  free ($3.rhs.msgstr);
253		}
254	| message_intro string_list
255		{
256		  check_obsolete ($1, $2);
257		  po_gram_error_at_line (&$1.pos, _("missing `msgstr' section"));
258		  free_message_intro ($1);
259		  string_list_destroy (&$2.stringlist);
260		}
261	;
262
263
264message_intro
265	: msg_intro
266		{
267		  $$.prev_ctxt = NULL;
268		  $$.prev_id = NULL;
269		  $$.prev_id_plural = NULL;
270		  $$.ctxt = $1.string;
271		  $$.pos = $1.pos;
272		  $$.obsolete = $1.obsolete;
273		}
274	| prev msg_intro
275		{
276		  check_obsolete ($1, $2);
277		  $$.prev_ctxt = $1.ctxt;
278		  $$.prev_id = $1.id;
279		  $$.prev_id_plural = $1.id_plural;
280		  $$.ctxt = $2.string;
281		  $$.pos = $2.pos;
282		  $$.obsolete = $2.obsolete;
283		}
284	;
285
286
287prev
288	: prev_msg_intro prev_string_list
289		{
290		  check_obsolete ($1, $2);
291		  $$.ctxt = $1.string;
292		  $$.id = string_list_concat_destroy (&$2.stringlist);
293		  $$.id_plural = NULL;
294		  $$.pos = $1.pos;
295		  $$.obsolete = $1.obsolete;
296		}
297	| prev_msg_intro prev_string_list prev_msgid_pluralform
298		{
299		  check_obsolete ($1, $2);
300		  check_obsolete ($1, $3);
301		  $$.ctxt = $1.string;
302		  $$.id = string_list_concat_destroy (&$2.stringlist);
303		  $$.id_plural = $3.string;
304		  $$.pos = $1.pos;
305		  $$.obsolete = $1.obsolete;
306		}
307	;
308
309
310msg_intro
311	: MSGID
312		{
313		  $$.string = NULL;
314		  $$.pos = $1.pos;
315		  $$.obsolete = $1.obsolete;
316		}
317	| MSGCTXT string_list MSGID
318		{
319		  check_obsolete ($1, $2);
320		  check_obsolete ($1, $3);
321		  $$.string = string_list_concat_destroy (&$2.stringlist);
322		  $$.pos = $3.pos;
323		  $$.obsolete = $3.obsolete;
324		}
325	;
326
327prev_msg_intro
328	: PREV_MSGID
329		{
330		  $$.string = NULL;
331		  $$.pos = $1.pos;
332		  $$.obsolete = $1.obsolete;
333		}
334	| PREV_MSGCTXT prev_string_list PREV_MSGID
335		{
336		  check_obsolete ($1, $2);
337		  check_obsolete ($1, $3);
338		  $$.string = string_list_concat_destroy (&$2.stringlist);
339		  $$.pos = $3.pos;
340		  $$.obsolete = $3.obsolete;
341		}
342	;
343
344
345msgid_pluralform
346	: MSGID_PLURAL string_list
347		{
348		  check_obsolete ($1, $2);
349		  plural_counter = 0;
350		  $$.string = string_list_concat_destroy (&$2.stringlist);
351		  $$.pos = $1.pos;
352		  $$.obsolete = $1.obsolete;
353		}
354	;
355
356prev_msgid_pluralform
357	: PREV_MSGID_PLURAL prev_string_list
358		{
359		  check_obsolete ($1, $2);
360		  $$.string = string_list_concat_destroy (&$2.stringlist);
361		  $$.pos = $1.pos;
362		  $$.obsolete = $1.obsolete;
363		}
364	;
365
366
367pluralform_list
368	: pluralform
369		{
370		  $$ = $1;
371		}
372	| pluralform_list pluralform
373		{
374		  check_obsolete ($1, $2);
375		  $$.rhs.msgstr = XNMALLOC ($1.rhs.msgstr_len + $2.rhs.msgstr_len, char);
376		  memcpy ($$.rhs.msgstr, $1.rhs.msgstr, $1.rhs.msgstr_len);
377		  memcpy ($$.rhs.msgstr + $1.rhs.msgstr_len, $2.rhs.msgstr, $2.rhs.msgstr_len);
378		  $$.rhs.msgstr_len = $1.rhs.msgstr_len + $2.rhs.msgstr_len;
379		  free ($1.rhs.msgstr);
380		  free ($2.rhs.msgstr);
381		  $$.pos = $1.pos;
382		  $$.obsolete = $1.obsolete;
383		}
384	;
385
386pluralform
387	: MSGSTR '[' NUMBER ']' string_list
388		{
389		  check_obsolete ($1, $2);
390		  check_obsolete ($1, $3);
391		  check_obsolete ($1, $4);
392		  check_obsolete ($1, $5);
393		  if ($3.number != plural_counter)
394		    {
395		      if (plural_counter == 0)
396			po_gram_error_at_line (&$1.pos, _("first plural form has nonzero index"));
397		      else
398			po_gram_error_at_line (&$1.pos, _("plural form has wrong index"));
399		    }
400		  plural_counter++;
401		  $$.rhs.msgstr = string_list_concat_destroy (&$5.stringlist);
402		  $$.rhs.msgstr_len = strlen ($$.rhs.msgstr) + 1;
403		  $$.pos = $1.pos;
404		  $$.obsolete = $1.obsolete;
405		}
406	;
407
408
409string_list
410	: STRING
411		{
412		  string_list_init (&$$.stringlist);
413		  string_list_append (&$$.stringlist, $1.string);
414		  $$.pos = $1.pos;
415		  $$.obsolete = $1.obsolete;
416		}
417	| string_list STRING
418		{
419		  check_obsolete ($1, $2);
420		  $$.stringlist = $1.stringlist;
421		  string_list_append (&$$.stringlist, $2.string);
422		  $$.pos = $1.pos;
423		  $$.obsolete = $1.obsolete;
424		}
425	;
426
427prev_string_list
428	: PREV_STRING
429		{
430		  string_list_init (&$$.stringlist);
431		  string_list_append (&$$.stringlist, $1.string);
432		  $$.pos = $1.pos;
433		  $$.obsolete = $1.obsolete;
434		}
435	| prev_string_list PREV_STRING
436		{
437		  check_obsolete ($1, $2);
438		  $$.stringlist = $1.stringlist;
439		  string_list_append (&$$.stringlist, $2.string);
440		  $$.pos = $1.pos;
441		  $$.obsolete = $1.obsolete;
442		}
443	;
444