1 /* xgettext common functions.
2 Copyright (C) 2001-2003, 2005-2006, 2008-2009 Free Software Foundation, Inc.
3 Written by Peter Miller <millerp@canb.auug.org.au>
4 and 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 3 of the License, or
9 (at your option) 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, see <http://www.gnu.org/licenses/>. */
34 /* Declare 'line_comment' and 'input_syntax'. */
35 #include "read-catalog.h"
43 /* If true, omit the header entry.
44 If false, keep the header entry present in the input. */
45 extern int xgettext_omit_header;
47 extern bool substring_match;
50 /* Calling convention for a given keyword. */
53 int argnum1; /* argument number to use for msgid */
54 int argnum2; /* argument number to use for msgid_plural */
55 int argnumc; /* argument number to use for msgctxt */
56 bool argnum1_glib_context; /* argument argnum1 has the syntax "ctxt|msgid" */
57 bool argnum2_glib_context; /* argument argnum2 has the syntax "ctxt|msgid" */
58 int argtotal; /* total number of arguments */
59 string_list_ty xcomments; /* auto-extracted comments */
62 /* Split keyword spec into keyword, argnum1, argnum2, argnumc. */
63 extern void split_keywordspec (const char *spec, const char **endp,
64 struct callshape *shapep);
66 /* Set of alternative calling conventions for a given keyword. */
69 const char *keyword; /* the keyword, not NUL terminated */
70 size_t keyword_len; /* the keyword's length */
72 struct callshape shapes[1]; /* actually nshapes elements */
75 /* Insert a (keyword, callshape) pair into a hash table mapping keyword to
76 'struct callshapes *'. */
77 extern void insert_keyword_callshape (hash_table *table,
78 const char *keyword, size_t keyword_len,
79 const struct callshape *shape);
82 /* Context representing some flags. */
83 typedef struct flag_context_ty flag_context_ty;
84 struct flag_context_ty
86 /* Regarding the primary formatstring type. */
87 /*enum is_format*/ unsigned int is_format1 : 3;
88 /*bool*/ unsigned int pass_format1 : 1;
89 /* Regarding the secondary formatstring type. */
90 /*enum is_format*/ unsigned int is_format2 : 3;
91 /*bool*/ unsigned int pass_format2 : 1;
92 /* Regarding the tertiary formatstring type. */
93 /*enum is_format*/ unsigned int is_format3 : 3;
94 /*bool*/ unsigned int pass_format3 : 1;
97 extern flag_context_ty null_context;
98 /* Transparent context. */
99 extern flag_context_ty passthrough_context;
100 /* Compute an inherited context.
101 The outer_context is assumed to have all pass_format* flags = false.
102 The result will then also have all pass_format* flags = false. */
103 extern flag_context_ty
104 inherited_context (flag_context_ty outer_context,
105 flag_context_ty modifier_context);
107 /* Context representing some flags, for each possible argument number.
108 This is a linked list, sorted according to the argument number. */
109 typedef struct flag_context_list_ty flag_context_list_ty;
110 struct flag_context_list_ty
112 int argnum; /* current argument number, > 0 */
113 flag_context_ty flags; /* flags for current argument */
114 flag_context_list_ty *next;
117 /* Iterator through a flag_context_list_ty. */
118 typedef struct flag_context_list_iterator_ty flag_context_list_iterator_ty;
119 struct flag_context_list_iterator_ty
121 int argnum; /* current argument number, > 0 */
122 const flag_context_list_ty* head; /* tail of list */
124 extern flag_context_list_iterator_ty null_context_list_iterator;
125 extern flag_context_list_iterator_ty passthrough_context_list_iterator;
126 extern flag_context_list_iterator_ty
127 flag_context_list_iterator (flag_context_list_ty *list);
128 extern flag_context_ty
129 flag_context_list_iterator_advance (flag_context_list_iterator_ty *iter);
131 /* For nearly each backend, we have a separate table mapping a keyword to
132 a flag_context_list_ty *. */
133 typedef hash_table /* char[] -> flag_context_list_ty * */
134 flag_context_list_table_ty;
135 extern flag_context_list_ty *
136 flag_context_list_table_lookup (flag_context_list_table_ty *flag_table,
137 const void *key, size_t keylen);
138 /* Record a flag in the appropriate backend's table. */
139 extern void xgettext_record_flag (const char *optionstring);
142 /* Context while building up lexical tokens. */
145 lc_outside, /* Initial context: outside of comments and strings. */
146 lc_comment, /* Inside a comment. */
147 lc_string /* Inside a string literal. */
151 /* Error message about non-ASCII character in a specific lexical context. */
152 extern char *non_ascii_error_message (lexical_context_ty lcontext,
153 const char *file_name,
157 /* Canonicalized encoding name for all input files. */
158 extern const char *xgettext_global_source_encoding;
161 /* Converter from xgettext_global_source_encoding to UTF-8 (except from
162 ASCII or UTF-8, when this conversion is a no-op). */
163 extern iconv_t xgettext_global_source_iconv;
166 /* Canonicalized encoding name for the current input file. */
167 extern const char *xgettext_current_source_encoding;
170 /* Converter from xgettext_current_source_encoding to UTF-8 (except from
171 ASCII or UTF-8, when this conversion is a no-op). */
172 extern iconv_t xgettext_current_source_iconv;
175 /* Convert the given string from xgettext_current_source_encoding to
176 the output file encoding (i.e. ASCII or UTF-8).
177 The resulting string is either the argument string, or freshly allocated.
178 The lcontext, file_name and line_number are only used for error message
180 extern char *from_current_source_encoding (const char *string,
181 lexical_context_ty lcontext,
182 const char *file_name,
186 /* List of messages whose msgids must not be extracted, or NULL.
187 Used by remember_a_message(). */
188 extern message_list_ty *exclude;
191 /* Comment handling for backends which support combining adjacent strings
193 In these backends we cannot use the xgettext_comment* functions directly,
194 because in multiline string expressions like
197 the newline between "string1" and "string2" would cause a call to
198 xgettext_comment_reset(), thus destroying the accumulated comments
199 that we need a little later, when we have concatenated the two strings
200 and pass them to remember_a_message().
201 Instead, we do the bookkeeping of the accumulated comments directly,
202 and save a pointer to the accumulated comments when we read "string1".
203 In order to avoid excessive copying of strings, we use reference
206 typedef struct refcounted_string_list_ty refcounted_string_list_ty;
207 struct refcounted_string_list_ty
209 unsigned int refcount;
210 struct string_list_ty contents;
213 static inline refcounted_string_list_ty *
214 add_reference (refcounted_string_list_ty *rslp)
222 drop_reference (refcounted_string_list_ty *rslp)
226 if (rslp->refcount > 1)
230 string_list_destroy (&rslp->contents);
236 extern refcounted_string_list_ty *savable_comment;
237 extern void savable_comment_add (const char *str);
238 extern void savable_comment_reset (void);
241 /* Add a message to the list of extracted messages.
242 msgctxt must be either NULL or a malloc()ed string; its ownership is passed
244 MSGID must be a malloc()ed string; its ownership is passed to the callee.
245 POS->file_name must be allocated with indefinite extent.
246 EXTRACTED_COMMENT is a comment that needs to be copied into the POT file,
248 COMMENT may be savable_comment, or it may be a saved copy of savable_comment
249 (then add_reference must be used when saving it, and drop_reference while
250 dropping it). Clear savable_comment. */
251 extern message_ty *remember_a_message (message_list_ty *mlp,
254 flag_context_ty context,
256 const char *extracted_comment,
257 refcounted_string_list_ty *comment);
259 /* Add an msgid_plural to a message previously returned by
261 STRING must be a malloc()ed string; its ownership is passed to the callee.
262 POS->file_name must be allocated with indefinite extent.
263 COMMENT may be savable_comment, or it may be a saved copy of savable_comment
264 (then add_reference must be used when saving it, and drop_reference while
265 dropping it). Clear savable_comment. */
266 extern void remember_a_message_plural (message_ty *mp,
268 flag_context_ty context,
270 refcounted_string_list_ty *comment);
273 /* Represents the progressive parsing of an argument list w.r.t. a single
274 'struct callshape'. */
277 int argnumc; /* number of context argument, 0 when seen */
278 int argnum1; /* number of singular argument, 0 when seen */
279 int argnum2; /* number of plural argument, 0 when seen */
280 bool argnum1_glib_context; /* argument argnum1 has the syntax "ctxt|msgid" */
281 bool argnum2_glib_context; /* argument argnum2 has the syntax "ctxt|msgid" */
282 int argtotal; /* total number of arguments, 0 if unspecified */
283 string_list_ty xcomments; /* auto-extracted comments */
284 char *msgctxt; /* context - owned string, or NULL */
285 lex_pos_ty msgctxt_pos;
286 char *msgid; /* msgid - owned string, or NULL */
287 flag_context_ty msgid_context;
288 lex_pos_ty msgid_pos;
289 refcounted_string_list_ty *msgid_comment;
290 char *msgid_plural; /* msgid_plural - owned string, or NULL */
291 flag_context_ty msgid_plural_context;
292 lex_pos_ty msgid_plural_pos;
295 /* Represents the progressive parsing of an argument list w.r.t. an entire
296 'struct callshapes'. */
297 struct arglist_parser
299 message_list_ty *mlp; /* list where the message shall be added */
300 const char *keyword; /* the keyword, not NUL terminated */
301 size_t keyword_len; /* the keyword's length */
302 size_t nalternatives; /* number of partial_call alternatives */
303 struct partial_call alternative[1]; /* partial_call alternatives */
306 /* Creates a fresh arglist_parser recognizing calls.
307 You can pass shapes = NULL for a parser not recognizing any calls. */
308 extern struct arglist_parser * arglist_parser_alloc (message_list_ty *mlp,
309 const struct callshapes *shapes);
310 /* Clones an arglist_parser. */
311 extern struct arglist_parser * arglist_parser_clone (struct arglist_parser *ap);
312 /* Adds a string argument to an arglist_parser. ARGNUM must be > 0.
313 STRING must be malloc()ed string; its ownership is passed to the callee.
314 FILE_NAME must be allocated with indefinite extent.
315 COMMENT may be savable_comment, or it may be a saved copy of savable_comment
316 (then add_reference must be used when saving it, and drop_reference while
317 dropping it). Clear savable_comment. */
318 extern void arglist_parser_remember (struct arglist_parser *ap,
319 int argnum, char *string,
320 flag_context_ty context,
321 char *file_name, size_t line_number,
322 refcounted_string_list_ty *comment);
323 /* Tests whether an arglist_parser has is not waiting for more arguments after
325 extern bool arglist_parser_decidedp (struct arglist_parser *ap, int argnum);
326 /* Terminates the processing of an arglist_parser after argument ARGNUM and
328 extern void arglist_parser_done (struct arglist_parser *ap, int argnum);
336 #endif /* _XGETTEXT_H */