No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / x-po.c
blob72045e1724774028127384c0301bf5715cb5b5c2
1 /* xgettext PO and JavaProperties backends.
2 Copyright (C) 1995-1998, 2000-2003, 2005 Free Software Foundation, Inc.
4 This file was written by Peter Miller <millerp@canb.auug.org.au>
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 <stdio.h>
25 #include <stdlib.h>
26 #include <stdbool.h>
27 #include <string.h>
29 #include "message.h"
30 #include "xgettext.h"
31 #include "x-po.h"
32 #include "x-properties.h"
33 #include "x-stringtable.h"
34 #include "xalloc.h"
35 #include "read-po.h"
36 #include "po-lex.h"
37 #include "gettext.h"
39 /* A convenience macro. I don't like writing gettext() every time. */
40 #define _(str) gettext (str)
43 /* The charset found in the header entry. */
44 static char *header_charset;
46 /* Define a subclass extract_po_reader_ty of default_po_reader_ty. */
48 static void
49 extract_add_message (default_po_reader_ty *this,
50 char *msgid,
51 lex_pos_ty *msgid_pos,
52 char *msgid_plural,
53 char *msgstr, size_t msgstr_len,
54 lex_pos_ty *msgstr_pos,
55 bool force_fuzzy, bool obsolete)
57 /* See whether we shall exclude this message. */
58 if (exclude != NULL && message_list_search (exclude, msgid) != NULL)
59 goto discard;
61 /* If the msgid is the empty string, it is the old header. Throw it
62 away, we have constructed a new one. Only remember its charset.
63 But if no new one was constructed, keep the old header. This is useful
64 because the old header may contain a charset= directive. */
65 if (*msgid == '\0' && !xgettext_omit_header)
67 const char *charsetstr = strstr (msgstr, "charset=");
69 if (charsetstr != NULL)
71 size_t len;
72 char *charset;
74 charsetstr += strlen ("charset=");
75 len = strcspn (charsetstr, " \t\n");
76 charset = (char *) xmalloc (len + 1);
77 memcpy (charset, charsetstr, len);
78 charset[len] = '\0';
80 if (header_charset != NULL)
81 free (header_charset);
82 header_charset = charset;
85 discard:
86 free (msgid);
87 free (msgstr);
88 return;
91 /* Invoke superclass method. */
92 default_add_message (this, msgid, msgid_pos, msgid_plural,
93 msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
97 /* So that the one parser can be used for multiple programs, and also
98 use good data hiding and encapsulation practices, an object
99 oriented approach has been taken. An object instance is allocated,
100 and all actions resulting from the parse will be through
101 invocations of method functions of that object. */
103 static default_po_reader_class_ty extract_methods =
106 sizeof (default_po_reader_ty),
107 default_constructor,
108 default_destructor,
109 default_parse_brief,
110 default_parse_debrief,
111 default_directive_domain,
112 default_directive_message,
113 default_comment,
114 default_comment_dot,
115 default_comment_filepos,
116 default_comment_special
118 default_set_domain, /* set_domain */
119 extract_add_message, /* add_message */
120 NULL /* frob_new_message */
124 static void
125 extract (FILE *fp,
126 const char *real_filename, const char *logical_filename,
127 input_syntax_ty syntax,
128 msgdomain_list_ty *mdlp)
130 default_po_reader_ty *pop;
132 header_charset = NULL;
134 pop = default_po_reader_alloc (&extract_methods);
135 pop->handle_comments = true;
136 pop->handle_filepos_comments = (line_comment != 0);
137 pop->allow_domain_directives = false;
138 pop->allow_duplicates = false;
139 pop->allow_duplicates_if_same_msgstr = true;
140 pop->mdlp = NULL;
141 pop->mlp = mdlp->item[0]->messages;
142 po_scan ((abstract_po_reader_ty *) pop, fp, real_filename, logical_filename,
143 syntax);
144 po_reader_free ((abstract_po_reader_ty *) pop);
146 if (header_charset != NULL)
148 if (!xgettext_omit_header)
150 /* Put the old charset into the freshly constructed header entry. */
151 message_ty *mp = message_list_search (mdlp->item[0]->messages, "");
153 if (mp != NULL && !mp->obsolete)
155 const char *header = mp->msgstr;
157 if (header != NULL)
159 const char *charsetstr = strstr (header, "charset=");
161 if (charsetstr != NULL)
163 size_t len, len1, len2, len3;
164 char *new_header;
166 charsetstr += strlen ("charset=");
167 len = strcspn (charsetstr, " \t\n");
169 len1 = charsetstr - header;
170 len2 = strlen (header_charset);
171 len3 = (header + strlen (header)) - (charsetstr + len);
172 new_header = (char *) xmalloc (len1 + len2 + len3 + 1);
173 memcpy (new_header, header, len1);
174 memcpy (new_header + len1, header_charset, len2);
175 memcpy (new_header + len1 + len2, charsetstr + len, len3 + 1);
176 mp->msgstr = new_header;
177 mp->msgstr_len = len1 + len2 + len3 + 1;
183 free (header_charset);
188 void
189 extract_po (FILE *fp,
190 const char *real_filename, const char *logical_filename,
191 flag_context_list_table_ty *flag_table,
192 msgdomain_list_ty *mdlp)
194 extract (fp, real_filename, logical_filename, syntax_po, mdlp);
198 void
199 extract_properties (FILE *fp,
200 const char *real_filename, const char *logical_filename,
201 flag_context_list_table_ty *flag_table,
202 msgdomain_list_ty *mdlp)
204 extract (fp, real_filename, logical_filename, syntax_properties, mdlp);
208 void
209 extract_stringtable (FILE *fp,
210 const char *real_filename, const char *logical_filename,
211 flag_context_list_table_ty *flag_table,
212 msgdomain_list_ty *mdlp)
214 extract (fp, real_filename, logical_filename, syntax_stringtable, mdlp);