Imported Upstream version 0.18.1.1
[platform/upstream/gettext.git] / gettext-tools / src / xgettext.h
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.
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 #ifndef _XGETTEXT_H
20 #define _XGETTEXT_H
21
22 #include <stdbool.h>
23 #include <stddef.h>
24 #include <stdlib.h>
25
26 #if HAVE_ICONV
27 #include <iconv.h>
28 #endif
29
30 #include "message.h"
31 #include "pos.h"
32 #include "str-list.h"
33
34 /* Declare 'line_comment' and 'input_syntax'.  */
35 #include "read-catalog.h"
36
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42
43 /* If true, omit the header entry.
44    If false, keep the header entry present in the input.  */
45 extern int xgettext_omit_header;
46
47 extern bool substring_match;
48
49
50 /* Calling convention for a given keyword.  */
51 struct callshape
52 {
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 */
60 };
61
62 /* Split keyword spec into keyword, argnum1, argnum2, argnumc.  */
63 extern void split_keywordspec (const char *spec, const char **endp,
64                                struct callshape *shapep);
65
66 /* Set of alternative calling conventions for a given keyword.  */
67 struct callshapes
68 {
69   const char *keyword;          /* the keyword, not NUL terminated */
70   size_t keyword_len;           /* the keyword's length */
71   size_t nshapes;
72   struct callshape shapes[1];   /* actually nshapes elements */
73 };
74
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);
80
81
82 /* Context representing some flags.  */
83 typedef struct flag_context_ty flag_context_ty;
84 struct flag_context_ty
85 {
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;
95 };
96 /* Null context.  */
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);
106
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
111 {
112   int argnum;                   /* current argument number, > 0 */
113   flag_context_ty flags;        /* flags for current argument */
114   flag_context_list_ty *next;
115 };
116
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
120 {
121   int argnum;                           /* current argument number, > 0 */
122   const flag_context_list_ty* head;     /* tail of list */
123 };
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);
130
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);
140
141
142 /* Context while building up lexical tokens.  */
143 typedef enum
144   {
145     lc_outside, /* Initial context: outside of comments and strings.  */
146     lc_comment, /* Inside a comment.  */
147     lc_string   /* Inside a string literal.  */
148   }
149   lexical_context_ty;
150
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,
154                                       size_t line_number);
155
156
157 /* Canonicalized encoding name for all input files.  */
158 extern const char *xgettext_global_source_encoding;
159
160 #if HAVE_ICONV
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;
164 #endif
165
166 /* Canonicalized encoding name for the current input file.  */
167 extern const char *xgettext_current_source_encoding;
168
169 #if HAVE_ICONV
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;
173 #endif
174
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
179    purposes.  */
180 extern char *from_current_source_encoding (const char *string,
181                                            lexical_context_ty lcontext,
182                                            const char *file_name,
183                                            size_t line_number);
184
185
186 /* List of messages whose msgids must not be extracted, or NULL.
187    Used by remember_a_message().  */
188 extern message_list_ty *exclude;
189
190
191 /* Comment handling for backends which support combining adjacent strings
192    even across lines.
193    In these backends we cannot use the xgettext_comment* functions directly,
194    because in multiline string expressions like
195            "string1" +
196            "string2"
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
204    counting.  */
205
206 typedef struct refcounted_string_list_ty refcounted_string_list_ty;
207 struct refcounted_string_list_ty
208 {
209   unsigned int refcount;
210   struct string_list_ty contents;
211 };
212
213 static inline refcounted_string_list_ty *
214 add_reference (refcounted_string_list_ty *rslp)
215 {
216   if (rslp != NULL)
217     rslp->refcount++;
218   return rslp;
219 }
220
221 static inline void
222 drop_reference (refcounted_string_list_ty *rslp)
223 {
224   if (rslp != NULL)
225     {
226       if (rslp->refcount > 1)
227         rslp->refcount--;
228       else
229         {
230           string_list_destroy (&rslp->contents);
231           free (rslp);
232         }
233     }
234 }
235
236 extern refcounted_string_list_ty *savable_comment;
237 extern void savable_comment_add (const char *str);
238 extern void savable_comment_reset (void);
239
240
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
243    to the callee.
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,
247    or NULL.
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,
252                                        char *msgctxt,
253                                        char *msgid,
254                                        flag_context_ty context,
255                                        lex_pos_ty *pos,
256                                        const char *extracted_comment,
257                                        refcounted_string_list_ty *comment);
258
259 /* Add an msgid_plural to a message previously returned by
260    remember_a_message.
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,
267                                        char *string,
268                                        flag_context_ty context,
269                                        lex_pos_ty *pos,
270                                        refcounted_string_list_ty *comment);
271
272
273 /* Represents the progressive parsing of an argument list w.r.t. a single
274    'struct callshape'.  */
275 struct partial_call
276 {
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;
293 };
294
295 /* Represents the progressive parsing of an argument list w.r.t. an entire
296    'struct callshapes'.  */
297 struct arglist_parser
298 {
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 */
304 };
305
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
324    argument ARGNUM.  */
325 extern bool arglist_parser_decidedp (struct arglist_parser *ap, int argnum);
326 /* Terminates the processing of an arglist_parser after argument ARGNUM and
327    deletes it.  */
328 extern void arglist_parser_done (struct arglist_parser *ap, int argnum);
329
330
331 #ifdef __cplusplus
332 }
333 #endif
334
335
336 #endif /* _XGETTEXT_H */