jpayne@69
|
1 /* Public API for GNU gettext PO files - contained in libgettextpo.
|
jpayne@69
|
2 Copyright (C) 2003-2008, 2010, 2012-2016, 2019-2024 Free Software Foundation, Inc.
|
jpayne@69
|
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
|
jpayne@69
|
4
|
jpayne@69
|
5 This program is free software: you can redistribute it and/or modify
|
jpayne@69
|
6 it under the terms of the GNU General Public License as published by
|
jpayne@69
|
7 the Free Software Foundation; either version 3 of the License, or
|
jpayne@69
|
8 (at your option) any later version.
|
jpayne@69
|
9
|
jpayne@69
|
10 This program is distributed in the hope that it will be useful,
|
jpayne@69
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
jpayne@69
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
jpayne@69
|
13 GNU General Public License for more details.
|
jpayne@69
|
14
|
jpayne@69
|
15 You should have received a copy of the GNU General Public License
|
jpayne@69
|
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
jpayne@69
|
17
|
jpayne@69
|
18 #ifndef _GETTEXT_PO_H
|
jpayne@69
|
19 #define _GETTEXT_PO_H 1
|
jpayne@69
|
20
|
jpayne@69
|
21 #include <stdlib.h>
|
jpayne@69
|
22
|
jpayne@69
|
23 #ifdef __cplusplus
|
jpayne@69
|
24 extern "C" {
|
jpayne@69
|
25 #endif
|
jpayne@69
|
26
|
jpayne@69
|
27
|
jpayne@69
|
28 /* =========================== Meta Information ============================ */
|
jpayne@69
|
29
|
jpayne@69
|
30 /* Version number: (major<<16) + (minor<<8) + subminor */
|
jpayne@69
|
31 #define LIBGETTEXTPO_VERSION 0x001605
|
jpayne@69
|
32 extern int libgettextpo_version;
|
jpayne@69
|
33
|
jpayne@69
|
34 /* ================================= Types ================================= */
|
jpayne@69
|
35
|
jpayne@69
|
36 /* A po_file_t represents the contents of a PO file. */
|
jpayne@69
|
37 typedef struct po_file *po_file_t;
|
jpayne@69
|
38
|
jpayne@69
|
39 /* A po_message_iterator_t represents an iterator through a domain of a
|
jpayne@69
|
40 PO file. */
|
jpayne@69
|
41 typedef struct po_message_iterator *po_message_iterator_t;
|
jpayne@69
|
42
|
jpayne@69
|
43 /* A po_message_t represents a message in a PO file. */
|
jpayne@69
|
44 typedef struct po_message *po_message_t;
|
jpayne@69
|
45
|
jpayne@69
|
46 /* A po_filepos_t represents a string's position within a source file. */
|
jpayne@69
|
47 typedef struct po_filepos *po_filepos_t;
|
jpayne@69
|
48
|
jpayne@69
|
49 /* A po_error_handler handles error situations. */
|
jpayne@69
|
50 struct po_error_handler
|
jpayne@69
|
51 {
|
jpayne@69
|
52 /* Signal an error. The error message is built from FORMAT and the following
|
jpayne@69
|
53 arguments. ERRNUM, if nonzero, is an errno value.
|
jpayne@69
|
54 Must increment the error_message_count variable declared in error.h.
|
jpayne@69
|
55 Must not return if STATUS is nonzero. */
|
jpayne@69
|
56 void (*error) (int status, int errnum,
|
jpayne@69
|
57 const char *format, ...)
|
jpayne@69
|
58 #if ((__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || __GNUC__ > 3) && !__STRICT_ANSI__
|
jpayne@69
|
59 __attribute__ ((__format__ (__printf__, 3, 4)))
|
jpayne@69
|
60 #endif
|
jpayne@69
|
61 ;
|
jpayne@69
|
62
|
jpayne@69
|
63 /* Signal an error. The error message is built from FORMAT and the following
|
jpayne@69
|
64 arguments. The error location is at FILENAME line LINENO. ERRNUM, if
|
jpayne@69
|
65 nonzero, is an errno value.
|
jpayne@69
|
66 Must increment the error_message_count variable declared in error.h.
|
jpayne@69
|
67 Must not return if STATUS is nonzero. */
|
jpayne@69
|
68 void (*error_at_line) (int status, int errnum,
|
jpayne@69
|
69 const char *filename, unsigned int lineno,
|
jpayne@69
|
70 const char *format, ...)
|
jpayne@69
|
71 #if ((__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || __GNUC__ > 3) && !__STRICT_ANSI__
|
jpayne@69
|
72 __attribute__ ((__format__ (__printf__, 5, 6)))
|
jpayne@69
|
73 #endif
|
jpayne@69
|
74 ;
|
jpayne@69
|
75
|
jpayne@69
|
76 /* Signal a multiline warning. The PREFIX applies to all lines of the
|
jpayne@69
|
77 MESSAGE. Free the PREFIX and MESSAGE when done. */
|
jpayne@69
|
78 void (*multiline_warning) (char *prefix, char *message);
|
jpayne@69
|
79
|
jpayne@69
|
80 /* Signal a multiline error. The PREFIX applies to all lines of the
|
jpayne@69
|
81 MESSAGE. Free the PREFIX and MESSAGE when done.
|
jpayne@69
|
82 Must increment the error_message_count variable declared in error.h if
|
jpayne@69
|
83 PREFIX is non-NULL. */
|
jpayne@69
|
84 void (*multiline_error) (char *prefix, char *message);
|
jpayne@69
|
85 };
|
jpayne@69
|
86 typedef const struct po_error_handler *po_error_handler_t;
|
jpayne@69
|
87
|
jpayne@69
|
88 /* A po_xerror_handler handles warnings, error and fatal error situations. */
|
jpayne@69
|
89 #define PO_SEVERITY_WARNING 0 /* just a warning, tell the user */
|
jpayne@69
|
90 #define PO_SEVERITY_ERROR 1 /* an error, the operation cannot complete */
|
jpayne@69
|
91 #define PO_SEVERITY_FATAL_ERROR 2 /* an error, the operation must be aborted */
|
jpayne@69
|
92 struct po_xerror_handler
|
jpayne@69
|
93 {
|
jpayne@69
|
94 /* Signal a problem of the given severity.
|
jpayne@69
|
95 MESSAGE and/or FILENAME + LINENO indicate where the problem occurred.
|
jpayne@69
|
96 If FILENAME is NULL, FILENAME and LINENO and COLUMN should be ignored.
|
jpayne@69
|
97 If LINENO is (size_t)(-1), LINENO and COLUMN should be ignored.
|
jpayne@69
|
98 If COLUMN is (size_t)(-1), it should be ignored.
|
jpayne@69
|
99 MESSAGE_TEXT is the problem description (if MULTILINE_P is true,
|
jpayne@69
|
100 multiple lines of text, each terminated with a newline, otherwise
|
jpayne@69
|
101 usually a single line).
|
jpayne@69
|
102 Must not return if SEVERITY is PO_SEVERITY_FATAL_ERROR. */
|
jpayne@69
|
103 void (*xerror) (int severity,
|
jpayne@69
|
104 po_message_t message,
|
jpayne@69
|
105 const char *filename, size_t lineno, size_t column,
|
jpayne@69
|
106 int multiline_p, const char *message_text);
|
jpayne@69
|
107 /* Signal a problem that refers to two messages.
|
jpayne@69
|
108 Similar to two calls to xerror.
|
jpayne@69
|
109 If possible, a "..." can be appended to MESSAGE_TEXT1 and prepended to
|
jpayne@69
|
110 MESSAGE_TEXT2. */
|
jpayne@69
|
111 void (*xerror2) (int severity,
|
jpayne@69
|
112 po_message_t message1,
|
jpayne@69
|
113 const char *filename1, size_t lineno1, size_t column1,
|
jpayne@69
|
114 int multiline_p1, const char *message_text1,
|
jpayne@69
|
115 po_message_t message2,
|
jpayne@69
|
116 const char *filename2, size_t lineno2, size_t column2,
|
jpayne@69
|
117 int multiline_p2, const char *message_text2);
|
jpayne@69
|
118 };
|
jpayne@69
|
119 typedef const struct po_xerror_handler *po_xerror_handler_t;
|
jpayne@69
|
120
|
jpayne@69
|
121 /* Memory allocation:
|
jpayne@69
|
122 The memory allocations performed by these functions use xmalloc(),
|
jpayne@69
|
123 therefore will cause a program exit if memory is exhausted.
|
jpayne@69
|
124 The memory allocated by po_file_read, and implicitly returned through
|
jpayne@69
|
125 the po_message_* functions, lasts until freed with po_file_free. */
|
jpayne@69
|
126
|
jpayne@69
|
127
|
jpayne@69
|
128 /* ============================= po_file_t API ============================= */
|
jpayne@69
|
129
|
jpayne@69
|
130 /* Create an empty PO file representation in memory. */
|
jpayne@69
|
131 extern po_file_t po_file_create (void);
|
jpayne@69
|
132
|
jpayne@69
|
133 /* Read a PO file into memory.
|
jpayne@69
|
134 Return its contents. Upon failure, call function from handler. */
|
jpayne@69
|
135 #define po_file_read po_file_read_v3
|
jpayne@69
|
136 extern po_file_t po_file_read (const char *filename,
|
jpayne@69
|
137 po_xerror_handler_t handler);
|
jpayne@69
|
138
|
jpayne@69
|
139 /* Write an in-memory PO file to a file.
|
jpayne@69
|
140 Upon failure, call function from handler. */
|
jpayne@69
|
141 #define po_file_write po_file_write_v2
|
jpayne@69
|
142 extern po_file_t po_file_write (po_file_t file, const char *filename,
|
jpayne@69
|
143 po_xerror_handler_t handler);
|
jpayne@69
|
144
|
jpayne@69
|
145 /* Free a PO file from memory. */
|
jpayne@69
|
146 extern void po_file_free (po_file_t file);
|
jpayne@69
|
147
|
jpayne@69
|
148 /* Return the names of the domains covered by a PO file in memory. */
|
jpayne@69
|
149 extern const char * const * po_file_domains (po_file_t file);
|
jpayne@69
|
150
|
jpayne@69
|
151
|
jpayne@69
|
152 /* =========================== Header entry API ============================ */
|
jpayne@69
|
153
|
jpayne@69
|
154 /* Return the header entry of a domain of a PO file in memory.
|
jpayne@69
|
155 The domain NULL denotes the default domain.
|
jpayne@69
|
156 Return NULL if there is no header entry. */
|
jpayne@69
|
157 extern const char * po_file_domain_header (po_file_t file, const char *domain);
|
jpayne@69
|
158
|
jpayne@69
|
159 /* Return the value of a field in a header entry.
|
jpayne@69
|
160 The return value is either a freshly allocated string, to be freed by the
|
jpayne@69
|
161 caller, or NULL. */
|
jpayne@69
|
162 extern char * po_header_field (const char *header, const char *field);
|
jpayne@69
|
163
|
jpayne@69
|
164 /* Return the header entry with a given field set to a given value. The field
|
jpayne@69
|
165 is added if necessary.
|
jpayne@69
|
166 The return value is a freshly allocated string. */
|
jpayne@69
|
167 extern char * po_header_set_field (const char *header, const char *field, const char *value);
|
jpayne@69
|
168
|
jpayne@69
|
169
|
jpayne@69
|
170 /* ======================= po_message_iterator_t API ======================= */
|
jpayne@69
|
171
|
jpayne@69
|
172 /* Create an iterator for traversing a domain of a PO file in memory.
|
jpayne@69
|
173 The domain NULL denotes the default domain. */
|
jpayne@69
|
174 extern po_message_iterator_t po_message_iterator (po_file_t file, const char *domain);
|
jpayne@69
|
175
|
jpayne@69
|
176 /* Free an iterator. */
|
jpayne@69
|
177 extern void po_message_iterator_free (po_message_iterator_t iterator);
|
jpayne@69
|
178
|
jpayne@69
|
179 /* Return the next message, and advance the iterator.
|
jpayne@69
|
180 Return NULL at the end of the message list. */
|
jpayne@69
|
181 extern po_message_t po_next_message (po_message_iterator_t iterator);
|
jpayne@69
|
182
|
jpayne@69
|
183 /* Insert a message in a PO file in memory, in the domain and at the position
|
jpayne@69
|
184 indicated by the iterator. The iterator thereby advances past the freshly
|
jpayne@69
|
185 inserted message. */
|
jpayne@69
|
186 extern void po_message_insert (po_message_iterator_t iterator, po_message_t message);
|
jpayne@69
|
187
|
jpayne@69
|
188
|
jpayne@69
|
189 /* =========================== po_message_t API ============================ */
|
jpayne@69
|
190
|
jpayne@69
|
191 /* Return a freshly constructed message.
|
jpayne@69
|
192 To finish initializing the message, you must set the msgid and msgstr. */
|
jpayne@69
|
193 extern po_message_t po_message_create (void);
|
jpayne@69
|
194
|
jpayne@69
|
195 /* Return the context of a message, or NULL for a message not restricted to a
|
jpayne@69
|
196 context. */
|
jpayne@69
|
197 extern const char * po_message_msgctxt (po_message_t message);
|
jpayne@69
|
198
|
jpayne@69
|
199 /* Change the context of a message. NULL means a message not restricted to a
|
jpayne@69
|
200 context. */
|
jpayne@69
|
201 extern void po_message_set_msgctxt (po_message_t message, const char *msgctxt);
|
jpayne@69
|
202
|
jpayne@69
|
203 /* Return the msgid (untranslated English string) of a message. */
|
jpayne@69
|
204 extern const char * po_message_msgid (po_message_t message);
|
jpayne@69
|
205
|
jpayne@69
|
206 /* Change the msgid (untranslated English string) of a message. */
|
jpayne@69
|
207 extern void po_message_set_msgid (po_message_t message, const char *msgid);
|
jpayne@69
|
208
|
jpayne@69
|
209 /* Return the msgid_plural (untranslated English plural string) of a message,
|
jpayne@69
|
210 or NULL for a message without plural. */
|
jpayne@69
|
211 extern const char * po_message_msgid_plural (po_message_t message);
|
jpayne@69
|
212
|
jpayne@69
|
213 /* Change the msgid_plural (untranslated English plural string) of a message.
|
jpayne@69
|
214 NULL means a message without plural. */
|
jpayne@69
|
215 extern void po_message_set_msgid_plural (po_message_t message, const char *msgid_plural);
|
jpayne@69
|
216
|
jpayne@69
|
217 /* Return the msgstr (translation) of a message.
|
jpayne@69
|
218 Return the empty string for an untranslated message. */
|
jpayne@69
|
219 extern const char * po_message_msgstr (po_message_t message);
|
jpayne@69
|
220
|
jpayne@69
|
221 /* Change the msgstr (translation) of a message.
|
jpayne@69
|
222 Use an empty string to denote an untranslated message. */
|
jpayne@69
|
223 extern void po_message_set_msgstr (po_message_t message, const char *msgstr);
|
jpayne@69
|
224
|
jpayne@69
|
225 /* Return the msgstr[index] for a message with plural handling, or
|
jpayne@69
|
226 NULL when the index is out of range or for a message without plural. */
|
jpayne@69
|
227 extern const char * po_message_msgstr_plural (po_message_t message, int index);
|
jpayne@69
|
228
|
jpayne@69
|
229 /* Change the msgstr[index] for a message with plural handling.
|
jpayne@69
|
230 Use a NULL value at the end to reduce the number of plural forms. */
|
jpayne@69
|
231 extern void po_message_set_msgstr_plural (po_message_t message, int index, const char *msgstr);
|
jpayne@69
|
232
|
jpayne@69
|
233 /* Return the comments for a message. */
|
jpayne@69
|
234 extern const char * po_message_comments (po_message_t message);
|
jpayne@69
|
235
|
jpayne@69
|
236 /* Change the comments for a message.
|
jpayne@69
|
237 comments should be a multiline string, ending in a newline, or empty. */
|
jpayne@69
|
238 extern void po_message_set_comments (po_message_t message, const char *comments);
|
jpayne@69
|
239
|
jpayne@69
|
240 /* Return the extracted comments for a message. */
|
jpayne@69
|
241 extern const char * po_message_extracted_comments (po_message_t message);
|
jpayne@69
|
242
|
jpayne@69
|
243 /* Change the extracted comments for a message.
|
jpayne@69
|
244 comments should be a multiline string, ending in a newline, or empty. */
|
jpayne@69
|
245 extern void po_message_set_extracted_comments (po_message_t message, const char *comments);
|
jpayne@69
|
246
|
jpayne@69
|
247 /* Return the i-th file position for a message, or NULL if i is out of
|
jpayne@69
|
248 range. */
|
jpayne@69
|
249 extern po_filepos_t po_message_filepos (po_message_t message, int i);
|
jpayne@69
|
250
|
jpayne@69
|
251 /* Remove the i-th file position from a message.
|
jpayne@69
|
252 The indices of all following file positions for the message are decremented
|
jpayne@69
|
253 by one. */
|
jpayne@69
|
254 extern void po_message_remove_filepos (po_message_t message, int i);
|
jpayne@69
|
255
|
jpayne@69
|
256 /* Add a file position to a message, if it is not already present for the
|
jpayne@69
|
257 message.
|
jpayne@69
|
258 file is the file name.
|
jpayne@69
|
259 start_line is the line number where the string starts, or (size_t)(-1) if no
|
jpayne@69
|
260 line number is available. */
|
jpayne@69
|
261 extern void po_message_add_filepos (po_message_t message, const char *file, size_t start_line);
|
jpayne@69
|
262
|
jpayne@69
|
263 /* Return the previous context of a message, or NULL for none. */
|
jpayne@69
|
264 extern const char * po_message_prev_msgctxt (po_message_t message);
|
jpayne@69
|
265
|
jpayne@69
|
266 /* Change the previous context of a message. NULL is allowed. */
|
jpayne@69
|
267 extern void po_message_set_prev_msgctxt (po_message_t message, const char *prev_msgctxt);
|
jpayne@69
|
268
|
jpayne@69
|
269 /* Return the previous msgid (untranslated English string) of a message, or
|
jpayne@69
|
270 NULL for none. */
|
jpayne@69
|
271 extern const char * po_message_prev_msgid (po_message_t message);
|
jpayne@69
|
272
|
jpayne@69
|
273 /* Change the previous msgid (untranslated English string) of a message.
|
jpayne@69
|
274 NULL is allowed. */
|
jpayne@69
|
275 extern void po_message_set_prev_msgid (po_message_t message, const char *prev_msgid);
|
jpayne@69
|
276
|
jpayne@69
|
277 /* Return the previous msgid_plural (untranslated English plural string) of a
|
jpayne@69
|
278 message, or NULL for none. */
|
jpayne@69
|
279 extern const char * po_message_prev_msgid_plural (po_message_t message);
|
jpayne@69
|
280
|
jpayne@69
|
281 /* Change the previous msgid_plural (untranslated English plural string) of a
|
jpayne@69
|
282 message. NULL is allowed. */
|
jpayne@69
|
283 extern void po_message_set_prev_msgid_plural (po_message_t message, const char *prev_msgid_plural);
|
jpayne@69
|
284
|
jpayne@69
|
285 /* Return true if the message is marked obsolete. */
|
jpayne@69
|
286 extern int po_message_is_obsolete (po_message_t message);
|
jpayne@69
|
287
|
jpayne@69
|
288 /* Change the obsolete mark of a message. */
|
jpayne@69
|
289 extern void po_message_set_obsolete (po_message_t message, int obsolete);
|
jpayne@69
|
290
|
jpayne@69
|
291 /* Return true if the message is marked fuzzy. */
|
jpayne@69
|
292 extern int po_message_is_fuzzy (po_message_t message);
|
jpayne@69
|
293
|
jpayne@69
|
294 /* Change the fuzzy mark of a message. */
|
jpayne@69
|
295 extern void po_message_set_fuzzy (po_message_t message, int fuzzy);
|
jpayne@69
|
296
|
jpayne@69
|
297 /* Return true if the message is marked as being a format string of the given
|
jpayne@69
|
298 type (e.g. "c-format"). */
|
jpayne@69
|
299 extern int po_message_is_format (po_message_t message, const char *format_type);
|
jpayne@69
|
300
|
jpayne@69
|
301 /* Change the format string mark for a given type of a message. */
|
jpayne@69
|
302 extern void po_message_set_format (po_message_t message, const char *format_type, /*bool*/int value);
|
jpayne@69
|
303
|
jpayne@69
|
304 /* If a numeric range of a message is set, return true and store the minimum
|
jpayne@69
|
305 and maximum value in *MINP and *MAXP. */
|
jpayne@69
|
306 extern int po_message_is_range (po_message_t message, int *minp, int *maxp);
|
jpayne@69
|
307
|
jpayne@69
|
308 /* Change the numeric range of a message. MIN and MAX must be non-negative,
|
jpayne@69
|
309 with MIN < MAX. Use MIN = MAX = -1 to remove the numeric range of a
|
jpayne@69
|
310 message. */
|
jpayne@69
|
311 extern void po_message_set_range (po_message_t message, int min, int max);
|
jpayne@69
|
312
|
jpayne@69
|
313
|
jpayne@69
|
314 /* =========================== po_filepos_t API ============================ */
|
jpayne@69
|
315
|
jpayne@69
|
316 /* Return the file name. */
|
jpayne@69
|
317 extern const char * po_filepos_file (po_filepos_t filepos);
|
jpayne@69
|
318
|
jpayne@69
|
319 /* Return the line number where the string starts, or (size_t)(-1) if no line
|
jpayne@69
|
320 number is available. */
|
jpayne@69
|
321 extern size_t po_filepos_start_line (po_filepos_t filepos);
|
jpayne@69
|
322
|
jpayne@69
|
323
|
jpayne@69
|
324 /* ============================ Format type API ============================= */
|
jpayne@69
|
325
|
jpayne@69
|
326 /* Return a NULL terminated array of the supported format types. */
|
jpayne@69
|
327 extern const char * const * po_format_list (void);
|
jpayne@69
|
328
|
jpayne@69
|
329 /* Return the pretty name associated with a format type.
|
jpayne@69
|
330 For example, for "csharp-format", return "C#".
|
jpayne@69
|
331 Return NULL if the argument is not a supported format type. */
|
jpayne@69
|
332 extern const char * po_format_pretty_name (const char *format_type);
|
jpayne@69
|
333
|
jpayne@69
|
334
|
jpayne@69
|
335 /* ============================= Checking API ============================== */
|
jpayne@69
|
336
|
jpayne@69
|
337 /* Test whether an entire file PO file is valid, like msgfmt does it.
|
jpayne@69
|
338 If it is invalid, pass the reasons to the handler. */
|
jpayne@69
|
339 extern void po_file_check_all (po_file_t file, po_xerror_handler_t handler);
|
jpayne@69
|
340
|
jpayne@69
|
341 /* Test a single message, to be inserted in a PO file in memory, like msgfmt
|
jpayne@69
|
342 does it. If it is invalid, pass the reasons to the handler. The iterator
|
jpayne@69
|
343 is not modified by this call; it only specifies the file and the domain. */
|
jpayne@69
|
344 extern void po_message_check_all (po_message_t message, po_message_iterator_t iterator, po_xerror_handler_t handler);
|
jpayne@69
|
345
|
jpayne@69
|
346 /* Test whether the message translation is a valid format string if the message
|
jpayne@69
|
347 is marked as being a format string. If it is invalid, pass the reasons to
|
jpayne@69
|
348 the handler. */
|
jpayne@69
|
349 #define po_message_check_format po_message_check_format_v2
|
jpayne@69
|
350 extern void po_message_check_format (po_message_t message, po_xerror_handler_t handler);
|
jpayne@69
|
351
|
jpayne@69
|
352
|
jpayne@69
|
353 #ifdef __cplusplus
|
jpayne@69
|
354 }
|
jpayne@69
|
355 #endif
|
jpayne@69
|
356
|
jpayne@69
|
357 #endif /* _GETTEXT_PO_H */
|