From: Bruno Haible Date: Tue, 7 Sep 2004 11:44:32 +0000 (+0000) Subject: Extend the gettexpo library. X-Git-Tag: v0.14.2~236 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5eab4880854b4ca997214acf024307eee15508ed;p=thirdparty%2Fgettext.git Extend the gettexpo library. Use custom error handlers during reading and writing of PO files. --- diff --git a/gettext-tools/ChangeLog b/gettext-tools/ChangeLog index c46ed6c95..ef3a0f8fe 100644 --- a/gettext-tools/ChangeLog +++ b/gettext-tools/ChangeLog @@ -1,3 +1,8 @@ +2004-09-05 Bruno Haible + + * windows/gettextsrc.def: Add the variables names from po-error.h. + * windows/gettextpo.def: Add many new function names. + 2004-04-19 Bruno Haible * gettext.m4: Change jm_ to gl_ in all uses of AC_DEFINE'd names. diff --git a/gettext-tools/po/ChangeLog b/gettext-tools/po/ChangeLog index 56cac390d..7a829ddb8 100644 --- a/gettext-tools/po/ChangeLog +++ b/gettext-tools/po/ChangeLog @@ -1,3 +1,7 @@ +2004-09-05 Bruno Haible + + * Makevars (XGETTEXT_OPTIONS): Recognize po_error and po_error_at_line. + 2004-03-21 Bruno Haible * ca.po: Update from Ivan Vilata i Balaguer . diff --git a/gettext-tools/po/Makevars b/gettext-tools/po/Makevars index 17be10a4e..e1f13d6c7 100644 --- a/gettext-tools/po/Makevars +++ b/gettext-tools/po/Makevars @@ -14,6 +14,7 @@ XGETTEXT_OPTIONS = \ --flag=error:3:c-format --flag=error_at_line:5:c-format \ --flag=asprintf:2:c-format --flag=vasprintf:2:c-format \ --flag=xasprintf:1:c-format \ + --flag=po_error:3:c-format --flag=po_error_at_line:5:c-format \ --flag=po_gram_error:1:c-format --flag=po_gram_error_at_line:2:c-format # This is the copyright holder that gets inserted into the header of the diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 1cc6a72ca..781c550fd 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,62 @@ +2004-09-05 Bruno Haible + + * po-error.h: New file. + * po-error.c: New file. + * po-charset.c: Include po-error.h. + (po_lex_charset_set): Use po_multiline_warning instead of + multiline_warning. + * po-lex.h: Include po-error.h. + (po_gram_error): Use po_error instead of error. + (po_gram_error_at_line): Use po_error_at_line instead of error_at_line. + * po-lex.c (po_gram_error): Use po_error instead of error. + (po_gram_error_at_line): Use po_error_at_line instead of error_at_line. + (mbfile_getc, lex_getc): Use po_error instead of error. + * read-po-abstract.c (po_scan): Likewise. + * write-po.c: Include po-error.h instead of error.h. + (wrap): Use po_error instead of error. + (message_print, message_print_obsolete): Use po_multiline_warning + instead of multiline_warning. + (msgdomain_list_print): Use po_error instead of error, po_error_at_line + instead of error_at_line. + * str-list.h (string_list_join): New declaration. + * str-list.c (string_list_join): New function. + * message.h (message_list_insert_at): New declaration. + * message.c (message_list_insert_at): New function. + * gettext-po.h (po_filepos_t): New type. + (struct po_error_handler, po_error_handler_t): New types. + (po_file_create): New declaration. + (po_file_read): Add handler argument. + (po_file_write, po_message_insert, po_message_create, + po_message_set_msgid, po_message_set_msgid_plural, + po_message_set_msgstr, po_message_set_msgstr_plural, + po_message_comments, po_message_set_comments, + po_message_extracted_comments, po_message_filepos, + po_message_set_obsolete, po_message_set_fuzzy, po_message_set_format, + po_filepos_file, po_filepos_start_line): New declarations. + * gettext-po.c (po_file_create): New function. + (po_file_read): Add handler argument. Keep an old version for backward + compatibility. + (po_file_write): New function. + (po_message_iterator): Store more information, to make + po_message_insert possible. + (po_message_iterator_free): Update. + (po_next_message): Don't crash if iterator->mlp is NULL. + (po_message_insert): New function. + (po_message_create): New function. + (po_message_set_msgid, po_message_set_msgid_plural, + po_message_set_msgstr, po_message_set_msgstr_plural, + po_message_comments, po_message_set_comments, + po_message_extracted_comments, po_message_filepos, + po_message_set_obsolete, po_message_set_fuzzy, po_message_set_format, + po_filepos_file, po_filepos_start_line): New functions. + * Makefile.am (noinst_HEADERS): Add po-error.h. + (COMMON_SOURCE): Add po-error.c. + * Makefile.msvc (OBJECTS): Add po-error.obj. + (po-error.obj): New rule. + * Makefile.vms (OBJECTS): Add po-error.obj. + (po-error.obj): New rule. + * FILES: Update. + 2004-09-03 Bruno Haible * Makefile.am (msginit_LDADD): Use the INTL_MACOSX_LDFLAGS. diff --git a/gettext-tools/src/FILES b/gettext-tools/src/FILES index 40fed3772..d5f76e8d7 100644 --- a/gettext-tools/src/FILES +++ b/gettext-tools/src/FILES @@ -32,6 +32,10 @@ msgl-ascii.h msgl-ascii.c Message list test for ASCII character set. +po-error.h +po-error.c + Error handling during writing and reading of PO files. + write-po.h write-po.c Output of a list-of-messages to a PO file. diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am index 266d072f0..36f129ac8 100644 --- a/gettext-tools/src/Makefile.am +++ b/gettext-tools/src/Makefile.am @@ -34,14 +34,21 @@ lib_LTLIBRARIES = libgettextsrc.la libgettextpo.la include_HEADERS = gettext-po.h -noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-charset.h po-lex.h \ -open-po.h read-po-abstract.h read-po.h read-properties.h read-stringtable.h \ -str-list.h write-po.h write-properties.h write-stringtable.h dir-list.h \ -file-list.h po-gram-gen.h po-gram-gen2.h po-hash-gen.h msgl-charset.h \ -msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-english.h msgfmt.h \ -msgunfmt.h plural-count.h read-mo.h write-mo.h read-java.h write-java.h \ -read-csharp.h write-csharp.h read-resources.h write-resources.h read-tcl.h \ -write-tcl.h write-qt.h po-time.h plural-table.h format.h \ +noinst_HEADERS = pos.h message.h po-error.h po-gram.h po-hash.h po-charset.h \ +po-lex.h open-po.h \ +read-po-abstract.h read-po.h read-properties.h read-stringtable.h \ +str-list.h \ +write-po.h write-properties.h write-stringtable.h \ +dir-list.h file-list.h po-gram-gen.h po-gram-gen2.h po-hash-gen.h \ +msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h \ +msgl-english.h msgfmt.h msgunfmt.h plural-count.h \ +read-mo.h write-mo.h \ +read-java.h write-java.h \ +read-csharp.h write-csharp.h \ +read-resources.h write-resources.h \ +read-tcl.h write-tcl.h \ +write-qt.h \ +po-time.h plural-table.h format.h \ xgettext.h x-c.h x-po.h x-sh.h x-python.h x-lisp.h x-elisp.h x-librep.h \ x-smalltalk.h x-java.h x-properties.h x-csharp.h x-awk.h x-ycp.h x-tcl.h \ x-perl.h x-php.h x-stringtable.h x-rst.h x-glade.h @@ -90,7 +97,7 @@ CSHARPCOMPFLAGS = -O -g # (read-po-abstract.c <--> po-hash-gen.y <--> po-gram-gen.y <--> po-lex.c) -> open-po.c -> dir-list.c -> str-list.c. # (read-po-abstract.c <--> po-hash-gen.y <--> po-gram-gen.y <--> po-lex.c) -> po-charset.c. # (read-po-abstract.c <--> po-hash-gen.y <--> po-gram-gen.y <--> po-lex.c) -> message.c -> str-list.c. -COMMON_SOURCE = message.c \ +COMMON_SOURCE = message.c po-error.c \ read-po-abstract.c po-lex.c po-gram-gen.y po-hash-gen.y po-charset.c \ read-properties.c read-stringtable.c open-po.c dir-list.c str-list.c diff --git a/gettext-tools/src/Makefile.msvc b/gettext-tools/src/Makefile.msvc index 00079b432..27bdbf2c9 100644 --- a/gettext-tools/src/Makefile.msvc +++ b/gettext-tools/src/Makefile.msvc @@ -106,6 +106,7 @@ msgattrib.exe msgcat.exe msgcomm.exe msgconv.exe msgen.exe msgexec.exe msgfilter OBJECTS = \ message.obj \ + po-error.obj \ read-po-abstract.obj \ po-lex.obj \ po-gram-gen.obj \ @@ -175,6 +176,9 @@ all : gettextsrc.lib $(PROGRAMS) gettextpo.lib message.obj : message.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c message.c +po-error.obj : po-error.c + $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c -Tp po-error.c + read-po-abstract.obj : read-po-abstract.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c read-po-abstract.c diff --git a/gettext-tools/src/Makefile.vms b/gettext-tools/src/Makefile.vms index 7445330de..53fb4e495 100644 --- a/gettext-tools/src/Makefile.vms +++ b/gettext-tools/src/Makefile.vms @@ -52,6 +52,7 @@ PROGRAMS = msgcmp.exe, msgfmt.exe, msgmerge.exe, msgunfmt.exe, xgettext.exe, msg OBJECTS = \ message.obj, \ + po-error.obj, \ read-po-abstract.obj, \ po-lex.obj, \ po-gram-gen.obj, \ @@ -119,6 +120,9 @@ all : gettextsrc.olb,$(PROGRAMS),gettextpo.olb message.obj : message.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) message.c +po-error.obj : po-error.c + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) po-error.c + read-po-abstract.obj : read-po-abstract.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) read-po-abstract.c diff --git a/gettext-tools/src/gettext-po.c b/gettext-tools/src/gettext-po.c index 611a2fbd8..2a4e62522 100644 --- a/gettext-tools/src/gettext-po.c +++ b/gettext-tools/src/gettext-po.c @@ -1,5 +1,5 @@ /* Public API for GNU gettext PO files. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003-2004 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software; you can redistribute it and/or modify @@ -23,12 +23,20 @@ /* Specification. */ #include "gettext-po.h" +#include #include #include #include "message.h" #include "xalloc.h" #include "read-po.h" +#include "write-po.h" +#include "error.h" +#include "xerror.h" +#include "po-error.h" +#include "gettext.h" + +#define _(str) gettext(str) struct po_file @@ -41,16 +49,70 @@ struct po_file struct po_message_iterator { + po_file_t file; + char *domain; message_list_ty *mlp; size_t index; }; /* A po_message_t is actually a 'struct message_ty *'. */ +/* A po_filepos_t is actually a 'lex_pos_ty *'. */ + + +/* Create an empty PO file representation in memory. */ + +po_file_t +po_file_create (void) +{ + po_file_t file; + + file = (struct po_file *) xmalloc (sizeof (struct po_file)); + file->mdlp = msgdomain_list_alloc (false); + file->real_filename = _(""); + file->logical_filename = file->real_filename; + file->domains = NULL; + return file; +} + /* Read a PO file into memory. Return its contents. Upon failure, return NULL and set errno. */ +po_file_t +po_file_read (const char *filename, po_error_handler_t handler) +{ + FILE *fp; + po_file_t file; + + fp = fopen (filename, "r"); + if (fp == NULL) + return NULL; + + /* Establish error handler around read_po(). */ + po_error = handler->error; + po_error_at_line = handler->error_at_line; + po_multiline_warning = handler->multiline_warning; + po_multiline_error = handler->multiline_error; + + file = (struct po_file *) xmalloc (sizeof (struct po_file)); + file->real_filename = filename; + file->logical_filename = filename; + file->mdlp = read_po (fp, file->real_filename, file->logical_filename); + file->domains = NULL; + + /* Restore error handler. */ + po_error = error; + po_error_at_line = error_at_line; + po_multiline_warning = multiline_warning; + po_multiline_error = multiline_error; + + fclose (fp); + return file; +} +#undef po_file_read + +/* Older version for binary backward compatibility. */ po_file_t po_file_read (const char *filename) { @@ -60,16 +122,42 @@ po_file_read (const char *filename) fp = fopen (filename, "r"); if (fp == NULL) return NULL; + file = (struct po_file *) xmalloc (sizeof (struct po_file)); file->real_filename = filename; file->logical_filename = filename; file->mdlp = read_po (fp, file->real_filename, file->logical_filename); file->domains = NULL; + fclose (fp); return file; } +/* Write an in-memory PO file to a file. + Upon failure, return NULL and set errno. */ + +po_file_t +po_file_write (po_file_t file, const char *filename, po_error_handler_t handler) +{ + /* Establish error handler around msgdomain_list_print(). */ + po_error = handler->error; + po_error_at_line = handler->error_at_line; + po_multiline_warning = handler->multiline_warning; + po_multiline_error = handler->multiline_error; + + msgdomain_list_print (file->mdlp, filename, true, false); + + /* Restore error handler. */ + po_error = error; + po_error_at_line = error_at_line; + po_multiline_warning = multiline_warning; + po_multiline_error = multiline_error; + + return file; +} + + /* Free a PO file from memory. */ void @@ -189,6 +277,8 @@ po_message_iterator (po_file_t file, const char *domain) iterator = (struct po_message_iterator *) xmalloc (sizeof (struct po_message_iterator)); + iterator->file = file; + iterator->domain = xstrdup (domain); iterator->mlp = msgdomain_list_sublist (file->mdlp, domain, false); iterator->index = 0; @@ -201,6 +291,7 @@ po_message_iterator (po_file_t file, const char *domain) void po_message_iterator_free (po_message_iterator_t iterator) { + free (iterator->domain); free (iterator); } @@ -211,13 +302,45 @@ po_message_iterator_free (po_message_iterator_t iterator) po_message_t po_next_message (po_message_iterator_t iterator) { - if (iterator->index < iterator->mlp->nitems) + if (iterator->mlp != NULL && iterator->index < iterator->mlp->nitems) return (po_message_t) iterator->mlp->item[iterator->index++]; else return NULL; } +/* Insert a message in a PO file in memory, in the domain and at the position + indicated by the iterator. The iterator thereby advances past the freshly + inserted message. */ + +void +po_message_insert (po_message_iterator_t iterator, po_message_t message) +{ + message_ty *mp = (message_ty *) message; + + if (iterator->mlp == NULL) + /* Now we need to allocate a sublist corresponding to the iterator. */ + iterator->mlp = + msgdomain_list_sublist (iterator->file->mdlp, iterator->domain, true); + /* Insert the message. */ + message_list_insert_at (iterator->mlp, iterator->index, mp); + /* Advance the iterator. */ + iterator->index++; +} + + +/* Return a freshly constructed message. + To finish initializing the message, you must set the msgid and msgstr. */ + +po_message_t +po_message_create (void) +{ + lex_pos_ty pos = { NULL, 0 }; + + return (po_message_t) message_alloc (NULL, NULL, NULL, 0, &pos); +} + + /* Return the msgid (untranslated English string) of a message. */ const char * @@ -229,6 +352,24 @@ po_message_msgid (po_message_t message) } +/* Change the msgid (untranslated English string) of a message. */ + +void +po_message_set_msgid (po_message_t message, const char *msgid) +{ + message_ty *mp = (message_ty *) message; + + if (msgid != mp->msgid) + { + char *old_msgid = (char *) mp->msgid; + + mp->msgid = xstrdup (msgid); + if (old_msgid != NULL) + free (old_msgid); + } +} + + /* Return the msgid_plural (untranslated English plural string) of a message, or NULL for a message without plural. */ @@ -241,6 +382,25 @@ po_message_msgid_plural (po_message_t message) } +/* Change the msgid_plural (untranslated English plural string) of a message. + NULL means a message without plural. */ + +void +po_message_set_msgid_plural (po_message_t message, const char *msgid_plural) +{ + message_ty *mp = (message_ty *) message; + + if (msgid_plural != mp->msgid_plural) + { + char *old_msgid_plural = (char *) mp->msgid_plural; + + mp->msgid_plural = (msgid_plural != NULL ? xstrdup (msgid_plural) : NULL); + if (old_msgid_plural != NULL) + free (old_msgid_plural); + } +} + + /* Return the msgstr (translation) of a message. Return the empty string for an untranslated message. */ @@ -253,6 +413,26 @@ po_message_msgstr (po_message_t message) } +/* Change the msgstr (translation) of a message. + Use an empty string to denote an untranslated message. */ + +void +po_message_set_msgstr (po_message_t message, const char *msgstr) +{ + message_ty *mp = (message_ty *) message; + + if (msgstr != mp->msgstr) + { + char *old_msgstr = (char *) mp->msgstr; + + mp->msgstr = xstrdup (msgstr); + mp->msgstr_len = strlen (mp->msgstr) + 1; + if (old_msgstr != NULL) + free (old_msgstr); + } +} + + /* Return the msgstr[index] for a message with plural handling, or NULL when the index is out of range or for a message without plural. */ @@ -280,6 +460,170 @@ po_message_msgstr_plural (po_message_t message, int index) } +/* Change the msgstr[index] for a message with plural handling. + Use a NULL value at the end to reduce the number of plural forms. */ + +void +po_message_set_msgstr_plural (po_message_t message, int index, const char *msgstr) +{ + message_ty *mp = (message_ty *) message; + + if (mp->msgid_plural != NULL && index >= 0) + { + char *p = (char *) mp->msgstr; + char *p_end = (char *) mp->msgstr + mp->msgstr_len; + char *copied_msgstr; + + /* Special care must be taken of the case that msgstr points into the + mp->msgstr string list, because mp->msgstr may be relocated before we + are done with msgstr. */ + if (msgstr >= p && msgstr < p_end) + msgstr = copied_msgstr = xstrdup (msgstr); + else + copied_msgstr = NULL; + + for (; ; p += strlen (p) + 1, index--) + { + if (p >= p_end) + { + /* Append at the end. */ + if (msgstr != NULL) + { + size_t new_msgstr_len = mp->msgstr_len + index + strlen (msgstr) + 1; + + mp->msgstr = + (char *) xrealloc ((char *) mp->msgstr, new_msgstr_len); + p = (char *) mp->msgstr + mp->msgstr_len; + for (; index > 0; index--) + *p++ = '\0'; + memcpy (p, msgstr, strlen (msgstr) + 1); + mp->msgstr_len = new_msgstr_len; + } + if (copied_msgstr != NULL) + free (copied_msgstr); + return; + } + if (index == 0) + break; + } + if (msgstr == NULL) + { + if (p + strlen (p) + 1 >= p_end) + { + /* Remove the string that starts at p. */ + mp->msgstr_len = p - mp->msgstr; + return; + } + /* It is not possible to remove an element of the string list + except the last one. So just replace it with the empty string. + That's the best we can do here. */ + msgstr = ""; + } + { + /* Replace the string that starts at p. */ + size_t i1 = p - mp->msgstr; + size_t i2before = i1 + strlen (p); + size_t i2after = i1 + strlen (msgstr); + size_t new_msgstr_len = mp->msgstr_len - i2before + i2after; + + if (i2after > i2before) + mp->msgstr = (char *) xrealloc ((char *) mp->msgstr, new_msgstr_len); + memmove ((char *) mp->msgstr + i2after, mp->msgstr + i2before, + mp->msgstr_len - i2before); + memcpy ((char *) mp->msgstr + i1, msgstr, i2after - i1); + mp->msgstr_len = new_msgstr_len; + } + if (copied_msgstr != NULL) + free (copied_msgstr); + } +} + + +/* Return the comments for a message. */ + +const char * +po_message_comments (po_message_t message) +{ + /* FIXME: memory leak. */ + message_ty *mp = (message_ty *) message; + + if (mp->comment == NULL || mp->comment->nitems == 0) + return ""; + else + return string_list_join (mp->comment, '\n', '\n', true); +} + + +/* Change the comments for a message. + comments should be a multiline string, ending in a newline, or empty. */ + +void +po_message_set_comments (po_message_t message, const char *comments) +{ + message_ty *mp = (message_ty *) message; + string_list_ty *slp = string_list_alloc (); + + { + char *copy = xstrdup (comments); + char *rest; + + rest = copy; + while (*rest != '\0') + { + char *newline = strchr (rest, '\n'); + + if (newline != NULL) + { + *newline = '\0'; + string_list_append (slp, rest); + rest = newline + 1; + } + else + { + string_list_append (slp, rest); + break; + } + } + free (copy); + } + + if (mp->comment != NULL) + string_list_free (mp->comment); + + mp->comment = slp; +} + + +/* Return the extracted comments for a message. */ + +const char * +po_message_extracted_comments (po_message_t message) +{ + /* FIXME: memory leak. */ + message_ty *mp = (message_ty *) message; + + if (mp->comment_dot == NULL || mp->comment_dot->nitems == 0) + return ""; + else + return string_list_join (mp->comment_dot, '\n', '\n', true); +} + + +/* Return the i-th file position for a message, or NULL if i is out of + range. */ + +po_filepos_t +po_message_filepos (po_message_t message, int i) +{ + message_ty *mp = (message_ty *) message; + + if (i >= 0 && (size_t)i < mp->filepos_count) + return (po_filepos_t) &mp->filepos[i]; + else + return NULL; +} + + /* Return true if the message is marked obsolete. */ int @@ -291,6 +635,17 @@ po_message_is_obsolete (po_message_t message) } +/* Change the obsolete mark of a message. */ + +void +po_message_set_obsolete (po_message_t message, int obsolete) +{ + message_ty *mp = (message_ty *) message; + + mp->obsolete = obsolete; +} + + /* Return true if the message is marked fuzzy. */ int @@ -302,6 +657,17 @@ po_message_is_fuzzy (po_message_t message) } +/* Change the fuzzy mark of a message. */ + +void +po_message_set_fuzzy (po_message_t message, int fuzzy) +{ + message_ty *mp = (message_ty *) message; + + mp->is_fuzzy = fuzzy; +} + + /* Return true if the message is marked as being a format string of the given type (e.g. "c-format"). */ @@ -320,3 +686,57 @@ po_message_is_format (po_message_t message, const char *format_type) return (possible_format_p (mp->is_format[i]) ? 1 : 0); return 0; } + + +/* Change the format string mark for a given type of a message. */ + +void +po_message_set_format (po_message_t message, const char *format_type, /*bool*/int value) +{ + message_ty *mp = (message_ty *) message; + size_t len = strlen (format_type); + size_t i; + + if (len >= 7 && memcmp (format_type + len - 7, "-format", 7) == 0) + for (i = 0; i < NFORMATS; i++) + if (strlen (format_language[i]) == len - 7 + && memcmp (format_language[i], format_type, len - 7) == 0) + /* The given format_type corresponds to (enum format_type) i. */ + mp->is_format[i] = (value ? yes : no); +} + + +#if 0 +/* Test whether the message translation is a valid format string if the message + is marked as being a format string. Return NULL if valid or not marked as + such, or an explanation string if invalid. */ + +char * +po_message_check_format (po_message_t message, const char *format_type) +{ + ?? +} +#endif + + +/* Return the file name. */ + +const char * +po_filepos_file (po_filepos_t filepos) +{ + lex_pos_ty *pp = (lex_pos_ty *) filepos; + + return pp->file_name; +} + + +/* Return the line number where the string starts, or (size_t)(-1) if no line + number is available. */ + +size_t +po_filepos_start_line (po_filepos_t filepos) +{ + lex_pos_ty *pp = (lex_pos_ty *) filepos; + + return pp->line_number; +} diff --git a/gettext-tools/src/gettext-po.h b/gettext-tools/src/gettext-po.h index 875352270..e735652ae 100644 --- a/gettext-tools/src/gettext-po.h +++ b/gettext-tools/src/gettext-po.h @@ -1,5 +1,5 @@ /* Public API for GNU gettext PO files - contained in libgettextpo. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003-2004 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software; you can redistribute it and/or modify @@ -19,6 +19,8 @@ #ifndef _GETTEXT_PO_H #define _GETTEXT_PO_H 1 +#include + #ifdef __cplusplus extern "C" { #endif @@ -36,6 +38,40 @@ typedef struct po_message_iterator *po_message_iterator_t; /* A po_message_t represents a message in a PO file. */ typedef struct po_message *po_message_t; +/* A po_filepos_t represents a string's position within a source file. */ +typedef struct po_filepos *po_filepos_t; + +/* A po_error_handler handles error situations. */ +struct po_error_handler +{ + /* Signal an error. The error message is built from FORMAT and the following + arguments. ERRNUM, if nonzero, is an errno value. + Must increment the error_message_count variable declared in error.h. + Must not return if STATUS is nonzero. */ + void (*error) (int status, int errnum, + const char *format, ...); + + /* Signal an error. The error message is built from FORMAT and the following + arguments. The error location is at FILENAME line LINENO. ERRNUM, if + nonzero, is an errno value. + Must increment the error_message_count variable declared in error.h. + Must not return if STATUS is nonzero. */ + void (*error_at_line) (int status, int errnum, + const char *filename, unsigned int lineno, + const char *format, ...); + + /* Signal a multiline warning. The PREFIX applies to all lines of the + MESSAGE. Free the PREFIX and MESSAGE when done. */ + void (*multiline_warning) (char *prefix, char *message); + + /* Signal a multiline error. The PREFIX applies to all lines of the + MESSAGE. Free the PREFIX and MESSAGE when done. + Must increment the error_message_count variable declared in error.h if + PREFIX is non-NULL. */ + void (*multiline_error) (char *prefix, char *message); +}; +typedef const struct po_error_handler *po_error_handler_t; + /* Memory allocation: The memory allocations performed by these functions use xmalloc(), therefore will cause a program exit if memory is exhausted. @@ -45,9 +81,19 @@ typedef struct po_message *po_message_t; /* ============================= po_file_t API ============================= */ +/* Create an empty PO file representation in memory. */ +extern po_file_t po_file_create (void); + /* Read a PO file into memory. Return its contents. Upon failure, return NULL and set errno. */ -extern po_file_t po_file_read (const char *filename); +#define po_file_read po_file_read_v2 +extern po_file_t po_file_read (const char *filename, + po_error_handler_t handler); + +/* Write an in-memory PO file to a file. + Upon failure, return NULL and set errno. */ +extern po_file_t po_file_write (po_file_t file, const char *filename, + po_error_handler_t handler); /* Free a PO file from memory. */ extern void po_file_free (po_file_t file); @@ -82,34 +128,98 @@ extern void po_message_iterator_free (po_message_iterator_t iterator); Return NULL at the end of the message list. */ extern po_message_t po_next_message (po_message_iterator_t iterator); +/* Insert a message in a PO file in memory, in the domain and at the position + indicated by the iterator. The iterator thereby advances past the freshly + inserted message. */ +extern void po_message_insert (po_message_iterator_t iterator, po_message_t message); + /* =========================== po_message_t API ============================ */ +/* Return a freshly constructed message. + To finish initializing the message, you must set the msgid and msgstr. */ +extern po_message_t po_message_create (void); + /* Return the msgid (untranslated English string) of a message. */ extern const char * po_message_msgid (po_message_t message); +/* Change the msgid (untranslated English string) of a message. */ +extern void po_message_set_msgid (po_message_t message, const char *msgid); + /* Return the msgid_plural (untranslated English plural string) of a message, or NULL for a message without plural. */ extern const char * po_message_msgid_plural (po_message_t message); +/* Change the msgid_plural (untranslated English plural string) of a message. + NULL means a message without plural. */ +extern void po_message_set_msgid_plural (po_message_t message, const char *msgid_plural); + /* Return the msgstr (translation) of a message. Return the empty string for an untranslated message. */ extern const char * po_message_msgstr (po_message_t message); +/* Change the msgstr (translation) of a message. + Use an empty string to denote an untranslated message. */ +extern void po_message_set_msgstr (po_message_t message, const char *msgstr); + /* Return the msgstr[index] for a message with plural handling, or NULL when the index is out of range or for a message without plural. */ extern const char * po_message_msgstr_plural (po_message_t message, int index); +/* Change the msgstr[index] for a message with plural handling. + Use a NULL value at the end to reduce the number of plural forms. */ +extern void po_message_set_msgstr_plural (po_message_t message, int index, const char *msgstr); + +/* Return the comments for a message. */ +extern const char * po_message_comments (po_message_t message); + +/* Change the comments for a message. + comments should be a multiline string, ending in a newline, or empty. */ +extern void po_message_set_comments (po_message_t message, const char *comments); + +/* Return the extracted comments for a message. */ +extern const char * po_message_extracted_comments (po_message_t message); + +/* Return the i-th file position for a message, or NULL if i is out of + range. */ +extern po_filepos_t po_message_filepos (po_message_t message, int i); + /* Return true if the message is marked obsolete. */ extern int po_message_is_obsolete (po_message_t message); +/* Change the obsolete mark of a message. */ +extern void po_message_set_obsolete (po_message_t message, int obsolete); + /* Return true if the message is marked fuzzy. */ extern int po_message_is_fuzzy (po_message_t message); +/* Change the fuzzy mark of a message. */ +extern void po_message_set_fuzzy (po_message_t message, int fuzzy); + /* Return true if the message is marked as being a format string of the given type (e.g. "c-format"). */ extern int po_message_is_format (po_message_t message, const char *format_type); +/* Change the format string mark for a given type of a message. */ +extern void po_message_set_format (po_message_t message, const char *format_type, /*bool*/int value); + +#if 0 +/* Test whether the message translation is a valid format string if the message + is marked as being a format string. Return NULL if valid or not marked as + such, or an explanation string if invalid. */ +extern char * po_message_check_format (po_message_t message, const char *format_type); +#endif + + +/* =========================== po_filepos_t API ============================ */ + +/* Return the file name. */ +extern const char * po_filepos_file (po_filepos_t filepos); + +/* Return the line number where the string starts, or (size_t)(-1) if no line + number is available. */ +extern size_t po_filepos_start_line (po_filepos_t filepos); + #ifdef __cplusplus } diff --git a/gettext-tools/src/message.c b/gettext-tools/src/message.c index 94a4be6a7..c75aa16eb 100644 --- a/gettext-tools/src/message.c +++ b/gettext-tools/src/message.c @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -290,6 +290,32 @@ message_list_prepend (message_list_ty *mlp, message_ty *mp) } +void +message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp) +{ + size_t j; + + if (mlp->nitems >= mlp->nitems_max) + { + size_t nbytes; + + mlp->nitems_max = mlp->nitems_max * 2 + 4; + nbytes = mlp->nitems_max * sizeof (message_ty *); + mlp->item = xrealloc (mlp->item, nbytes); + } + for (j = mlp->nitems; j > n; j--) + mlp->item[j] = mlp->item[j - 1]; + mlp->item[j] = mp; + mlp->nitems++; + + if (mlp->use_hashtable) + if (insert_entry (&mlp->htable, mp->msgid, strlen (mp->msgid) + 1, mp)) + /* A message list has duplicates, although it was allocated with the + assertion that it wouldn't have duplicates. It is a bug. */ + abort (); +} + + #if 0 /* unused */ void message_list_delete_nth (message_list_ty *mlp, size_t n) diff --git a/gettext-tools/src/message.h b/gettext-tools/src/message.h index 33a6dacc1..ebbb848e6 100644 --- a/gettext-tools/src/message.h +++ b/gettext-tools/src/message.h @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -191,6 +191,8 @@ extern void message_list_append (message_list_ty *mlp, message_ty *mp); extern void message_list_prepend (message_list_ty *mlp, message_ty *mp); +extern void + message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp); extern void message_list_delete_nth (message_list_ty *mlp, size_t n); typedef bool message_predicate_ty (const message_ty *mp); diff --git a/gettext-tools/src/po-charset.c b/gettext-tools/src/po-charset.c index 4399a8607..ec7906d7a 100644 --- a/gettext-tools/src/po-charset.c +++ b/gettext-tools/src/po-charset.c @@ -1,5 +1,5 @@ /* Charset handling while reading PO files. - Copyright (C) 2001-2003 Free Software Foundation, Inc. + Copyright (C) 2001-2004 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software; you can redistribute it and/or modify @@ -30,6 +30,7 @@ #include "xallocsa.h" #include "xerror.h" +#include "po-error.h" #include "basename.h" #include "progname.h" #include "strstr.h" @@ -222,11 +223,11 @@ po_lex_charset_set (const char *header_entry, const char *filename) if (!(filenamelen >= 4 && memcmp (filename + filenamelen - 4, ".pot", 4) == 0 && strcmp (charset, "CHARSET") == 0)) - multiline_warning (xasprintf (_("%s: warning: "), filename), - xasprintf (_("\ + po_multiline_warning (xasprintf (_("%s: warning: "), filename), + xasprintf (_("\ Charset \"%s\" is not a portable encoding name.\n\ Message conversion to user's charset might not work.\n"), - charset)); + charset)); } else { @@ -292,22 +293,22 @@ Message conversion to user's charset might not work.\n"), else note = _("Continuing anyway."); - multiline_warning (xasprintf (_("%s: warning: "), filename), - xasprintf (_("\ + po_multiline_warning (xasprintf (_("%s: warning: "), filename), + xasprintf (_("\ Charset \"%s\" is not supported. %s relies on iconv(),\n\ and iconv() does not support \"%s\".\n"), - po_lex_charset, - basename (program_name), - po_lex_charset)); + po_lex_charset, + basename (program_name), + po_lex_charset)); # if !defined _LIBICONV_VERSION - multiline_warning (NULL, - xasprintf (_("\ + po_multiline_warning (NULL, + xasprintf (_("\ Installing GNU libiconv and then reinstalling GNU gettext\n\ would fix this problem.\n"))); # endif - multiline_warning (NULL, xasprintf (_("%s\n"), note)); + po_multiline_warning (NULL, xasprintf (_("%s\n"), note)); } #else /* Test for a charset which has double-byte characters @@ -320,19 +321,19 @@ would fix this problem.\n"))); const char *note = _("Continuing anyway, expect parse errors."); - multiline_warning (xasprintf (_("%s: warning: "), filename), - xasprintf (_("\ + po_multiline_warning (xasprintf (_("%s: warning: "), filename), + xasprintf (_("\ Charset \"%s\" is not supported. %s relies on iconv().\n\ This version was built without iconv().\n"), - po_lex_charset, - basename (program_name))); + po_lex_charset, + basename (program_name))); - multiline_warning (NULL, - xasprintf (_("\ + po_multiline_warning (NULL, + xasprintf (_("\ Installing GNU libiconv and then reinstalling GNU gettext\n\ would fix this problem.\n"))); - multiline_warning (NULL, xasprintf (_("%s\n"), note)); + po_multiline_warning (NULL, xasprintf (_("%s\n"), note)); } #endif } @@ -347,8 +348,8 @@ would fix this problem.\n"))); if (!(filenamelen >= 4 && memcmp (filename + filenamelen - 4, ".pot", 4) == 0)) - multiline_warning (xasprintf (_("%s: warning: "), filename), - xasprintf (_("\ + po_multiline_warning (xasprintf (_("%s: warning: "), filename), + xasprintf (_("\ Charset missing in header.\n\ Message conversion to user's charset will not work.\n"))); } diff --git a/gettext-tools/src/po-lex.c b/gettext-tools/src/po-lex.c index 8a5597827..1da40f908 100644 --- a/gettext-tools/src/po-lex.c +++ b/gettext-tools/src/po-lex.c @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller . Multibyte character handling by Bruno Haible . @@ -89,8 +89,8 @@ po_gram_error (const char *fmt, ...) error (EXIT_FAILURE, 0, _("memory exhausted")); va_end (ap); error_with_progname = false; - error (0, 0, "%s:%lu:%d: %s", gram_pos.file_name, - (unsigned long) gram_pos.line_number, gram_pos_column + 1, buffer); + po_error (0, 0, "%s:%lu:%d: %s", gram_pos.file_name, + (unsigned long) gram_pos.line_number, gram_pos_column + 1, buffer); error_with_progname = true; free (buffer); @@ -100,7 +100,7 @@ po_gram_error (const char *fmt, ...) if (*fmt == '.') --error_message_count; else if (error_message_count >= gram_max_allowed_errors) - error (EXIT_FAILURE, 0, _("too many errors, aborting")); + po_error (EXIT_FAILURE, 0, _("too many errors, aborting")); } /* CAUTION: If you change this function, you must also make identical @@ -118,7 +118,7 @@ po_gram_error_at_line (const lex_pos_ty *pp, const char *fmt, ...) error (EXIT_FAILURE, 0, _("memory exhausted")); va_end (ap); error_with_progname = false; - error_at_line (0, 0, pp->file_name, pp->line_number, "%s", buffer); + po_error_at_line (0, 0, pp->file_name, pp->line_number, "%s", buffer); error_with_progname = true; free (buffer); @@ -129,7 +129,7 @@ po_gram_error_at_line (const lex_pos_ty *pp, const char *fmt, ...) if (*fmt == '.') --error_message_count; else if (error_message_count >= gram_max_allowed_errors) - error (EXIT_FAILURE, 0, _("too many errors, aborting")); + po_error (EXIT_FAILURE, 0, _("too many errors, aborting")); } #endif @@ -501,7 +501,7 @@ incomplete multibyte sequence at end of line")); } } else - error (EXIT_FAILURE, errno, _("iconv failure")); + po_error (EXIT_FAILURE, errno, _("iconv failure")); } else { @@ -663,8 +663,8 @@ lex_getc (mbchar_t mbc) if (ferror (mbf->fp)) { bomb: - error (EXIT_FAILURE, errno, _("error while reading \"%s\""), - gram_pos.file_name); + po_error (EXIT_FAILURE, errno, _("error while reading \"%s\""), + gram_pos.file_name); } break; } diff --git a/gettext-tools/src/po-lex.h b/gettext-tools/src/po-lex.h index 12ee22528..10533e0ab 100644 --- a/gettext-tools/src/po-lex.h +++ b/gettext-tools/src/po-lex.h @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -25,8 +25,9 @@ #include #include "error.h" #include "error-progname.h" -#include "pos.h" #include "xerror.h" +#include "po-error.h" +#include "pos.h" #ifdef __cplusplus @@ -81,15 +82,15 @@ extern void po_lex_pass_obsolete_entries (bool flag); do { \ char *totalfmt = xasprintf ("%s%s", "%s:%lu:%d: ", fmt); \ error_with_progname = false; \ - error (0, 0, totalfmt, gram_pos.file_name, \ - (unsigned long) gram_pos.line_number, gram_pos_column + 1, \ - __VA_ARGS__ + 0); \ + po_error (0, 0, totalfmt, gram_pos.file_name, \ + (unsigned long) gram_pos.line_number, gram_pos_column + 1, \ + __VA_ARGS__ + 0); \ error_with_progname = true; \ free (totalfmt); \ if (*fmt == '.') \ --error_message_count; \ else if (error_message_count >= gram_max_allowed_errors) \ - error (1, 0, _("too many errors, aborting")); \ + po_error (1, 0, _("too many errors, aborting")); \ } while (0) /* CAUTION: If you change this macro, you must also make identical @@ -98,13 +99,13 @@ extern void po_lex_pass_obsolete_entries (bool flag); # define po_gram_error_at_line(pos, fmt, ...) \ do { \ error_with_progname = false; \ - error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \ - fmt, __VA_ARGS__ + 0); \ + po_error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \ + fmt, __VA_ARGS__ + 0); \ error_with_progname = true; \ if (*fmt == '.') \ --error_message_count; \ else if (error_message_count >= gram_max_allowed_errors) \ - error (1, 0, _("too many errors, aborting")); \ + po_error (1, 0, _("too many errors, aborting")); \ } while (0) /* GCC is also smart enough to allow optimizations like this. */ @@ -117,14 +118,14 @@ extern void po_lex_pass_obsolete_entries (bool flag); do { \ char *totalfmt = xasprintf ("%s%s", "%s:%d:%d: ", fmt); \ error_with_progname = false; \ - error (0, 0, totalfmt, gram_pos.file_name, gram_pos.line_number, \ - gram_pos_column + 1 , ## args); \ + po_error (0, 0, totalfmt, gram_pos.file_name, gram_pos.line_number, \ + gram_pos_column + 1 , ## args); \ error_with_progname = true; \ free (totalfmt); \ if (*fmt == '.') \ --error_message_count; \ else if (error_message_count >= gram_max_allowed_errors) \ - error (1, 0, _("too many errors, aborting")); \ + po_error (1, 0, _("too many errors, aborting")); \ } while (0) /* CAUTION: If you change this macro, you must also make identical @@ -133,13 +134,13 @@ extern void po_lex_pass_obsolete_entries (bool flag); # define po_gram_error_at_line(pos, fmt, args...) \ do { \ error_with_progname = false; \ - error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \ - fmt , ## args); \ + po_error_at_line (0, 0, (pos)->file_name, (pos)->line_number, \ + fmt , ## args); \ error_with_progname = true; \ if (*fmt == '.') \ --error_message_count; \ else if (error_message_count >= gram_max_allowed_errors) \ - error (1, 0, _("too many errors, aborting")); \ + po_error (1, 0, _("too many errors, aborting")); \ } while (0) #else diff --git a/gettext-tools/src/read-po-abstract.c b/gettext-tools/src/read-po-abstract.c index 0aa1300f5..1230a951b 100644 --- a/gettext-tools/src/read-po-abstract.c +++ b/gettext-tools/src/read-po-abstract.c @@ -1,5 +1,5 @@ /* Reading PO files, abstract class. - Copyright (C) 1995-1996, 1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1996, 1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -188,10 +188,10 @@ po_scan (abstract_po_reader_ty *pop, FILE *fp, } if (error_message_count > 0) - error (EXIT_FAILURE, 0, - ngettext ("found %d fatal error", "found %d fatal errors", - error_message_count), - error_message_count); + po_error (EXIT_FAILURE, 0, + ngettext ("found %d fatal error", "found %d fatal errors", + error_message_count), + error_message_count); error_message_count = 0; } diff --git a/gettext-tools/src/str-list.c b/gettext-tools/src/str-list.c index fb3244326..bcf14beb5 100644 --- a/gettext-tools/src/str-list.c +++ b/gettext-tools/src/str-list.c @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995, 1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995, 1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -176,11 +176,14 @@ string_list_concat_destroy (string_list_ty *slp) } -#if 0 /* unused */ /* Return a freshly allocated string obtained by concatenating all the - strings in the list, separated by spaces. */ + strings in the list, separated by the separator character, terminated + by the terminator character. The terminator character is not added if + drop_redundant_terminator is true and the last string already ends with + the terminator. */ char * -string_list_join (const string_list_ty *slp) +string_list_join (const string_list_ty *slp, char separator, + char terminator, bool drop_redundant_terminator) { size_t len; size_t j; @@ -190,24 +193,31 @@ string_list_join (const string_list_ty *slp) len = 1; for (j = 0; j < slp->nitems; ++j) { - if (j) + if (separator && j > 0) ++len; len += strlen (slp->item[j]); } + if (terminator) + ++len; result = (char *) xmalloc (len); pos = 0; for (j = 0; j < slp->nitems; ++j) { - if (j) - result[pos++] = ' '; + if (separator && j > 0) + result[pos++] = separator; len = strlen (slp->item[j]); memcpy (result + pos, slp->item[j], len); pos += len; } + if (terminator + && !(drop_redundant_terminator + && slp->nitems > 0 + && (len = strlen (slp->item[slp->nitems - 1])) > 0 + && slp->item[slp->nitems - 1][len - 1] == terminator)) + result[pos++] = terminator; result[pos] = '\0'; return result; } -#endif /* Return 1 if s is contained in the list of strings, 0 otherwise. */ diff --git a/gettext-tools/src/str-list.h b/gettext-tools/src/str-list.h index f316c9729..0787ebe34 100644 --- a/gettext-tools/src/str-list.h +++ b/gettext-tools/src/str-list.h @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995-1996, 1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1996, 1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -69,11 +69,13 @@ extern char *string_list_concat (const string_list_ty *slp); strings in the list, and destroy the list. */ extern char *string_list_concat_destroy (string_list_ty *slp); -#if 0 /* unused */ /* Return a freshly allocated string obtained by concatenating all the - strings in the list, separated by spaces. */ -extern char *string_list_join (const string_list_ty *slp); -#endif + strings in the list, separated by the separator character, terminated + by the terminator character. The terminator character is not added if + drop_redundant_terminator is true and the last string already ends with + the terminator. */ +extern char *string_list_join (const string_list_ty *slp, char separator, + char terminator, bool drop_redundant_terminator); /* Return 1 if s is contained in the list of strings, 0 otherwise. */ extern bool string_list_member (const string_list_ty *slp, const char *s); diff --git a/gettext-tools/src/write-po.c b/gettext-tools/src/write-po.c index 201aa38b6..01dd0ff22 100644 --- a/gettext-tools/src/write-po.c +++ b/gettext-tools/src/write-po.c @@ -1,5 +1,5 @@ /* GNU gettext - internationalization aids - Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2004 Free Software Foundation, Inc. This file was written by Peter Miller @@ -47,8 +47,8 @@ #include "fwriteerror.h" #include "exit.h" #include "error-progname.h" -#include "error.h" #include "xerror.h" +#include "po-error.h" #include "gettext.h" /* Our regular abbreviation. */ @@ -552,7 +552,7 @@ wrap (FILE *fp, const char *line_prefix, const char *name, const char *value, { if (errno == EILSEQ) { - error (0, 0, _("invalid multibyte sequence")); + po_error (0, 0, _("invalid multibyte sequence")); continue; } else @@ -603,9 +603,9 @@ wrap (FILE *fp, const char *line_prefix, const char *name, const char *value, /* We warn about any use of escape sequences beside '\n' and '\t'. */ if (c != 'n' && c != 't') - error (0, 0, _("\ + po_error (0, 0, _("\ internationalized messages should not contain the `\\%c' escape sequence"), - c); + c); } else if (escape && !c_isprint ((unsigned char) c)) { @@ -658,7 +658,7 @@ internationalized messages should not contain the `\\%c' escape sequence"), { if (errno == EILSEQ) { - error (0, 0, _("invalid multibyte sequence")); + po_error (0, 0, _("invalid multibyte sequence")); continue; } else @@ -848,8 +848,8 @@ message_print (const message_ty *mp, FILE *fp, const char *charset, this domain, emit an empty string. */ if (!is_ascii_string (mp->msgid) && po_charset_canonicalize (charset) != po_charset_utf8) - multiline_warning (xasprintf (_("warning: ")), - xasprintf (_("\ + po_multiline_warning (xasprintf (_("warning: ")), + xasprintf (_("\ The following msgid contains non-ASCII characters.\n\ This will cause problems to translators who use a character encoding\n\ different from yours. Consider using a pure ASCII msgid instead.\n\ @@ -914,8 +914,8 @@ message_print_obsolete (const message_ty *mp, FILE *fp, const char *charset, are as readable as possible. */ if (!is_ascii_string (mp->msgid) && po_charset_canonicalize (charset) != po_charset_utf8) - multiline_warning (xasprintf (_("warning: ")), - xasprintf (_("\ + po_multiline_warning (xasprintf (_("warning: ")), + xasprintf (_("\ The following msgid contains non-ASCII characters.\n\ This will cause problems to translators who use a character encoding\n\ different from yours. Consider using a pure ASCII msgid instead.\n\ @@ -1060,9 +1060,9 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename, if (mdlp->nitems > 1) { if (use_syntax_properties) - error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with Java .properties syntax. Try using PO file syntax instead.")); + po_error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with Java .properties syntax. Try using PO file syntax instead.")); if (use_syntax_stringtable) - error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with NeXTstep/GNUstep .strings syntax.")); + po_error (EXIT_FAILURE, 0, _("Cannot output multiple translation domains into a single file with NeXTstep/GNUstep .strings syntax.")); } if (mdlp->nitems == 1) { @@ -1086,13 +1086,13 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename, { error_with_progname = false; if (use_syntax_properties) - error_at_line (EXIT_FAILURE, 0, - has_plural->file_name, has_plural->line_number, - _("message catalog has plural form translations, but the output format does not support them. Try generating a Java class using \"msgfmt --java\", instead of a properties file.")); + po_error_at_line (EXIT_FAILURE, 0, + has_plural->file_name, has_plural->line_number, + _("message catalog has plural form translations, but the output format does not support them. Try generating a Java class using \"msgfmt --java\", instead of a properties file.")); if (use_syntax_stringtable) - error_at_line (EXIT_FAILURE, 0, - has_plural->file_name, has_plural->line_number, - _("message catalog has plural form translations, but the output format does not support them.")); + po_error_at_line (EXIT_FAILURE, 0, + has_plural->file_name, has_plural->line_number, + _("message catalog has plural form translations, but the output format does not support them.")); error_with_progname = true; } } @@ -1104,8 +1104,8 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename, { fp = fopen (filename, "w"); if (fp == NULL) - error (EXIT_FAILURE, errno, _("cannot create output file \"%s\""), - filename); + po_error (EXIT_FAILURE, errno, _("cannot create output file \"%s\""), + filename); } else { @@ -1123,8 +1123,8 @@ msgdomain_list_print (msgdomain_list_ty *mdlp, const char *filename, /* Make sure nothing went wrong. */ if (fwriteerror (fp)) - error (EXIT_FAILURE, errno, _("error while writing \"%s\" file"), - filename); + po_error (EXIT_FAILURE, errno, _("error while writing \"%s\" file"), + filename); if (fp != stdout) fclose (fp); diff --git a/gettext-tools/windows/gettextpo.def b/gettext-tools/windows/gettextpo.def index 1dfb2d61f..a5440699e 100644 --- a/gettext-tools/windows/gettextpo.def +++ b/gettext-tools/windows/gettextpo.def @@ -1,10 +1,20 @@ LIBRARY gettextpo EXPORTS +po_file_create po_file_domains po_file_domain_header po_file_free po_file_read +po_file_read_v2 +po_file_write +po_filepos_file +po_filepos_start_line po_header_field +po_message_comments +po_message_create +po_message_extracted_comments +po_message_filepos +po_message_insert po_message_is_format po_message_is_fuzzy po_message_is_obsolete @@ -14,4 +24,12 @@ po_message_msgid po_message_msgid_plural po_message_msgstr po_message_msgstr_plural +po_message_set_comments +po_message_set_format +po_message_set_fuzzy +po_message_set_msgid +po_message_set_msgid_plural +po_message_set_msgstr +po_message_set_msgstr_plural +po_message_set_obsolete po_next_message diff --git a/gettext-tools/windows/gettextsrc.def b/gettext-tools/windows/gettextsrc.def index 008620b9d..e10c24778 100644 --- a/gettext-tools/windows/gettextsrc.def +++ b/gettext-tools/windows/gettextsrc.def @@ -35,10 +35,14 @@ plural_table plural_table_size po_charset_ascii po_charset_utf8 +po_error +po_error_at_line po_gram_lval po_lex_charset po_lex_iconv po_lex_weird_cjk +po_multiline_error +po_multiline_warning use_first catenate_msgdomain_list compare_po_locale_charsets