No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / x-rst.c
blob20eef828f542238ae75601c436a8f08c0aefd617
1 /* xgettext RST backend.
2 Copyright (C) 2001-2003 Free Software Foundation, Inc.
4 This file was written by Bruno Haible <haible@clisp.cons.org>, 2001.
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 2, or (at your option)
9 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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include <ctype.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stddef.h>
29 #include "message.h"
30 #include "xgettext.h"
31 #include "x-rst.h"
32 #include "error.h"
33 #include "error-progname.h"
34 #include "xalloc.h"
35 #include "exit.h"
36 #include "gettext.h"
38 #define _(s) gettext(s)
40 /* RST stands for Resource String Table.
42 An RST file consists of several string definitions. A string definition
43 starts at the beginning of a line and looks like this:
44 ModuleName.ConstName=StringExpression
45 A StringExpression consists of string pieces of the form 'xyz',
46 single characters of the form #nnn (decimal integer), and +
47 at the end of the line to designate continuation on the next line.
48 String definitions can be separated by blank lines or comment lines
49 beginning with '#'.
51 This backend attempts to be functionally equivalent to the 'rstconv'
52 program, part of the Free Pascal run time library, written by
53 Sebastian Guenther. Except that the locations are output as
54 "ModuleName.ConstName", not "ModuleName:ConstName".
57 void
58 extract_rst (FILE *f,
59 const char *real_filename, const char *logical_filename,
60 flag_context_list_table_ty *flag_table,
61 msgdomain_list_ty *mdlp)
63 static char *buffer;
64 static int bufmax;
65 message_list_ty *mlp = mdlp->item[0]->messages;
66 int line_number;
68 line_number = 1;
69 for (;;)
71 int c;
72 int bufpos;
73 char *location;
74 char *msgid;
75 lex_pos_ty pos;
77 c = getc (f);
78 if (c == EOF)
79 break;
81 /* Ignore blank line. */
82 if (c == '\n')
84 line_number++;
85 continue;
88 /* Ignore comment line. */
89 if (c == '#')
92 c = getc (f);
93 while (c != EOF && c != '\n');
94 if (c == EOF)
95 break;
96 line_number++;
97 continue;
100 /* Read ModuleName.ConstName. */
101 bufpos = 0;
102 for (;;)
104 if (c == EOF || c == '\n')
106 error_with_progname = false;
107 error (EXIT_FAILURE, 0, _("%s:%d: invalid string definition"),
108 logical_filename, line_number);
109 error_with_progname = true;
111 if (bufpos >= bufmax)
113 bufmax = 2 * bufmax + 10;
114 buffer = xrealloc (buffer, bufmax);
116 if (c == '=')
117 break;
118 buffer[bufpos++] = c;
119 c = getc (f);
120 if (c == EOF && ferror (f))
121 goto bomb;
123 buffer[bufpos] = '\0';
124 location = xstrdup (buffer);
126 /* Read StringExpression. */
127 bufpos = 0;
128 for (;;)
130 c = getc (f);
131 if (c == EOF)
132 break;
133 else if (c == '\n')
135 line_number++;
136 break;
138 else if (c == '\'')
140 for (;;)
142 c = getc (f);
143 /* Embedded single quotes like 'abc''def' don't occur.
144 See fpc-1.0.4/compiler/cresstr.pas. */
145 if (c == EOF || c == '\n' || c == '\'')
146 break;
147 if (bufpos >= bufmax)
149 bufmax = 2 * bufmax + 10;
150 buffer = xrealloc (buffer, bufmax);
152 buffer[bufpos++] = c;
154 if (c == EOF)
155 break;
156 else if (c == '\n')
158 line_number++;
159 break;
162 else if (c == '#')
164 int n;
165 c = getc (f);
166 if (c == EOF && ferror (f))
167 goto bomb;
168 if (c == EOF || !isdigit (c))
170 error_with_progname = false;
171 error (EXIT_FAILURE, 0, _("%s:%d: missing number after #"),
172 logical_filename, line_number);
173 error_with_progname = true;
175 n = (c - '0');
176 for (;;)
178 c = getc (f);
179 if (c == EOF || !isdigit (c))
180 break;
181 n = n * 10 + (c - '0');
183 if (bufpos >= bufmax)
185 bufmax = 2 * bufmax + 10;
186 buffer = xrealloc (buffer, bufmax);
188 buffer[bufpos++] = (unsigned char) n;
189 if (c == EOF)
190 break;
191 ungetc (c, f);
193 else if (c == '+')
195 c = getc (f);
196 if (c == EOF)
197 break;
198 if (c == '\n')
199 line_number++;
200 else
201 ungetc (c, f);
203 else
205 error_with_progname = false;
206 error (EXIT_FAILURE, 0, _("%s:%d: invalid string expression"),
207 logical_filename, line_number);
208 error_with_progname = true;
211 if (bufpos >= bufmax)
213 bufmax = 2 * bufmax + 10;
214 buffer = xrealloc (buffer, bufmax);
216 buffer[bufpos] = '\0';
217 msgid = xstrdup (buffer);
219 pos.file_name = location;
220 pos.line_number = (size_t)(-1);
222 remember_a_message (mlp, msgid, null_context, &pos);
224 /* Here c is the last read character: EOF or '\n'. */
225 if (c == EOF)
226 break;
229 if (ferror (f))
231 bomb:
232 error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
233 real_filename);