• 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/* xgettext RST backend.
2   Copyright (C) 2001-2003, 2005-2007 Free Software Foundation, Inc.
3
4   This file was written by Bruno Haible <haible@clisp.cons.org>, 2001.
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#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23/* Specification.  */
24#include "x-rst.h"
25
26#include <errno.h>
27#include <stdio.h>
28#include <stddef.h>
29#include <stdlib.h>
30
31#include "c-ctype.h"
32#include "message.h"
33#include "xgettext.h"
34#include "x-rst.h"
35#include "error.h"
36#include "error-progname.h"
37#include "xalloc.h"
38#include "gettext.h"
39
40#define _(s) gettext(s)
41
42/* RST stands for Resource String Table.
43
44   An RST file consists of several string definitions.  A string definition
45   starts at the beginning of a line and looks like this:
46       ModuleName.ConstName=StringExpression
47   A StringExpression consists of string pieces of the form 'xyz',
48   single characters of the form #nnn (decimal integer), and +
49   at the end of the line to designate continuation on the next line.
50   String definitions can be separated by blank lines or comment lines
51   beginning with '#'.
52
53   This backend attempts to be functionally equivalent to the 'rstconv'
54   program, part of the Free Pascal run time library, written by
55   Sebastian Guenther.  Except that the locations are output as
56   "ModuleName.ConstName", not "ModuleName:ConstName".
57 */
58
59void
60extract_rst (FILE *f,
61	     const char *real_filename, const char *logical_filename,
62	     flag_context_list_table_ty *flag_table,
63	     msgdomain_list_ty *mdlp)
64{
65  static char *buffer;
66  static int bufmax;
67  message_list_ty *mlp = mdlp->item[0]->messages;
68  int line_number;
69
70  line_number = 1;
71  for (;;)
72    {
73      int c;
74      int bufpos;
75      char *location;
76      char *msgid;
77      lex_pos_ty pos;
78
79      c = getc (f);
80      if (c == EOF)
81	break;
82
83      /* Ignore blank line.  */
84      if (c == '\n')
85	{
86	  line_number++;
87	  continue;
88	}
89
90      /* Ignore comment line.  */
91      if (c == '#')
92	{
93	  do
94	    c = getc (f);
95	  while (c != EOF && c != '\n');
96	  if (c == EOF)
97	    break;
98	  line_number++;
99	  continue;
100	}
101
102      /* Read ModuleName.ConstName.  */
103      bufpos = 0;
104      for (;;)
105	{
106	  if (c == EOF || c == '\n')
107	    {
108	      error_with_progname = false;
109	      error (EXIT_FAILURE, 0, _("%s:%d: invalid string definition"),
110		     logical_filename, line_number);
111	      error_with_progname = true;
112	    }
113	  if (bufpos >= bufmax)
114	    {
115	      bufmax = 2 * bufmax + 10;
116	      buffer = xrealloc (buffer, bufmax);
117	    }
118	  if (c == '=')
119	    break;
120	  buffer[bufpos++] = c;
121	  c = getc (f);
122	  if (c == EOF && ferror (f))
123	    goto bomb;
124	}
125      buffer[bufpos] = '\0';
126      location = xstrdup (buffer);
127
128      /* Read StringExpression.  */
129      bufpos = 0;
130      for (;;)
131	{
132	  c = getc (f);
133	  if (c == EOF)
134	    break;
135	  else if (c == '\n')
136	    {
137	      line_number++;
138	      break;
139	    }
140	  else if (c == '\'')
141	    {
142	      for (;;)
143		{
144		  c = getc (f);
145		  /* Embedded single quotes like 'abc''def' don't occur.
146		     See fpc-1.0.4/compiler/cresstr.pas.  */
147		  if (c == EOF || c == '\n' || c == '\'')
148		    break;
149		  if (bufpos >= bufmax)
150		    {
151		      bufmax = 2 * bufmax + 10;
152		      buffer = xrealloc (buffer, bufmax);
153		    }
154		  buffer[bufpos++] = c;
155		}
156	      if (c == EOF)
157		break;
158	      else if (c == '\n')
159		{
160		  line_number++;
161		  break;
162		}
163	    }
164	  else if (c == '#')
165	    {
166	      int n;
167	      c = getc (f);
168	      if (c == EOF && ferror (f))
169		goto bomb;
170	      if (c == EOF || !c_isdigit (c))
171		{
172		  error_with_progname = false;
173		  error (EXIT_FAILURE, 0, _("%s:%d: missing number after #"),
174			 logical_filename, line_number);
175		  error_with_progname = true;
176		}
177	      n = (c - '0');
178	      for (;;)
179		{
180		  c = getc (f);
181		  if (c == EOF || !c_isdigit (c))
182		    break;
183		  n = n * 10 + (c - '0');
184		}
185	      if (bufpos >= bufmax)
186		{
187		  bufmax = 2 * bufmax + 10;
188		  buffer = xrealloc (buffer, bufmax);
189		}
190	      buffer[bufpos++] = (unsigned char) n;
191	      if (c == EOF)
192		break;
193	      ungetc (c, f);
194	    }
195	  else if (c == '+')
196	    {
197	      c = getc (f);
198	      if (c == EOF)
199		break;
200	      if (c == '\n')
201		line_number++;
202	      else
203		ungetc (c, f);
204	    }
205	  else
206	    {
207	      error_with_progname = false;
208	      error (EXIT_FAILURE, 0, _("%s:%d: invalid string expression"),
209		     logical_filename, line_number);
210	      error_with_progname = true;
211	    }
212	}
213      if (bufpos >= bufmax)
214	{
215	  bufmax = 2 * bufmax + 10;
216	  buffer = xrealloc (buffer, bufmax);
217	}
218      buffer[bufpos] = '\0';
219      msgid = xstrdup (buffer);
220
221      pos.file_name = location;
222      pos.line_number = (size_t)(-1);
223
224      remember_a_message (mlp, NULL, msgid, null_context, &pos, NULL);
225
226      /* Here c is the last read character: EOF or '\n'.  */
227      if (c == EOF)
228	break;
229    }
230
231  if (ferror (f))
232    {
233    bomb:
234      error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
235	     real_filename);
236    }
237}
238