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)
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. */
32 #include "x-properties.h"
33 #include "x-stringtable.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. */
49 extract_add_message (default_po_reader_ty
*this,
51 lex_pos_ty
*msgid_pos
,
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
)
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
)
74 charsetstr
+= strlen ("charset=");
75 len
= strcspn (charsetstr
, " \t\n");
76 charset
= (char *) xmalloc (len
+ 1);
77 memcpy (charset
, charsetstr
, len
);
80 if (header_charset
!= NULL
)
81 free (header_charset
);
82 header_charset
= charset
;
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
),
110 default_parse_debrief
,
111 default_directive_domain
,
112 default_directive_message
,
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 */
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;
141 pop
->mlp
= mdlp
->item
[0]->messages
;
142 po_scan ((abstract_po_reader_ty
*) pop
, fp
, real_filename
, logical_filename
,
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
;
159 const char *charsetstr
= strstr (header
, "charset=");
161 if (charsetstr
!= NULL
)
163 size_t len
, len1
, len2
, len3
;
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
);
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
);
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
);
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
);