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