diff options
author | Bruno Haible <bruno@clisp.org> | 2003-02-10 21:07:22 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:08:57 +0200 |
commit | 381a0c0f9e065a81ddcba07ffb2baf3e0a3e60b0 (patch) | |
tree | 964d67ebcb446255b3c4288f73cae48e2875d4dc | |
parent | bdc66caf57fde3fd4c8feee4926b826851aa0a36 (diff) | |
download | external_gettext-381a0c0f9e065a81ddcba07ffb2baf3e0a3e60b0.zip external_gettext-381a0c0f9e065a81ddcba07ffb2baf3e0a3e60b0.tar.gz external_gettext-381a0c0f9e065a81ddcba07ffb2baf3e0a3e60b0.tar.bz2 |
New library libgettextpo.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | PACKAGING | 2 | ||||
-rw-r--r-- | doc/ChangeLog | 4 | ||||
-rw-r--r-- | doc/gettext.texi | 136 | ||||
-rw-r--r-- | src/ChangeLog | 9 | ||||
-rw-r--r-- | src/Makefile.am | 19 | ||||
-rw-r--r-- | src/gettext-po.c | 210 | ||||
-rw-r--r-- | src/gettext-po.h | 95 |
9 files changed, 483 insertions, 2 deletions
@@ -1,3 +1,7 @@ +2003-01-31 Bruno Haible <bruno@clisp.org> + + * PACKAGING: Add gettext-po.h and libgettextpo*. + 2003-01-03 Albert Chin <libtool@thewrittenword.com> * ltmain.sh: Don't pass -R flags found in a .la's dependency_libs @@ -6,6 +6,12 @@ Version 0.11.6 - October 2002 strings in C++. This is needed for proper internationalization of C++ programs. +* A new include file libgettextpo, with public header file "gettext-po.h", + provides functions for reading PO files into memory. It is useful for + applying PO files to areas not covered by the GNU gettext programs. + New documentation section: + - Writing your own programs that process PO files. + * xgettext now supports msgid strings in other encodings than ASCII. xgettext has a new option --from-code that specifies the encoding of the source files. The resulting POT files are UTF-8 encoded. @@ -64,8 +64,10 @@ following file list. $prefix/doc/libasprintf/autosprintf.html $prefix/info/gettext.info* $prefix/info/autosprintf.info + $prefix/include/gettext-po.h $prefix/lib/libgettextlib* $prefix/lib/libgettextsrc* + $prefix/lib/libgettextpo* $prefix/lib/gettext/* $prefix/share/locale/*/LC_MESSAGES/gettext.mo $prefix/share/gettext/config.rpath diff --git a/doc/ChangeLog b/doc/ChangeLog index b5447e1..38ed3b0 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2003-01-31 Bruno Haible <bruno@clisp.org> + + * gettext.texi (libgettextpo): New node. + 2003-01-24 Bruno Haible <bruno@clisp.org> * msgattrib.texi: Document options --only-file and --ignore-file. diff --git a/doc/gettext.texi b/doc/gettext.texi index 6bad1e3..cd9bd6a 100644 --- a/doc/gettext.texi +++ b/doc/gettext.texi @@ -212,6 +212,7 @@ Manipulating PO Files * msgattrib Invocation:: Invoking the @code{msgattrib} Program * msgen Invocation:: Invoking the @code{msgen} Program * msgexec Invocation:: Invoking the @code{msgexec} Program +* libgettextpo:: Writing your own programs that process PO files Producing Binary MO Files @@ -3637,6 +3638,10 @@ or untranslated messages of a translation catalog. @samp{msgen} is useful as a first step for preparing English translation catalogs. It copies each message's msgid to its msgstr. +Finally, for those applications where all these various programs are not +sufficient, a library @samp{libgettextpo} is provided that can be used to +write other specialized programs that process PO files. + @menu * msgcat Invocation:: Invoking the @code{msgcat} Program * msgconv Invocation:: Invoking the @code{msgconv} Program @@ -3648,6 +3653,7 @@ catalogs. It copies each message's msgid to its msgstr. * msgattrib Invocation:: Invoking the @code{msgattrib} Program * msgen Invocation:: Invoking the @code{msgen} Program * msgexec Invocation:: Invoking the @code{msgexec} Program +* libgettextpo:: Writing your own programs that process PO files @end menu @node msgcat Invocation, msgconv Invocation, Manipulating, Manipulating @@ -3695,11 +3701,139 @@ catalogs. It copies each message's msgid to its msgstr. @include msgen.texi -@node msgexec Invocation, , msgen Invocation, Manipulating +@node msgexec Invocation, libgettextpo, msgen Invocation, Manipulating @section Invoking the @code{msgexec} Program @include msgexec.texi +@node libgettextpo, , msgexec Invocation, Manipulating +@section Writing your own programs that process PO files + +For the tasks for which a combination of @samp{msgattrib}, @samp{msgcat} etc. +is not sufficient, a set of C functions is provided in a library, to make it +possible to process PO files in your own programs. When you use this library, +you don't need to write routines to parse the PO file; instead, you retreive +a pointer in memory to each of messages contained in the PO file. Functions +for writing PO files are not provided at this time. + +The functions are declared in the header file @samp{<gettext-po.h>}, and are +defined in a library called @samp{libgettextpo}. + +@deftp {Data Type} po_file_t +This is a pointer type that refers to the contents of a PO file, after it has +been read into memory. +@end deftp + +@deftp {Data Type} po_message_iterator_t +This is a pointer type that refers to an iterator that produces a sequence of +messages. +@end deftp + +@deftp {Data Type} po_message_t +This is a pointer type that refers to a message of a PO file, including its +translation. +@end deftp + +@deftypefun po_file_t po_file_read (const char *@var{filename}) +The @code{po_file_read} function reads a PO file into memory. The file name +is given as argument. The return value is a handle to the PO file's contents, +valid until @code{po_file_free} is called on it. In case of error, the return +value is @code{NULL}, and @code{errno} is set. +@end deftypefun + +@deftypefun void po_file_free (po_file_t @var{file}) +The @code{po_file_free} function frees a PO file's contents from memory, +including all messages that are only implicitly accessible through iterators. +@end deftypefun + +@deftypefun {const char * const *} po_file_domains (po_file_t @var{file}) +The @code{po_file_domains} function returns the domains for which the given +PO file has messages. The return value is a @code{NULL} terminated array +which is valid as long as the @var{file} handle is valid. For PO files which +contain no @samp{domain} directive, the return value contains only one domain, +namely the default domain @code{"messages"}. +@end deftypefun + +@deftypefun po_message_iterator_t po_message_iterator (po_file_t @var{file}, const char *@var{domain}) +The @code{po_message_iterator} returns an iterator that will produce the +messages of @var{file} that belong to the given @var{domain}. If @var{domain} +is @code{NULL}, the default domain is used instead. To list the messages, +use the function @code{po_next_message} repeatedly. +@end deftypefun + +@deftypefun void po_message_iterator_free (po_message_iterator_t @var{iterator}) +The @code{po_message_iterator_free} function frees an iterator previously +allocated through the @code{po_message_iterator} function. +@end deftypefun + +@deftypefun po_message_t po_next_message (po_message_iterator_t @var{iterator}) +The @code{po_next_message} function returns the next message from +@var{iterator} and advances the iterator. It returns @code{NULL} when the +iterator has reached the end of its message list. +@end deftypefun + +The following functions returns details of a @code{po_message_t}. Recall +that the results are valid as long as the @var{file} handle is valid. + +@deftypefun {const char *} po_message_msgid (po_message_t @var{message}) +The @code{po_message_msgid} function returns the @code{msgid} (untranslated +English string) of a message. This is guaranteed to be non-@code{NULL}. +@end deftypefun + +@deftypefun {const char *} po_message_msgid_plural (po_message_t @var{message}) +The @code{po_message_msgid_plural} function returns the @code{msgid_plural} +(untranslated English plural string) of a message with plurals, or @code{NULL} +for a message without plural. +@end deftypefun + +@deftypefun {const char *} po_message_msgstr (po_message_t @var{message}) +The @code{po_message_msgstr} function returns the @code{msgstr} (translation) +of a message. For an untranslated message, the return value is an empty +string. +@end deftypefun + +@deftypefun {const char *} po_message_msgstr_plural (po_message_t @var{message}, int @var{index}) +The @code{po_message_msgstr_plural} function returns the +@code{msgstr[@var{index}]} of a message with plurals, or @code{NULL} when +the @var{index} is out of range or for a message without plural. +@end deftypefun + +Here is an example code how these functions can be used. + +@example +const char *filename = @dots{}; +po_file_t file = po_file_read (filename); + +if (file == NULL) + error (EXIT_FAILURE, errno, "couldn't open the PO file %s", filename); +@{ + const char * const *domains = po_file_domains (file); + const char * const *domainp; + + for (domainp = domains; *domainp; domainp++) + @{ + const char *domain = *domainp; + po_message_iterator_t iterator = po_message_iterator (file, domain); + + for (;;) + @{ + po_message_t *message = po_next_message (iterator); + + if (message == NULL) + break; + @{ + const char *msgid = po_message_msgid (message); + const char *msgstr = po_message_msgstr (message); + + @dots{} + @} + @} + po_message_iterator_free (iterator); + @} +@} +po_file_free (file); +@end example + @node Binaries, Users, Manipulating, Top @chapter Producing Binary MO Files diff --git a/src/ChangeLog b/src/ChangeLog index 71c8c27..1f86671 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2003-01-31 Bruno Haible <bruno@clisp.org> + + * gettext-po.h: New file. + * gettext-po.c: New file. + * Makefile.am (lib_LTLIBRARIES): Add libgettextpo.la. + (include_HEADERS): New variable. + (libgettextpo_la_SOURCES, libgettextpo_la_LDFLAGS): New variables. + (LTV_CURRENT, LTV_REVISION, LTV_AGE): New variables. + 2003-01-24 Bruno Haible <bruno@clisp.org> * msgattrib.c (long_options): Add --only-file and --ignore-file. diff --git a/src/Makefile.am b/src/Makefile.am index f5910de..9652fa0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,7 +30,9 @@ msgattrib msgcat msgcomm msgconv msgen msgexec msgfilter msggrep msginit msguniq noinst_PROGRAMS = hostname urlget -lib_LTLIBRARIES = libgettextsrc.la +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 \ po.h open-po.h read-po.h str-list.h write-po.h dir-list.h file-list.h \ @@ -86,6 +88,14 @@ $(COMMON_SOURCE) read-po.c write-po.c msgl-ascii.c msgl-iconv.c msgl-equal.c \ msgl-cat.c msgl-english.c file-list.c msgl-charset.c po-time.c plural.c \ plural-table.c $(FORMAT_SOURCE) +# libgettextpo contains the public API for PO files. +libgettextpo_la_SOURCES = gettext-po.c +# Libtool's library version information for libgettextpo. +# See the libtool documentation, section "Library interface versions". +LTV_CURRENT=0 +LTV_REVISION=0 +LTV_AGE=0 + # x-python needs table of Unicode character names. LIBUNINAME = ../libuniname/libuniname.a @@ -126,6 +136,13 @@ install-exec-am: install-exec-clean install-exec-clean: $(RM) $(DESTDIR)$(libdir)/libgettextsrc.a +# How to build libgettextpo.la. +# Need libgettextsrc.la. +libgettextpo_la_LDFLAGS = \ + -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \ + -rpath $(libdir) \ + libgettextsrc.la -lc -no-undefined + # Link dependencies. gettext_LDADD = ../lib/basename.lo ../lib/error.lo ../lib/getopt.lo ../lib/getopt1.lo ../lib/strtoul.lo ../lib/xmalloc.lo @LTLIBINTL@ ngettext_LDADD = ../lib/basename.lo ../lib/error.lo ../lib/getopt.lo ../lib/getopt1.lo ../lib/strtoul.lo ../lib/xmalloc.lo @LTLIBINTL@ diff --git a/src/gettext-po.c b/src/gettext-po.c new file mode 100644 index 0000000..85dc4ac --- /dev/null +++ b/src/gettext-po.c @@ -0,0 +1,210 @@ +/* Public API for GNU gettext PO files. + Copyright (C) 2003 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Specification. */ +#include "gettext-po.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "message.h" +#include "xmalloc.h" +#include "read-po.h" + + +struct po_file +{ + msgdomain_list_ty *mdlp; + const char *real_filename; + const char *logical_filename; + const char **domains; +}; + +struct po_message_iterator +{ + message_list_ty *mlp; + size_t index; +}; + +/* A po_message_t is actually a 'struct message_ty *'. */ + + +/* 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) +{ + FILE *fp; + po_file_t file; + + 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; +} + + +/* Free a PO file from memory. */ + +void +po_file_free (po_file_t file) +{ + msgdomain_list_free (file->mdlp); + if (file->domains != NULL) + free (file->domains); + free (file); +} + + +/* Return the names of the domains covered by a PO file in memory. */ + +const char * const * +po_file_domains (po_file_t file) +{ + if (file->domains == NULL) + { + size_t n = file->mdlp->nitems; + const char **domains = + (const char **) xmalloc ((n + 1) * sizeof (const char *)); + size_t j; + + for (j = 0; j < n; j++) + domains[j] = file->mdlp->item[j]->domain; + domains[n] = NULL; + + file->domains = domains; + } + + return file->domains; +} + + +/* Create an iterator for traversing a domain of a PO file in memory. + The domain NULL denotes the default domain. */ + +po_message_iterator_t +po_message_iterator (po_file_t file, const char *domain) +{ + po_message_iterator_t iterator; + + if (domain == NULL) + domain = MESSAGE_DOMAIN_DEFAULT; + + iterator = + (struct po_message_iterator *) + xmalloc (sizeof (struct po_message_iterator)); + iterator->mlp = msgdomain_list_sublist (file->mdlp, domain, false); + iterator->index = 0; + + return iterator; +} + + +/* Free an iterator. */ + +void +po_message_iterator_free (po_message_iterator_t iterator) +{ + free (iterator); +} + + +/* Return the next message, and advance the iterator. + Return NULL at the end of the message list. */ + +po_message_t +po_next_message (po_message_iterator_t iterator) +{ + if (iterator->index < iterator->mlp->nitems) + return (po_message_t) iterator->mlp->item[iterator->index++]; + else + return NULL; +} + + +/* Return the msgid (untranslated English string) of a message. */ + +const char * +po_message_msgid (po_message_t message) +{ + message_ty *mp = (message_ty *) message; + + return mp->msgid; +} + + +/* Return the msgid_plural (untranslated English plural string) of a message, + or NULL for a message without plural. */ + +const char * +po_message_msgid_plural (po_message_t message) +{ + message_ty *mp = (message_ty *) message; + + return mp->msgid_plural; +} + + +/* Return the msgstr (translation) of a message. + Return the empty string for an untranslated message. */ + +const char * +po_message_msgstr (po_message_t message) +{ + message_ty *mp = (message_ty *) message; + + return mp->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. */ + +const char * +po_message_msgstr_plural (po_message_t message, int index) +{ + message_ty *mp = (message_ty *) message; + + if (mp->msgid_plural != NULL && index >= 0) + { + const char *p; + const char *p_end = mp->msgstr + mp->msgstr_len; + + for (p = mp->msgstr; ; p += strlen (p) + 1, index--) + { + if (p >= p_end) + return NULL; + if (index == 0) + break; + } + return p; + } + else + return NULL; +} diff --git a/src/gettext-po.h b/src/gettext-po.h new file mode 100644 index 0000000..27788e6 --- /dev/null +++ b/src/gettext-po.h @@ -0,0 +1,95 @@ +/* Public API for GNU gettext PO files - contained in libgettextpo. + Copyright (C) 2003 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _GETTEXT_PO_H +#define _GETTEXT_PO_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ================================= Types ================================= */ + +/* A po_file_t represents the contents of a PO file. */ +typedef struct po_file *po_file_t; + +/* A po_message_iterator_t represents an iterator through a domain of a + PO file. */ +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; + +/* Memory allocation: + The memory allocations performed by these functions use xmalloc(), + therefore will cause a program exit if memory is exhausted. + The memory allocated by po_file_read, and implicitly returned through + the po_message_* functions, lasts until freed with po_file_free. */ + + +/* ============================= po_file_t API ============================= */ + +/* 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); + +/* Free a PO file from memory. */ +extern void po_file_free (po_file_t file); + +/* Return the names of the domains covered by a PO file in memory. */ +extern const char * const * po_file_domains (po_file_t file); + + +/* ======================= po_message_iterator_t API ======================= */ + +/* Create an iterator for traversing a domain of a PO file in memory. + The domain NULL denotes the default domain. */ +extern po_message_iterator_t po_message_iterator (po_file_t file, const char *domain); + +/* Free an iterator. */ +extern void po_message_iterator_free (po_message_iterator_t iterator); + +/* Return the next message, and advance the iterator. + Return NULL at the end of the message list. */ +extern po_message_t po_next_message (po_message_iterator_t iterator); + + +/* =========================== po_message_t API ============================ */ + +/* Return the msgid (untranslated English string) of a message. */ +extern const char * po_message_msgid (po_message_t message); + +/* 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); + +/* 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); + +/* 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); + + +#ifdef __cplusplus +} +#endif + +#endif /* _GETTEXT_PO_H */ |