pax_global_header00006660000000000000000000000064136705133120014513gustar00rootroot0000000000000052 comment=9b7afc702bccace9a544b8efa2a28bc2b13371ed ocaml-gettext-0.4.2/000077500000000000000000000000001367051331200142735ustar00rootroot00000000000000ocaml-gettext-0.4.2/.gitignore000066400000000000000000000001441367051331200162620ustar00rootroot00000000000000/_build/ /configure /dist/ /po/*.mo /po/fr.po.bak /test/test /test/tests/ *.merlin /*.install *.swp ocaml-gettext-0.4.2/.headache.config000066400000000000000000000055201367051331200172640ustar00rootroot00000000000000########################################################################## # ocaml-gettext : a library to translate messages # # # # Copyright (C) 2003-2007 Sylvain Le Gall # # # # This library is free software; you can redistribute it and/or # # modify it under the terms of the GNU Lesser General Public # # License as published by the Free Software Foundation; either # # version 2.1 of the License, or (at your option) any later version; # # with the OCaml static compilation exception. # # # # This library 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 # # Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public # # License along with this library; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # # USA # ########################################################################## | ".*README.*" -> no | ".*COPYING.*" -> no | ".*\.doap" -> skip match:"<\?xml.*>" | ".*\.doap" -> lines open:"" | ".*\.xml" -> skip match:"<\?xml.*>" | ".*\.xml" -> lines open:"" | ".*\.patch" -> no | "CHANGELOG" -> no | "THANKS" -> no | "TODO" -> no | "install-sh" -> no | "missing" -> no | "configure" -> no | "INSTALL" -> no | "configure.in" -> frame open:"dnl *" line:"*" close:"*" | "aclocal.m4" -> frame open:"#" line:"#" close:"#" | ".*\\.ml\\.in" -> frame open:"(*" line:"*" close:"*)" | ".*\\.ml" -> skip match:"(\\*pp .* \\*)" | "\\.headache\\.config" -> frame open:"#" line:"#" close:"#" | ".*\\.swp" -> no | ".*\\.po" -> no | ".*\\.mo" -> no | "META" -> frame open:"#" line:"#" close:"#" | "META.in" -> frame open:"#" line:"#" close:"#" | "\\.announce" -> no | "POTFILES" -> no | "LINGUAS" -> no | ".*\\.pot" -> no | ".*\\.png" -> no | "\\.header" -> no ocaml-gettext-0.4.2/.header000066400000000000000000000015251367051331200155270ustar00rootroot00000000000000ocaml-gettext: a library to translate messages Copyright (C) 2003-2007 Sylvain Le Gall This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version; with the OCaml static compilation exception. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ocaml-gettext-0.4.2/.ocamlformat000066400000000000000000000000271367051331200165770ustar00rootroot00000000000000profile = conventional ocaml-gettext-0.4.2/.travis.yml000066400000000000000000000021621367051331200164050ustar00rootroot00000000000000language: c sudo: required install: test -e .travis.opam.sh || wget https://raw.githubusercontent.com/ocaml/ocaml-ci-scripts/master/.travis-opam.sh script: bash -ex .travis-opam.sh env: global: - OUNIT_CI=true PINS="gettext.0.4.0:. gettext-stub.0.4.0:. gettext-camomile.0.4.0:." addons: homebrew: update: true cache: directories: - $HOME/Library/Caches/Homebrew matrix: include: - name: "gettext: reverse dependencies with linux" os: linux env: OCAML_VERSION=4.08 PACKAGE="gettext" REVDEPS="true" - name: "gettext-stub: reverse dependencies with linux" os: linux env: OCAML_VERSION=4.08 PACKAGE="gettext-stub" REVDEPS="true" - name: "gettext-camomile: reverse dependencies with linux" os: linux env: OCAML_VERSION=4.08 PACKAGE="gettext-camomile" REVDEPS="true" - name: "gettext: MacOSX" os: osx env: OCAML_VERSION=4.08 PACKAGE="gettext" - name: "gettext-stub: MacOSX" os: osx env: OCAML_VERSION=4.08 PACKAGE="gettext-stub" - name: "gettext-camomile: MacOSX" os: osx env: OCAML_VERSION=4.08 PACKAGE="gettext-camomile" ocaml-gettext-0.4.2/CHANGES.md000066400000000000000000000063301367051331200156670ustar00rootroot00000000000000## v0.4.2 - 2020-06-11 ### Fixed - Compatibility with OCaml 4.11. (Thanks to kit-ty-kate, closes: #8) ## v0.4.1 - 2019-10-02 ### Fixed - Improve documentation layout. - Set minimum version of OCaml to 4.03. - Add depext for Alpine Linux. ## v0.4.0 - 2019-10-02 ### Changed - Migrate build system to dune and opam. - Make the package available on Linux, MacOSX and Windows. - Reformat the documentation to use GitHub compatible Markdown. ### Fixed - Move ocaml-xgettext from Camlp4 to ppx (thanks to Richard W.M. Jones). ## v0.3.8 - 2017-11-12 - Replace string by bytes, for compability with OCAml 4.06. ## v0.3.7 - 2017-03-01 - Add an extra step to generate configure. ## v0.3.6 - 2017-02-26 - Remove unix.cma linking argument for 4.0{3,4} compatibility ## v0.3.5 - 2014-08-04 - Always use format_of_string to not segfault with OCaml 4.02. ## v0.3.4 - 2011-08-09 - Use camomile 0.8.3 ## v0.3.3 - 2009-11-01 - Upgrade ocaml-fileutils 0.4.0 - Improve gettext-stub C parts (memory management) - Correctly handle OCaml string, wrt of escape char (Closes: FS#70) - Remove the right file when uninstalling (Closes: FS#61) - Enforce type safety for format string and plural (Closes: FS#72) - Only output warning for install check that can be handle afterwards i (Closes: FS#74) - Add a --strict flag to ocaml-gettext to make an error for every install check failed. - Take into account Windows eol '\r' when parsing comments (Closes: FS#75) - Don't include empty translation (Closes: FS#90) - Check returned format string for fdgettext (Closes: FS#91) ## v0.3.2 - 2008-06-05 - Fix bug when buggy LANG/LC_ALL is set, using gettext stub (Richard W.M. Jones) ## v0.3.1 - 2008-05-09 - Fix bug when no LANG or LC_ALL is set - Better autoconf use of @VERSION@ - Only remove build dir in top Makefile ## v0.3.0 - 2008-04-29 - Get rid of ocaml-ast-analyze (Richard W.M. Jones) - Port of camlp4 extension to OCaml 3.10.1 (Richard W.M. Jones) - Compile with camomile 0.7.1 (Richar W.M. Jones) - Check dependency on ocaml-fileutils in configure - Add --disable-doc-pdf to configure, to allow building doc without PDF (and fop) - Get rid of camlidl - Distribute .mli and .cmx file - Handle multiline comment when merging, especially location "#:" and special comment "#," - Partially handle UTF-8, by not escaping string using "Printf.fprintf "%S"" but by using the same rule as the one used for reading escaped string - Rework build system to: - use "install" programm to create dir and copy files - use --docdir and --prefix from configure - Don't build PDF document by default - Install documentation in $docdir/html/{api|api-ref|reference-manual} - Fix typo in documentation ## v0.2.0 - Full rewrite of ocaml-gettext. - Contains two version of the gettext engine : one is based on a purely OCaml approach (gettext-camomile), one is base on the former one (gettext-stub). - The two engines shared a common interface based on gettext.base module. - Most of the encoding/settings choice are accessible through command line option. - Simplify the functions to accesse to gettext : 4 functions to translate - Rebuild the string extractor with as a camlp4 analyzer - Write test and benchmark program for maintaing the quality - Write an example - Write a manual ocaml-gettext-0.4.2/LICENSE.txt000066400000000000000000000665171367051331200161350ustar00rootroot00000000000000The Library is distributed under the terms of the GNU Library General Public License version 2 (found in /usr/share/common-licenses/LGPL-2 on debian systems). As a special exception to the GNU Library General Public License, you may link, statically or dynamically, a "work that uses the Library" with a publicly distributed version of the Library to produce an executable file containing portions of the Library, and distribute that executable file under terms of your choice, without any of the additional requirements listed in clause 6 of the GNU Library General Public License. By "a publicly distributed version of the Library", we mean either the unmodified Library as distributed by INRIA, or a modified version of the Library that is distributed under the conditions defined in clause 3 of the GNU Library General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Library General Public License. ----------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. ^L Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. ^L GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. ^L Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. ^L 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. ^L 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. ^L 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. ^L 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ^L How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ######################## # File test/utf8-ja.po # ######################## This file has been extracted for testing purpose from virt-p2v. Here is the copyright notice: # Japanese translations for virt-p2v package. # Copyright (C) 2008 THE virt-p2v'S COPYRIGHT HOLDER # This file is distributed under the same license as the virt-p2v package. # Richard Jones , 2008. ocaml-gettext-0.4.2/Makefile000066400000000000000000000047371367051331200157460ustar00rootroot00000000000000########################################################################## # ocaml-gettext: a library to translate messages # # # # Copyright (C) 2003-2008 Sylvain Le Gall # # # # This library is free software; you can redistribute it and/or # # modify it under the terms of the GNU Lesser General Public # # License as published by the Free Software Foundation; either # # version 2.1 of the License, or (at your option) any later version; # # with the OCaml static compilation exception. # # # # This library 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 # # Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public # # License along with this library; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # # USA # ########################################################################## default: build test GENERATED_FILES=src/lib/gettext/base/gettextConfigGen.ml $(GENERATED_FILES): configure.ml ocaml configure.ml build: $(GENERATED_FILES) dune build @install doc: $(GENERATED_FILES) dune build @doc test: $(GENERATED_FILES) dune build examples/library/examplesLibrary.a dune build examples/gui/examplesGUI.a dune build examples/program/program.exe dune runtest all: $(GENERATED_FILES) dune build @all dune runtest install: build dune install uninstall: all dune uninstall clean: dune clean bench: dune exec test/bench/bench.exe headache: distclean headache -h .header \ -c .headache.config \ `find $(CURDIR)/ -type d -name .svn -prune -false -o -type f` deploy: doc test dune-release lint dune-release tag git push --all git push --tag dune-release eol: find ./ -name _build -prune -false -or -name "*.ml" | xargs grep -r -e " *$$" .PHONY: build doc test all uninstall clean install bench deploy ocaml-gettext-0.4.2/README.md000066400000000000000000000036701367051331200155600ustar00rootroot00000000000000OCaml-gettext - Internationalization library for OCaml (i18n) ============================================================= [![Travis status][travis-img]][travis] [![AppVeyor status][appveyor-img]][appveyor] Internationalization of a program means that the program have the possibility to handle different language. It can output messages which depend on the language of the user. Typically, if a program can output "bonjour" for a french user, and "hello" for an english user, this program is internationalized. GNU gettext is one of the standard solutions for i18n. You just need to use special functions to translate strings. These functions are used when the program is running to do the translation and when compiling the program to extract the strings automatically. In ocaml-gettext these functions are "s_", "f_","sn_" and "fn_". They are both used to translate at runtime and to extract strings for translation. ocaml-gettext provides enough service to build a internationalized program. It comes with : * a pure Ocaml implementation, based on Camomile, * an alternative implementation with a binding to GNU gettext library, * `ocaml-gettext` a tool to extract strings from Ocaml source. [travis]: https://travis-ci.org/gildor478/ocaml-gettext [travis-img]: https://travis-ci.org/gildor478/ocaml-gettext.svg?branch=master [appveyor]: https://ci.appveyor.com/project/gildor478/ocaml-gettext [appveyor-img]: https://ci.appveyor.com/api/projects/status/4dalakr6ixnhotve/branch/master?svg=true Installation ------------ The recommended way to install ocaml-gettext is via the [opam package manager][opam]: ```sh $ opam install gettext gettext-camomile gettext-stub ``` Documentation ------------- * API documentation is [available online](https://gildor478.github.io/ocaml-gettext). * [Reference manual](doc/reference-manual.md) Examples -------- * A [library](examples/library) * A [program](examples/program) * A [GUI](examples/gui) ocaml-gettext-0.4.2/THANKS000066400000000000000000000002671367051331200152130ustar00rootroot00000000000000 Special thanks to Richard W.M. Jones from Red Hat. He made possible to release version 0.3.0 by porting the library to OCaml 3.10.1. A great part of the 0.3.0 has been made by him. ocaml-gettext-0.4.2/TODO.md000066400000000000000000000011311367051331200153560ustar00rootroot00000000000000v 0.4.0 : - Better parse comments, to keep licence et al - Try to be faster than gettext C library - Try to get GettextStub.* and GettextDummy.* be typed GettextTypes.REALIZE_TYPE (trying to avoid the use of a .mli file). - Reread the code to improve general layout (naming scheme, exception name... ie better style) - Correct the BUG: related to bug from ocaml-fileutils - Intercept problem when recoding string (charset), errors should be wrap inside a failsafe or at least raise a coherent exception. - Create what is necessary for running into Threaded env - Write a patch for xgettext et al ocaml-gettext-0.4.2/appveyor.yml000066400000000000000000000010361367051331200166630ustar00rootroot00000000000000platform: - x86 environment: FORK_USER: ocaml FORK_BRANCH: master CYG_ROOT: C:\cygwin64 PINS: gettext.0.4.0:. gettext-stub.0.4.0:. gettext-camomile.0.4.0:. OUNIT_CI: true matrix: - PACKAGE: gettext - PACKAGE: gettext-stub - PACKAGE: gettext-camomile install: - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/$env:FORK_USER/ocaml-ci-scripts/$env:FORK_BRANCH/appveyor-install.ps1")) build_script: - call %CYG_ROOT%\bin\bash.exe -l %APPVEYOR_BUILD_FOLDER%\appveyor-opam.sh ocaml-gettext-0.4.2/configure.ml000066400000000000000000000016551367051331200166150ustar00rootroot00000000000000let () = let version = ref "dev" in let default_localedir = ref "/usr/share/locale" in let localedir = ref "/usr/local/share/locale" in Arg.parse (Arg.align [ ( "--with-defaultlocaledir", Arg.String (fun s -> default_localedir := s), " Location of the default locale dir." ); ( "--with-localedir", Arg.String (fun s -> localedir := s), " Additional location of the locale dir." ); ( "--version", Arg.String (fun s -> version := s), " Current version of gettext." ); ]) (fun s -> raise (Arg.Bad (Printf.sprintf "don't know what to do with %S" s))) "Usage: ocaml configure.ml [OPTIONS]"; let oc = open_out_bin "src/lib/gettext/base/gettextConfigGen.ml" in Printf.fprintf oc "let default_localedir = %S\nlet localedir = %S\nlet version = %S\n" !default_localedir !localedir !version; close_out oc ocaml-gettext-0.4.2/doc/000077500000000000000000000000001367051331200150405ustar00rootroot00000000000000ocaml-gettext-0.4.2/doc/Makefile000066400000000000000000000033321367051331200165010ustar00rootroot00000000000000########################################################################## # ocaml-gettext: a library to translate messages # # # # Copyright (C) 2003-2008 Sylvain Le Gall # # # # This library is free software; you can redistribute it and/or # # modify it under the terms of the GNU Lesser General Public # # License as published by the Free Software Foundation; either # # version 2.1 of the License, or (at your option) any later version; # # with the OCaml static compilation exception. # # # # This library 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 # # Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public # # License along with this library; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # # USA # ########################################################################## update: pandoc -s -t man ocaml-gettext.1.md -o ocaml-gettext.1 pandoc -s -t man ocaml-gettext.5.md -o ocaml-gettext.5 pandoc -s -t man ocaml-xgettext.1.md -o ocaml-xgettext.1 ocaml-gettext-0.4.2/doc/dune000066400000000000000000000001511367051331200157130ustar00rootroot00000000000000(install (files ocaml-gettext.1 ocaml-xgettext.1 ocaml-gettext.5) (package gettext) (section man)) ocaml-gettext-0.4.2/doc/gui-fr.png000066400000000000000000000054211367051331200167410ustar00rootroot00000000000000PNG  IHDR_ j pHYsutIME' k7 IDATxyTGcFGDїQW€r 8*AEH^(,Hc TDd@6#,O|B4"G=\ ]U]MUWO`BJ@\Pc'؋D !; 7>I8>8Gֿ`!)nx06ó{x؅źb9?YCHQg⢌ ThЂc8C$8#:/ I?@:Ș(SRRvFsvp__HO c47/zImFKO@-ֿ͍oq?#XR,5{S#z-|OnbG=_b|"&?S܏yЃmOڂ) Š8%! IUDo Dp7gʞKDNߪg|2'WlѢ=kb +|,om̺/C{֗!_ܟr9I* ikm^GDeKv#;B>t(Y׿-Ukj0=.[AwoΔNDg7"LbKv0YSPH|T2[-O-+ uX x ;ڟrb\o6uMȿ ڼ6(!+bU@<_L&BF{'g0t~(_\&oz4)S[M;Xpx0X[RC,(ala V͏jŸ#n,3<9K.b+TɂX JYs6kY.3up=קg'##3|6瀝a`,L&?$d}]5@R0SS-]NYYY@+EC uݻw+|uqFFz |/Nf_}]uMА}ay޻|55 O(({P5̌TJU/^L_^JS,65*+SRP^^~9mvuuKVT]j?{2#jovv>p~>IHLvq΍??????G>Y kq|HqN,sgBƫھM@}pg~OO^#$s^d)Ux-Bwu0QY@se֟|N{dd?iL_vv?Px?(^IENDB`ocaml-gettext-0.4.2/doc/gui.png000066400000000000000000000044231367051331200163350ustar00rootroot00000000000000PNG  IHDR]FA pHYsutIME(x'IDATx{Pw2(R)r=)PTO0(Z! "⩕G:8ŃA+UWK鴔^|U 9F!m֐Y~~, B!l*[|1 ! a4| 0 #I-a"$IUtuj#*(\47KF9SHn,rE0LUthDe ƝgЎMpc/HF566Ψp`ޚּquT7-̖gtL9YwoPEI-ȝU;`c?.c9)ǟ/%<@VE+؁7NYi`t6xb]3L~dѓ[tĒ",=<_pwyg]ٸZ٧ZSjV_o_i q0h)֜V/įbmҕư덱>sKtٝ% .P&xׇj۵kLw获"4O_nh!=ź4"vH֎HO:B(j҉vL(n" n-1W/^^VJe1}n7do`<Dwʜ+-2h&dk+xm:\$5+3mBL*կ4܅φ:Zd4>)[$vC^o`%W|\IO*\qP4-BgW|WSv&1 ܽ,ecx(}ȳ]P$Ri>eI(na;J>eMeU;⎧U70%J|/s3d9I(@9; `4U[fiGbB@k-#1]˨w &4%S;U{ X`E"^w4? 8 0 iL`440 iL`440 iLfRkV\'PRy{-7N}_P4OuhJ~ⴅyMUŽ;?+Js[]Ԏ`v,8?&/rdd$6fʹqgGFFd}+E___KKkժUnҠȠE%~/93]]>z#Ɲǎ&1|ʆ޺ YWj߷Y"/2Rq[ks[kK2ygK~~?br>˃ylwwPx!yͦB-|vpg's˺;n Y""y~5㶰̭ɿD~Qq鱣o}x2>5bx||ŋ|Ç|Kn] ӽǛ-N=m֭2~m&%wssy"<׎`Gw}w“9mi|;\ [--gettext-disable] [--gettext-domain-dir {textdomain} {dir}]
[--gettext-dir {dir}]
[--gettext-language {language}]
[--gettext-codeset {codeset}] # DESCRIPTION This section describes briefly the common options provided by programs using ocaml-gettext library. --gettext-failsafe ignore : Defines the behaviour of ocaml-gettext regarding any error that could be encountered during the processing of string translation. ignore is the default behaviour. The string returned is the original string untranslated. This behaviour is consistent and allows to have a usable output, even if it is not perfect. --gettext-failsafe inform-stderr : Same behaviour as ignore, except that a message is printed on stderr, --gettext-failsafe raise-exception : Stops the program by raising an exception when an error is encountered. --gettext-disable : Disables any translation made by ocaml-gettext. All translations return the original string untranslated. --gettext-domain-dir textdomain dir : Defines a dir to search for a specific domain. This could be useful if MO files are stored in a non standard directory. --gettext-dir dir : Adds a directory to search for MO files. --gettext-language language : Sets the language to use in ocaml-gettext library. The language should be POSIX compliant. The language should follow the following convention: lang\[_territory]\[.charset]\[@modifier]. The lang and territory should be two letters ISO code. Charset should be a valid ISO character set (at least recognised by the underlying charset recoding routine). For example, valid languages are: fr_FR.ISO-8859-1@euro, de_DE.UTF-8. --gettext-codeset codeset : Sets the codeset for output. Users should be aware that these command line options, apply only for strings after the initialisation of the library. This means that if the options initially guessed by ocaml-gettext don't match the command line provided, there should be some untranslated string, because these strings are translated before parsing options. This is particularly true for the usage message itself (--help): even if the strings are translated, they are translated before setting the correct option. Some options (--gettext-codeset for example) are overrided internally for particular use. It should be required to always translate strings to UTF-8 in graphical user interface (because GTK2 requires it). ocaml-gettext-0.4.2/doc/ocaml-xgettext.1000066400000000000000000000012161367051331200200670ustar00rootroot00000000000000.\" Automatically generated by Pandoc 1.17.2 .\" .TH "OCAML\-XGETTEXT" "1" "2008\-04\-29" "" "" .hy .SH NAME .PP ocaml\-xgettext \- program to extract translatable strings from OCaml source file. .SH SYNOPSIS .PP ocaml\-xgettext [ppx arguments] [filename] .SH DESCRIPTION .PP This manual page documents briefly the ocaml\-xgettext .PP ocaml\-xgettext is a ppx filter. It outputs an OCaml marshalled data structure that can only be understood by ocaml\-gettext. The purpose of this program is to be a backend for OCaml source code string extraction. You should not use it directly. .SH SEE ALSO .PP \f[C]ocaml\-gettext\f[](1) .SH AUTHORS Sylvain Le Gall. ocaml-gettext-0.4.2/doc/ocaml-xgettext.1.md000066400000000000000000000010331367051331200204630ustar00rootroot00000000000000% OCAML-XGETTEXT(1) % Sylvain Le Gall % 2008-04-29 # NAME ocaml-xgettext - program to extract translatable strings from OCaml source file. # SYNOPSIS ocaml-xgettext [ppx arguments] [filename] # DESCRIPTION This manual page documents briefly the ocaml-xgettext ocaml-xgettext is a ppx filter. It outputs an OCaml marshalled data structure that can only be understood by ocaml-gettext. The purpose of this program is to be a backend for OCaml source code string extraction. You should not use it directly. # SEE ALSO `ocaml-gettext`(1) ocaml-gettext-0.4.2/doc/reference-manual.md000066400000000000000000000430751367051331200206040ustar00rootroot00000000000000# OCaml-gettext reference manual [gettext documentation]: http://www.gnu.org/software/gettext/manual/gettext.html [ocaml-gettext-options manpage]: ocaml-gettext.5.md Overview -------- ### What is ocaml-gettext? ocaml-gettext is a library to support string translation in OCaml. It provides a simple interface to help programmers and translators to create programs that can support different languages. This allows the internationalization of programs. ocaml-gettext provides two main features: - translate English strings into localized strings (depending on which gettext data are installed), - convert charset from the one used by the translator into the charset of the user. The library is build according three points of view: - for the programmer: this library provides functions that can be used in OCaml, - for the translator: this library provides a standard file format (PO file) to help the translator, - for the user: this library provides a set of command line options to set the language and the charset. ocaml-gettext was initially only a wrapper of gettext. It comes with a patch against the source of xgettext to add support of the OCaml language. As i already used this approach, i was convinced that this library should be better integrated by using more advanced features of OCaml (such as `camlp4`). As a result of porting gettext to ocaml-gettext, we have: - a library that can understood the native format of gettext file (MO file), - two implementations: a wrapper around gettext and a pure OCaml implementation using camomile, - `ocaml-gettext`: a command line tool to help you to extract, to merge and to install gettext data. ### How is ocaml-gettext related to gettext? ocaml-gettext is a close cousin of gettext. In fact, the API is based on gettext. Almost everything in ocaml-gettext is compatible with gettext: - functions provided in the API are very close to the gettext one, - the library contains a binding of the gettext library, - all the file used are gettext compatible: the library uses PO file for translator and MO file for translation, - the library tries to use the same initialisation sequence as gettext: it uses the same environment variable, tries to find MO files in the same places... This documentation will not covered the point that are better explained in the [gettext documentation]. It is highly recommended to read this documentation, before reading this manual. Most of the point that are explained there are not explained again here. However, we have tried to be as precise as possible to enable programming with ocaml-gettext without having the need to be a gettext expert. Programming with ocaml-gettext ------------------------------ ### Overview The API of ocaml-gettext is really reduced. It is made on purpose. The design is heavily based on modules and functors. There is no real reason for this design, it was just really useful at the time the code was written. The library supposes that all the `textdomain` that will be used during translation, are declared before using it. It is a real constraint, but it enables more optimisation. Moreover, it allows having a more "functional" use. First of all, a parameter `t` should be defined. This parameter holds all the required value to initialise ocaml-gettext. In particular, it contains information about: - which textdomain will be used, - which language will be used, - how the error should be handle, - which directory to search. This parameter is build and updated through internal functions. You don't have direct access to it. The parameter `t` is not directly used for translation. It must be converted into a parameter `t'` which is a real function to access translation. The transformation from `t` to `t'` is handled through a function `realize`. The parameter `t'` is used in low level translation. All the work of the library is done in the function `realize`. This function is not provided in the base package. It is build out of real implementation of ocaml-gettext (such as `gettext-camomile` or `gettext-stub`). This function could handle all the parameters in different ways. Concerning `gettext-camomile`, it builds a translation table for all the files found which correspond to a declared `textdomain`. Since it should be very difficult to pass a parameter `t` or `t'` in all functions that should use translation, we provide a more simple way to use the library. The top level functions use a global reference to store the parameters `t` and `t'`. This helps to integrate ocaml-gettext more easily into existing application. ### Makefile and source layout The source layout should conform to the one described in [gettext documentation]. In particular, it should contain a `po` directory. There should be in this directory : - a file `LINGUAS` describing available translations, - a file `POTFILES` containing the listing of all files that contain translatable strings, - a `Makefile` to build the whole thing, - a set of PO file which contains translated strings for different languages. During the build, the `Makefile` should generate a file `your-domain.pot` that contains a template PO file that can be used by translator. To build programs and libraries with ocaml-gettext, the preferred way is to use ocamlfind. There are five findlib packages: - gettext.base: the base package of ocaml-gettext. It contains the top level type required to compile any library, - gettext.extension[1](#1): a package used to extend ocaml-gettext. It is reserved for very particular functions (such as creating a new `realize` function), - gettext.extract: a package that enables to create special `camlp4` program (such as `ocaml-xgettext`), - gettext-stub: an implementation of ocaml-gettext using gettext, - gettext-camomile: an implementation of ocaml-gettext using camomile. It is a pure ocaml implementation. In order to link an application or a library using ocaml-gettext, you should link with one of : gettext.base, gettext-camomile or gettext-stub. ### Library Library should use the module `Gettext.Library`. It doesn't need any real implementation of ocaml-gettext. By this way, you can let the library user choose the most appropriate ocaml-gettext implementation. This point is essential : a library could be used as well in a GUI program or in short run command line program. These two examples don't require the same kind of implementation at all: GUI program loads most of their translated strings, command line program only use one among them. So by using the module `Gettext.Library` framework, you don't restrict programs to use one particular implementation of ocaml-gettext. The library should define, using the functor `Init` provided: - his textdomain through the `textdomain` value, - his dependencies through the `dependencies` value, - if needed his charset and directory binding (but it is not recommended to do so). After having instantiated the module `Gettext.Library` with the appropriate `Init`, you should use the function provided : - `s_`: for translating singular strings, - `f_`: for translating singular strings which will be used with `Printf` function[2](#2), - `sn_`: for translating plural strings, - `fn_`: for translating plural strings which will be used with `Printf` function, > **Warning** > > You must keep the function name `s_`, `f_`, `sn_` and `fn_`. The > extraction of translatable strings matches these names. If you don't > keep it, the extraction of translatable strings will fail. All the calls to translation functions, use the textdomain provided in `Init`. The only constraint when using ocaml-gettext in your library is to provide an access to the value `Gettext.Library.init`. This value is used as dependencies for other libraries and programs that depend on it. For example, since you use the library ocaml-gettext, your primary dependency is the function `init` provided in the top level (the function `Gettext.string_of_exception` is localised). > **Warning** > > If you distribute your library, don't forget to mention that > ocaml-gettext will only be able to translate the string defined in > your library, if and only if the MO file build with is also installed. > If not installed ocaml-gettext is useless. ### Program Program should use ocaml-gettext just as libraries do. The only difference lies in the fact that you should provide a `realize` function in the `InitProgram`. The other difference is that the `init` value is not a dependency that should be used by other program. It is a `Arg` usable value. It allows user to define some important parameters. ```shell $>./program --help --my-name name Your name. Default : "" --gettext-failsafe {ignore|inform-stderr|raise-exception} Choose how to handle failure in ocaml-gettext. Default: ignore. --gettext-disable Disable the translation perform by ocaml-gettext. Default: enable. --gettext-domain-dir textdomain dir Set a dir to search ocaml-gettext files for the specified domain. Default: [ ]. --gettext-dir dir Add a search dir for ocaml-gettext files. Default: [ "/usr/share/locale"; "/usr/local/share/locale" ]. --gettext-language language Set the default language for ocaml-gettext. Default: (none). --gettext-codeset codeset Set the default codeset for outputting string with ocaml-gettext. Default: ISO-8859-1. -help Display this list of options --help Display this list of options ``` If you want to include a manpage (or info file), that describes the command line option of ocaml-gettext, you should use the Docbook XML fragment distributed with this application. Docbook should be enough generic to allow you to link it into your documentation. If you don't want to link it with your documentation, you can refer to [ocaml-gettext-options manpage]. You should take care of what implementation of ocaml-gettext you are using. In order to choose the right implementation you should consider your program and every characteristic of it (how many strings does it need to fetch? Does it use already a C library that link with gettext?). - GettextCamomile.Map - Pure OCaml implementation, - Full load of all MO files before any translation, - Use OCaml standard `Map`. - Usage - Pure OCaml program, - Program that requires to translate a lot of strings, - Threaded program (since it uses OCaml Map, it should be thread safe without problem). - GettextCamomile.Hashtbl - Pure OCaml implementation, - Full load of all MO file before any translation, - Use OCaml standard `Hashtbl`. - Usage - Pure OCaml program, - Program that requires to translate a lot of strings, - Should work with threaded program, provided that the `Hashtbl` works in threaded environment. - GettextCamomile.Open - Pure OCaml implementation, - Load strings from MO if needed, - Use OCaml standard `Hashtbl`, - Use a dichotomic search for the strings, - Compute MO file to open at initialisation, - Open a file when fetching string, - Doesn't memorize already translated strings, - Implementation design copied from gettext. - Usage - Pure OCaml program, - Program that require to translate very few strings, - Should work with threaded program, provided that `open_in` function call work. - GettextStub.Native - Native gettext library, - Partial load of all MO file before any translation, use `mmap`. - Usage - OCaml program that uses library compiled with gettext, - Should work with threaded program, provided that the `gettext` work in threaded environment. To support a language, the corresponding locales need to be generated. - GettextStub.Preload - Native gettext library, - Forced load of all MO file before any translation, the preload is realized by trying to load the string "" for all the textdomain defined. - Usage - OCaml program that uses library compiled with gettext, - Program that needs to translate a lot of strings, - Should work with threaded program, provided that the `gettext` work in threaded environment. To support a language, the corresponding locales need to be generated. ### Graphical user interface Graphical user interface works just as a program or a library. The only difference is that the file which contains the graphical user interface should not be written in OCaml. You have two cases : - You use glade file, so you should extract the strings from this file using `xgettext` - You use a hand written interface written in OCaml, the extraction of the strings follow the same way as a library. You should use the first alternative : it is easier for a translator to extract strings, without having to compile your application (it enables translators that don't know OCaml to help you). In order to do so, you should use the native `xgettext` binary (provided with gettext). It should support the format of the translatable strings found in your GUI file (for example, `xgettext` supports glade file). But for now you can only use the second alternative, because OCaml is not yet supported in `xgettext`. This should be fixed, once `ocaml-gettext` will be enough stable to become a back-end for `xgettext`[3](#3). In the two cases, you just have to add your GUI file (in OCaml or native form) to `POTFILES`. Graphical user interfaces are good candidates for settings a fixed `Init.codeset`. Typically, GTK2 interfaces require to have these parameters set to UTF-8. ```ocaml open GuiGettext.Gettext;; (* Give access to the init of GuiGettext *) let init = Gettext.init (* Build a simple window that display your name *) let hello_you name = let spf x = Printf.sprintf x in let window = GWindow.window ~title:(s_ "Hello world !") ~border_width:12 () in let label = GMisc.label ~text:(spf (f_ "Hello %s") name) ~packing:window#add () in ignore (window#event#connect#delete ~callback:(fun _ -> false)); ignore (window#connect#destroy ~callback:(fun _ -> GMain.Main.quit ())); window#show (); GMain.Main.main () ``` `./program --gettext-dir ../build/share/locale --gettext-lang C --my-name Sylvain`:
![Default GUI, not translated](gui.png "GUI") `./program --gettext-dir ../build/share/locale --gettext-lang C --my-name Sylvain`:
![GUI translated to french](gui-fr.png "GUI fr") > **Warning** > > If you build lablgtk application, you must keep in mind that some > locale settings are made in the function `GMain.Init`. Those settings > could override those done through the command line options. In order > to correctly use ocaml-gettext, you must be sure to call `GMain.Init` > before using `Arg.parse` with the ocaml-gettext args. Translating ocaml-gettext programs and libraries ------------------------------------------------ ocaml-gettext has been built around gettext. This allows translators to use exactly the same technics as they should use with gettext. All the documentation required for translating can be found in [gettext documentation]. It is recommended to use GUI which allows easier translation such as : - [gtranslator](http://gtranslator.sourceforge.net/), - [kbabel](http://i18n.kde.org/tools/kbabel/). ### Using ocaml-gettext programs ocaml-gettext program can be used just as any OCaml program. The only difference with standard OCaml program is that they come with a bunch of command line options which are specific to OCaml program. In most cases, you just have to define a well suited `LC_ALL` or `LANG` environment variable. Since ocaml-gettext is compatible with gettext, if your environment variable works with gettext, it should also works with ocaml-gettext. You can find more details in the [gettextdocumentation] or in the [ocaml-gettext-options manpage]. Tips and tricks --------------- ### Adding gettext support without depending on ocaml-gettext You want to 'gettextify' your program, adding 's\_' and 'f\_' annotations throughout. However now your program has an additional dependency, ocaml-gettext. You can make ocaml-gettext optional by creating a set of dummy functions which do nothing: ```ocaml (* This file is generated automatically by ./configure. *) module Gettext = struct external s_ : string -> string = "%identity" external f_ : ('a -> 'b, 'c, 'd) format -> ('a -> 'b, 'c, 'd) format = "%identity" let sn_ : string -> string -> int -> string = fun s p n -> if n = 1 then s else p let fn_ : ('a -> 'b, 'c, 'd) format -> ('a -> 'b, 'c, 'd) format -> int -> ('a -> 'b, 'c, 'd) format = fun s p n -> if n = 1 then s else p end ``` You have to arrange for your configure script to place the above content or the real ProgramGettext module into 'prog\_gettext.ml', depending on whether it detects that ocaml-gettext is installed (eg. using 'ocamlfind query gettext' or some other method). Links ----- [Gettext documentation](http://www.gnu.org/software/gettext/manual/gettext.html) 1: This feature is described here for your information only. Since it belongs to low level implementation of ocaml-gettext, it should not be used. 2: Strings which should be used by `Printf` function are checked to be sure that the returned strings are equivalent to the provided English string. In particular, every "%"-symbol should be the same in the provided string and the returned string. If not, it is the untranslated string which is returned. 3: For now, extracting strings from OCaml source file and glade file, requires to patch gettext. You can find this path in patches. This patch will be sent to upstream author once it will be considered enough stable. ocaml-gettext-0.4.2/dune-project000066400000000000000000000001031367051331200166070ustar00rootroot00000000000000(lang dune 1.11) (name gettext) (explicit_js_mode) (using fmt 1.2) ocaml-gettext-0.4.2/examples/000077500000000000000000000000001367051331200161115ustar00rootroot00000000000000ocaml-gettext-0.4.2/examples/gui/000077500000000000000000000000001367051331200166755ustar00rootroot00000000000000ocaml-gettext-0.4.2/examples/gui/dune000066400000000000000000000001031367051331200175450ustar00rootroot00000000000000(library (name examplesGUI) (libraries gettext.base lablgtk3)) ocaml-gettext-0.4.2/examples/gui/gui.ml000066400000000000000000000041741367051331200200210ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open GuiGettext.Gettext (* Give access to the init of GuiGettext *) let init = Gettext.init (* Build a simple window that display your name *) let hello_you name = let spf x = Printf.sprintf x in let window = GWindow.window ~title:(s_ "Hello world !") ~border_width:12 () in ignore (GMisc.label ~text:(spf (f_ "Hello %s") name) ~packing:window#add ()); ignore (((window#event)#connect)#delete ~callback:(fun _ -> false)); ignore ((window#connect)#destroy ~callback:(fun _ -> GMain.Main.quit ())); window#show (); GMain.Main.main () ocaml-gettext-0.4.2/examples/gui/guiGettext.ml000066400000000000000000000034621367051331200213650ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (* Create the module Gettext, using the textdomain "mydomain" *) module Gettext = Gettext.Library (struct let textdomain = "mydomain" let codeset = Some "UTF-8" let dir = None let dependencies = Gettext.init end) ocaml-gettext-0.4.2/examples/library/000077500000000000000000000000001367051331200175555ustar00rootroot00000000000000ocaml-gettext-0.4.2/examples/library/dune000066400000000000000000000000761367051331200204360ustar00rootroot00000000000000(library (name examplesLibrary) (libraries gettext.base)) ocaml-gettext-0.4.2/examples/library/library.ml000066400000000000000000000044231367051331200215560ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open LibraryGettext.Gettext (* Give access to the init of LibraryGettext *) let init = Gettext.init (* Example function *) let library_only_function () = (* Two simple examples : singular translation *) print_endline (s_ "Hello world !"); Printf.printf (f_ "Hello %s !\n") "world"; (* More complicated : plural translation, using strings *) print_endline ( sn_ "There is " "There are " 2 ^ string_of_int 2 ^ sn_ "plate." "plates." 2 ); (* More simple forms of plural translation, using printf *) Printf.printf (fn_ "There is %d plate.\n" "There are %d plates.\n" 2) 2 (* Another example function : used by program.ml *) let hello_you name = Printf.printf (f_ "Hello %s\n") name ocaml-gettext-0.4.2/examples/library/libraryGettext.ml000066400000000000000000000034521367051331200231240ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (* Create the module Gettext, using the textdomain "mydomain" *) module Gettext = Gettext.Library (struct let textdomain = "mydomain" let codeset = None let dir = None let dependencies = Gettext.init end) ocaml-gettext-0.4.2/examples/po/000077500000000000000000000000001367051331200165275ustar00rootroot00000000000000ocaml-gettext-0.4.2/examples/po/LINGUAS000066400000000000000000000000031367051331200175450ustar00rootroot00000000000000fr ocaml-gettext-0.4.2/examples/po/Makefile000066400000000000000000000063321367051331200201730ustar00rootroot00000000000000########################################################################## # ocaml-gettext: a library to translate messages # # # # Copyright (C) 2003-2008 Sylvain Le Gall # # # # This library is free software; you can redistribute it and/or # # modify it under the terms of the GNU Lesser General Public # # License as published by the Free Software Foundation; either # # version 2.1 of the License, or (at your option) any later version; # # with the OCaml static compilation exception. # # # # This library 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 # # Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public # # License along with this library; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # # USA # ########################################################################## OCAML_GETTEXT_PACKAGE = mydomain LINGUAS=$(shell cat LINGUAS) SOURCES=POTFILES OCAML_GETTEXT=ocaml-gettext OCAML_GETTEXT_EXTRACT_OPTIONS= OCAML_GETTEXT_COMPILE_OPTIONS= OCAML_GETTEXT_INSTALL_OPTIONS= OCAML_GETTEXT_MERGE_OPTIONS= BUILDPO=../build/share/locale/ POFILES=$(addsuffix .po,$(LINGUAS)) MOFILES=$(addsuffix .mo,$(LINGUAS)) POTFILE=$(OCAML_GETTEXT_PACKAGE).pot all: install-buildpo install: install-po uninstall: uninstall-po clean:: clean-po %.mo: %.po $(OCAML_GETTEXT) --action compile $(OCAML_GETTEXT_COMPILE_OPTIONS) \ --compile-output $@ $^ %.pot: $(SOURCES) $(OCAML_GETTEXT) --action extract $(OCAML_GETTEXT_EXTRACT_OPTIONS) \ --extract-pot $@ $^ %.po: $(POTFILE) $(OCAML_GETTEXT) --action merge $(OCAML_GETTEXT_MERGE_OPTIONS) \ --merge-pot $(POTFILE) $@ $(BUILDPO): mkdir -p $(BUILDPO) .PRECIOUS: $(POTFILE) install-buildpo: $(MOFILES) $(BUILDPO) $(OCAML_GETTEXT) --action install $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --install-textdomain $(OCAML_GETTEXT_PACKAGE) \ --install-destdir $(BUILDPO) $(MOFILES) install-po: $(MOFILES) $(OCAML_GETTEXT) --action install $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --install-textdomain $(OCAML_GETTEXT_PACKAGE) \ --install-destdir $(PODIR) $(MOFILES) uninstall-po: $(OCAML_GETTEXT) --action uninstall $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --uninstall-textdomain $(OCAML_GETTEXT_PACKAGE) \ --uninstall-orgdir $(PODIR) $(MOFILES) clean-po: -$(OCAML_GETTEXT) --action uninstall $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --uninstall-textdomain $(OCAML_GETTEXT_PACKAGE) \ --uninstall-orgdir $(BUILDPO) $(MOFILES) -$(RM) $(MOFILES) ocaml-gettext-0.4.2/examples/po/POTFILES000066400000000000000000000000721367051331200176760ustar00rootroot00000000000000../library/library.ml ../gui/gui.ml ../program/program.ml ocaml-gettext-0.4.2/examples/po/fr.po000066400000000000000000000031671367051331200175050ustar00rootroot00000000000000# EXAMPLE MYDOMAIN PROGRAM. # Copyright (C) 2005-2008 Sylvain Le Gall # This file is distributed under the same license as the ocaml-gettext package. # , fuzzy msgid "" msgstr "" "Project-Id-Version: ocaml-gettext 0.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2005-04-05 23:20+0000\n" "PO-Revision-Date: 2005-04-06 01:29+0200\n" "Last-Translator: Sylvain Le Gall \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;" #: ../gui/gui.ml:15 msgid "Hello %s" msgstr "Bonjour %s" #: ../library/library.ml:14 msgid "Hello %s !\\n" msgstr "Bonjour %s !\\n" #: ../library/library.ml:29 msgid "Hello %s\\n" msgstr "Bonjour %s\\n" #: ../library/library.ml:13 ../gui/gui.ml:13 msgid "Hello world !" msgstr "Bonjour le monde !" #: ../library/library.ml:18 msgid "There is " msgid_plural "There are " msgstr[0] "Il y a " msgstr[1] "Il y a" #: ../library/library.ml:24 msgid "There is %d plate.\\n" msgid_plural "There are %d plates.\\n" msgstr[0] "Il y a %d assiettes.\\n" msgstr[1] "Il y a %d assiettes.\\n" #: ../program/program.ml:35 msgid "\\\"Hello you\\\" program by Sylvain Le Gall\n\n%s\n\nCommand: program [options]\n\nOptions:" msgstr "\\\"Bonjour à toi\\\" application par Sylvain Le Gall\n\n%s\n\nCommande: program [options]\n\nOptions :" #: ../program/program.ml:19 msgid "name Your name. Default : %S" msgstr "nom Votre nom. Par défaut : %S" #: ../library/library.ml:20 msgid "plate." msgid_plural "plates." msgstr[0] "assiette." msgstr[1] "assiettes." ocaml-gettext-0.4.2/examples/po/mydomain.pot000066400000000000000000000025711367051331200210750ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2005-04-05 23:31+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: ../gui/gui.ml:15 msgid "Hello %s" msgstr "" #: ../library/library.ml:14 msgid "Hello %s !\\n" msgstr "" #: ../library/library.ml:29 msgid "Hello %s\\n" msgstr "" #: ../library/library.ml:13 ../gui/gui.ml:13 msgid "Hello world !" msgstr "" #: ../library/library.ml:18 msgid "There is " msgid_plural "There are " msgstr[0] "" msgstr[1] "" #: ../library/library.ml:24 msgid "There is %d plate.\\n" msgid_plural "There are %d plates.\\n" msgstr[0] "" msgstr[1] "" #: ../program/program.ml:35 msgid "\\\"Hello you\\\" program by Sylvain Le Gall\n\n%s\n\nCommand: program [options]\n\nOptions:" msgstr "" #: ../program/program.ml:19 msgid "name Your name. Default : %S" msgstr "" #: ../library/library.ml:20 msgid "plate." msgid_plural "plates." msgstr[0] "" msgstr[1] "" ocaml-gettext-0.4.2/examples/program/000077500000000000000000000000001367051331200175605ustar00rootroot00000000000000ocaml-gettext-0.4.2/examples/program/dune000066400000000000000000000001461367051331200204370ustar00rootroot00000000000000(executable (name program) (libraries gettext.base gettext-camomile examplesGUI examplesLibrary)) ocaml-gettext-0.4.2/examples/program/program.ml000066400000000000000000000044421367051331200215650ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open ProgramGettext.Gettext let () = let my_name = ref "" in let spf x = Printf.sprintf x in let gettext_args, gettext_copyright = ProgramGettext.Gettext.init in let args = Arg.align ( [ ( "--my-name", Arg.String (fun s -> my_name := s), spf (f_ "name Your name. Default : %S") !my_name ); ] @ gettext_args ) in let () = Arg.parse args (fun _ -> ()) (spf (f_ "\"Hello you\" program by Sylvain Le Gall\n\n\ %s\n\n\ Command: program [options]\n\n\ Options:") gettext_copyright) in ExamplesLibrary.Library.hello_you !my_name; ExamplesGUI.Gui.hello_you !my_name ocaml-gettext-0.4.2/examples/program/programGettext.ml000066400000000000000000000037431367051331200231350ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (* Create the module Gettext, using the textdomain "mydomain" *) module Gettext = Gettext.Program (struct let textdomain = "mydomain" let codeset = None let dir = None let dependencies = ExamplesLibrary.Library.init @ ExamplesGUI.Gui.init end) (* I do prefer fully ocaml implementation, so choose the GettextCamomile module *) (GettextCamomile.Map) ocaml-gettext-0.4.2/gettext-camomile.opam000066400000000000000000000016211367051331200204210ustar00rootroot00000000000000opam-version: "2.0" maintainer: "Sylvain Le Gall " authors: [ "Sylvain Le Gall" ] license: "LGPL-2.1-only with OCaml-LGPL-linking-exception" homepage: "https://github.com/gildor478/ocaml-gettext" dev-repo: "git+https://github.com/gildor478/ocaml-gettext.git" bug-reports: "https://github.com/gildor478/ocaml-gettext/issues" doc: "https://gildor478.github.io/ocaml-gettext/" build: [ ["ocaml" "configure.ml" "--with-defaultlocaledir" "%{lib}%/gettext/share/locale" "--version" version] ["dune" "build" "-p" name "-j" jobs "@install" "@doc" {with-doc} "@runtest" {with-test} ] ] depends: [ "ocaml" {>= "4.03.0"} "dune" {>= "1.11.0"} "camomile" "base-bytes" "gettext" {= version} "ounit" {with-test & > "2.0.8"} "fileutils" {with-test} ] synopsis: "Internationalization library using camomile (i18n)" description:""" See gettext package description. """ ocaml-gettext-0.4.2/gettext-stub.opam000066400000000000000000000022671367051331200176170ustar00rootroot00000000000000opam-version: "2.0" maintainer: "Sylvain Le Gall " authors: [ "Sylvain Le Gall" ] license: "LGPL-2.1-only with OCaml-LGPL-linking-exception" homepage: "https://github.com/gildor478/ocaml-gettext" dev-repo: "git+https://github.com/gildor478/ocaml-gettext.git" bug-reports: "https://github.com/gildor478/ocaml-gettext/issues" doc: "https://gildor478.github.io/ocaml-gettext/" build: [ ["ocaml" "configure.ml" "--with-defaultlocaledir" "%{lib}%/gettext/share/locale" "--version" version] ["dune" "build" "-p" name "-j" jobs "@install" "@doc" {with-doc} "@runtest" {with-test} ] ] depends: [ "ocaml" {>= "4.03.0"} "dune" {>= "1.11.0"} "dune-configurator" "base-bytes" "gettext" {= version} "ounit" {with-test & > "2.0.8"} "fileutils" {with-test} ] depexts: [ ["gettext"] {os = "macos" & os-distribution = "homebrew"} ["gettext"] {os = "macos" & os-distribution = "macports"} ["gettext"] {os = "win32" & os-distribution = "cygwinports"} ["gettext-dev"] {os-distribution = "alpine"} ["libc6-dev"] {os-family = "debian"} ] synopsis: "Internationalization using C gettext library (i18n)" description:""" See gettext package description. """ ocaml-gettext-0.4.2/gettext.opam000066400000000000000000000022121367051331200166320ustar00rootroot00000000000000opam-version: "2.0" maintainer: "Sylvain Le Gall " authors: [ "Sylvain Le Gall" ] license: "LGPL-2.1-only with OCaml-LGPL-linking-exception" homepage: "https://github.com/gildor478/ocaml-gettext" dev-repo: "git+https://github.com/gildor478/ocaml-gettext.git" bug-reports: "https://github.com/gildor478/ocaml-gettext/issues" doc: "https://gildor478.github.io/ocaml-gettext/" build: [ ["ocaml" "configure.ml" "--with-defaultlocaledir" "%{lib}%/gettext/share/locale" "--version" version] ["dune" "build" "-p" name "-j" jobs "@install" "@doc" {with-doc} "@runtest" {with-test} ] ] depends: [ "ocaml" {>= "4.03.0"} "dune" {>= "1.11.0"} "cppo" {build} "fileutils" "base-bytes" "ounit" {with-test & > "2.0.8"} ] synopsis: "Internationalization library (i18n)" description:""" This library enables string translation in OCaml. The API is based on GNU gettext. It comes with a tool to extract strings which need to be translated from OCaml source files. This enables OCaml program to output string in the native language of the user, if a corresponding translation file of the English strings is provided. """ ocaml-gettext-0.4.2/patches/000077500000000000000000000000001367051331200157225ustar00rootroot00000000000000ocaml-gettext-0.4.2/patches/README.patches000066400000000000000000000001721367051331200202300ustar00rootroot00000000000000gettext-ocaml.patch: Used to work on previous version. No longer work, but will work again in version 0.3.0, be patient. ocaml-gettext-0.4.2/patches/gettext-ocaml.patch000066400000000000000000001133211367051331200215210ustar00rootroot00000000000000diff -Nurd gettext-0.12.1/gettext-tools/src/FILES gettext-0.12.1.ocaml/gettext-tools/src/FILES --- gettext-0.12.1/gettext-tools/src/FILES 2003-04-29 12:00:15.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/FILES 2003-07-03 18:52:19.000000000 +0200 @@ -177,6 +177,7 @@ format-ycp.c Format string handling for YCP. format-tcl.c Format string handling for Tcl. format-php.c Format string handling for PHP. +format-ocaml.c Format string handling for Objective Caml. format.c Table of the language dependent format string handlers. +-------------- The 'msgfmt' program @@ -239,6 +240,9 @@ | x-php.h | x-php.c | String extractor for PHP. +| x-ocaml.h +| x-ocaml.c +| String extractor for Objective Caml. | x-rst.h | x-rst.c | String extractor from .rst files, for Object Pascal. diff -Nurd gettext-0.12.1/gettext-tools/src/Makefile.am gettext-0.12.1.ocaml/gettext-tools/src/Makefile.am --- gettext-0.12.1/gettext-tools/src/Makefile.am 2003-04-29 12:05:37.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/Makefile.am 2003-07-16 22:00:23.000000000 +0200 @@ -42,7 +42,7 @@ write-mo.h read-java.h write-java.h read-tcl.h write-tcl.h po-time.h \ plural-table.h format.h xgettext.h x-c.h x-po.h x-python.h x-lisp.h x-elisp.h \ x-librep.h x-smalltalk.h x-java.h x-properties.h x-awk.h x-ycp.h x-tcl.h \ -x-php.h x-rst.h x-glade.h +x-php.h x-rst.h x-glade.h x-ocaml.h EXTRA_DIST += FILES project-id ChangeLog.0 @@ -93,7 +93,7 @@ FORMAT_SOURCE = format.c format-invalid.h \ format-c.c format-python.c format-lisp.c format-elisp.c format-librep.c \ format-java.c format-awk.c format-pascal.c format-ycp.c format-tcl.c \ -format-php.c +format-php.c format-ocaml.c # libgettextsrc contains all code that is needed by at least two programs. libgettextsrc_la_SOURCES = \ @@ -119,7 +119,7 @@ msgunfmt_SOURCES = msgunfmt.c read-mo.c read-java.c read-tcl.c xgettext_SOURCES = xgettext.c \ x-c.c x-po.c x-python.c x-lisp.c x-elisp.c x-librep.c x-smalltalk.c \ - x-java.l x-awk.c x-ycp.c x-tcl.c x-php.c x-rst.c x-glade.c + x-java.l x-awk.c x-ycp.c x-tcl.c x-php.c x-rst.c x-glade.c x-ocaml.c msgattrib_SOURCES = msgattrib.c msgcat_SOURCES = msgcat.c msgcomm_SOURCES = msgcomm.c diff -Nurd gettext-0.12.1/gettext-tools/src/Makefile.in gettext-0.12.1.ocaml/gettext-tools/src/Makefile.in --- gettext-0.12.1/gettext-tools/src/Makefile.in 2003-05-22 15:41:24.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/Makefile.in 2003-07-16 22:04:36.000000000 +0200 @@ -250,7 +250,7 @@ write-mo.h read-java.h write-java.h read-tcl.h write-tcl.h po-time.h \ plural-table.h format.h xgettext.h x-c.h x-po.h x-python.h x-lisp.h x-elisp.h \ x-librep.h x-smalltalk.h x-java.h x-properties.h x-awk.h x-ycp.h x-tcl.h \ -x-php.h x-rst.h x-glade.h +x-php.h x-rst.h x-glade.h x-ocaml.h localedir = $(datadir)/locale @@ -286,7 +286,7 @@ FORMAT_SOURCE = format.c format-invalid.h \ format-c.c format-python.c format-lisp.c format-elisp.c format-librep.c \ format-java.c format-awk.c format-pascal.c format-ycp.c format-tcl.c \ -format-php.c +format-php.c format-ocaml.c # libgettextsrc contains all code that is needed by at least two programs. @@ -314,7 +314,7 @@ msgunfmt_SOURCES = msgunfmt.c read-mo.c read-java.c read-tcl.c xgettext_SOURCES = xgettext.c \ x-c.c x-po.c x-python.c x-lisp.c x-elisp.c x-librep.c x-smalltalk.c \ - x-java.l x-awk.c x-ycp.c x-tcl.c x-php.c x-rst.c x-glade.c + x-java.l x-awk.c x-ycp.c x-tcl.c x-php.c x-rst.c x-glade.c x-ocaml.c msgattrib_SOURCES = msgattrib.c msgcat_SOURCES = msgcat.c @@ -439,7 +439,7 @@ dir-list.lo str-list.lo am__objects_2 = format.lo format-c.lo format-python.lo format-lisp.lo \ format-elisp.lo format-librep.lo format-java.lo format-awk.lo \ - format-pascal.lo format-ycp.lo format-tcl.lo format-php.lo + format-pascal.lo format-ycp.lo format-tcl.lo format-php.lo format-ocaml.lo am_libgettextsrc_la_OBJECTS = $(am__objects_1) read-po.lo \ write-properties.lo write-po.lo msgl-ascii.lo msgl-iconv.lo \ msgl-equal.lo msgl-cat.lo msgl-english.lo file-list.lo \ @@ -517,7 +517,7 @@ xgettext-x-java.$(OBJEXT) xgettext-x-awk.$(OBJEXT) \ xgettext-x-ycp.$(OBJEXT) xgettext-x-tcl.$(OBJEXT) \ xgettext-x-php.$(OBJEXT) xgettext-x-rst.$(OBJEXT) \ - xgettext-x-glade.$(OBJEXT) + xgettext-x-glade.$(OBJEXT) xgettext-x-ocaml.$(OBJEXT) xgettext_OBJECTS = $(am_xgettext_OBJECTS) xgettext_DEPENDENCIES = ../libuniname/libuniname.a libgettextsrc.la @@ -1045,6 +1045,15 @@ xgettext-x-php.lo: x-php.c $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xgettext_CFLAGS) $(CFLAGS) -c -o xgettext-x-php.lo `test -f 'x-php.c' || echo '$(srcdir)/'`x-php.c +xgettext-x-ocaml.o: x-ocaml.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xgettext_CFLAGS) $(CFLAGS) -c -o xgettext-x-ocaml.o `test -f 'x-ocaml.c' || echo '$(srcdir)/'`x-ocaml.c + +xgettext-x-ocaml.obj: x-ocaml.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xgettext_CFLAGS) $(CFLAGS) -c -o xgettext-x-ocaml.obj `if test -f 'x-ocaml.c'; then $(CYGPATH_W) 'x-ocaml.c'; else $(CYGPATH_W) '$(srcdir)/x-ocaml.c'; fi` + +xgettext-x-ocaml.lo: x-ocaml.c + $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xgettext_CFLAGS) $(CFLAGS) -c -o xgettext-x-ocaml.lo `test -f 'x-ocaml.c' || echo '$(srcdir)/'`x-ocaml.c + xgettext-x-rst.o: x-rst.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xgettext_CFLAGS) $(CFLAGS) -c -o xgettext-x-rst.o `test -f 'x-rst.c' || echo '$(srcdir)/'`x-rst.c diff -Nurd gettext-0.12.1/gettext-tools/src/Makefile.msvc gettext-0.12.1.ocaml/gettext-tools/src/Makefile.msvc --- gettext-0.12.1/gettext-tools/src/Makefile.msvc 2003-05-18 13:21:29.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/Makefile.msvc 2003-07-16 22:06:25.000000000 +0200 @@ -139,13 +139,14 @@ format-pascal.obj \ format-ycp.obj \ format-tcl.obj \ - format-php.obj + format-php.obj \ + format-ocaml.obj msgcmp_OBJECTS = msgcmp.obj msgfmt_OBJECTS = msgfmt.obj write-mo.obj write-java.obj write-tcl.obj plural-eval.obj msgmerge_OBJECTS = msgmerge.obj msgunfmt_OBJECTS = msgunfmt.obj read-mo.obj read-java.obj read-tcl.obj -xgettext_OBJECTS = xgettext.obj x-c.obj x-po.obj x-python.obj x-lisp.obj x-elisp.obj x-librep.obj x-smalltalk.obj x-java.obj x-awk.obj x-ycp.obj x-tcl.obj x-php.obj x-rst.obj x-glade.obj +xgettext_OBJECTS = xgettext.obj x-c.obj x-po.obj x-python.obj x-lisp.obj x-elisp.obj x-librep.obj x-smalltalk.obj x-java.obj x-awk.obj x-ycp.obj x-tcl.obj x-php.obj x-rst.obj x-glade.obj x-ocaml.obj msgattrib_OBJECTS = msgattrib.obj msgcat_OBJECTS = msgcat.obj msgcomm_OBJECTS = msgcomm.obj @@ -269,6 +270,9 @@ format-php.obj : format-php.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c format-php.c +format-ocaml.obj : format-ocaml.c + $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c format-ocaml.c + !if !$(DLL) gettextsrc.lib : $(OBJECTS) @@ -360,6 +364,9 @@ x-php.obj : x-php.c $(CC) $(INCLUDES) $(CFLAGS) -c x-php.c +x-ocaml.obj : x-ocaml.c + $(CC) $(INCLUDES) $(CFLAGS) -c x-ocaml.c + x-rst.obj : x-rst.c $(CC) $(INCLUDES) $(CFLAGS) -c x-rst.c diff -Nurd gettext-0.12.1/gettext-tools/src/Makefile.vms gettext-0.12.1.ocaml/gettext-tools/src/Makefile.vms --- gettext-0.12.1/gettext-tools/src/Makefile.vms 2003-04-29 12:00:16.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/Makefile.vms 2003-07-16 22:07:34.000000000 +0200 @@ -85,13 +85,14 @@ format-pascal.obj, \ format-ycp.obj, \ format-tcl.obj, \ - format-php.obj + format-php.obj \ + format-ocaml.obj msgcmp_OBJECTS = msgcmp.obj msgfmt_OBJECTS = msgfmt.obj, write-mo.obj, write-java.obj, write-tcl.obj, plural-eval.obj msgmerge_OBJECTS = msgmerge.obj msgunfmt_OBJECTS = msgunfmt.obj, read-mo.obj, read-java.obj, read-tcl.obj -xgettext_OBJECTS = xgettext.obj, x-c.obj, x-po.obj, x-python.obj, x-lisp.obj, x-elisp.obj, x-librep.obj, x-smalltalk.obj, x-java.obj, x-awk.obj, x-ycp.obj, x-tcl.obj, x-php.obj, x-rst.obj, x-glade.obj +xgettext_OBJECTS = xgettext.obj, x-c.obj, x-po.obj, x-python.obj, x-lisp.obj, x-elisp.obj, x-librep.obj, x-smalltalk.obj, x-java.obj, x-awk.obj, x-ycp.obj, x-tcl.obj, x-php.obj, x-rst.obj, x-glade.obj x-ocaml.obj msgattrib_OBJECTS = msgattrib.obj msgcat_OBJECTS = msgcat.obj msgcomm_OBJECTS = msgcomm.obj @@ -213,6 +214,9 @@ format-php.obj : format-php.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) format-php.c +format-ocaml.obj : format-ocaml.c + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) format-ocaml.c + gettextsrc.olb : $(OBJECTS) $(AR) $(AR_FLAGS) gettextsrc.olb $(OBJECTS) @@ -290,6 +294,9 @@ x-php.obj : x-php.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) x-php.c +x-ocaml.obj : x-ocaml.c + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) x-ocaml.c + x-rst.obj : x-rst.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) x-rst.c diff -Nurd gettext-0.12.1/gettext-tools/src/format-ocaml.c gettext-0.12.1.ocaml/gettext-tools/src/format-ocaml.c --- gettext-0.12.1/gettext-tools/src/format-ocaml.c 1970-01-01 01:00:00.000000000 +0100 +++ gettext-0.12.1.ocaml/gettext-tools/src/format-ocaml.c 2003-07-16 22:19:35.000000000 +0200 @@ -0,0 +1,108 @@ +/* Ocaml format strings. + Copyright (C) 2001-2003 Free Software Foundation, Inc. + Written by Sylvain LE GALL , 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 +#endif + +#include +#include + +#include "format.h" +#include "xmalloc.h" +#include "xerror.h" +#include "format-invalid.h" +#include "error.h" +#include "progname.h" +#include "gettext.h" + +#define _(str) gettext (str) + +/* Ocaml Printf format string + Unfortunately, there is no way to explicitely use args in string from + ocaml. One way is to use Printf.* but, it needs a plain string ( and not + the return of a function ). + + Still working on it +*/ + +struct spec +{ + int directives; +}; + +static void * +format_parse (const char *format, char **invalid_reason) +{ + struct spec spec; + struct spec *result; + + spec.directives = 0; + + result = (struct spec *) xmalloc (sizeof (struct spec) ); + *result = spec; + return result; +} + +static void +format_free (void *descr) +{ + struct spec *spec = (struct spec *) descr; + + free (spec); +} + +static int +format_get_number_of_directives (void *descr) +{ + struct spec *spec = (struct spec *) descr; + + return spec->directives; +} + +static bool +format_check (const lex_pos_ty *pos, void *msgid_descr, void *msgstr_descr, + bool equality, bool noisy, const char *pretty_msgstr) +{ + struct spec *spec1 = (struct spec *) msgid_descr; + struct spec *spec2 = (struct spec *) msgstr_descr; + bool err = false; + unsigned int i; + + // We have always 0 directives + if ( equality ) + { + err = true; + } + else + { + err = false; + }; + + return err; +} + + +struct formatstring_parser formatstring_ocaml = +{ + format_parse, + format_free, + format_get_number_of_directives, + format_check +}; + diff -Nurd gettext-0.12.1/gettext-tools/src/format.c gettext-0.12.1.ocaml/gettext-tools/src/format.c --- gettext-0.12.1/gettext-tools/src/format.c 2002-08-19 13:00:09.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/format.c 2003-07-16 22:16:32.000000000 +0200 @@ -37,5 +37,6 @@ /* format_pascal */ &formatstring_pascal, /* format_ycp */ &formatstring_ycp, /* format_tcl */ &formatstring_tcl, - /* format_php */ &formatstring_php + /* format_php */ &formatstring_php, + /* format_ocaml */ &formatstring_ocaml }; diff -Nurd gettext-0.12.1/gettext-tools/src/format.h gettext-0.12.1.ocaml/gettext-tools/src/format.h --- gettext-0.12.1/gettext-tools/src/format.h 2003-02-24 11:50:20.000000000 +0100 +++ gettext-0.12.1.ocaml/gettext-tools/src/format.h 2003-07-03 18:47:27.000000000 +0200 @@ -67,6 +67,7 @@ extern struct formatstring_parser formatstring_ycp; extern struct formatstring_parser formatstring_tcl; extern struct formatstring_parser formatstring_php; +extern struct formatstring_parser formatstring_ocaml; /* Table of all format string parsers. */ extern struct formatstring_parser *formatstring_parsers[NFORMATS]; diff -Nurd gettext-0.12.1/gettext-tools/src/message.c gettext-0.12.1.ocaml/gettext-tools/src/message.c --- gettext-0.12.1/gettext-tools/src/message.c 2003-04-29 12:04:04.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/message.c 2003-07-16 22:09:07.000000000 +0200 @@ -45,7 +45,8 @@ /* format_pascal */ "object-pascal", /* format_ycp */ "ycp", /* format_tcl */ "tcl", - /* format_php */ "php" + /* format_php */ "php", + /* format_ocaml */ "ocaml" }; const char *const format_language_pretty[NFORMATS] = @@ -61,7 +62,8 @@ /* format_pascal */ "Object Pascal", /* format_ycp */ "YCP", /* format_tcl */ "Tcl", - /* format_php */ "PHP" + /* format_php */ "PHP", + /* format_ocaml */ "Objective Caml" }; diff -Nurd gettext-0.12.1/gettext-tools/src/message.h gettext-0.12.1.ocaml/gettext-tools/src/message.h --- gettext-0.12.1/gettext-tools/src/message.h 2003-04-29 12:04:04.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/message.h 2003-07-03 18:48:21.000000000 +0200 @@ -45,9 +45,10 @@ format_pascal, format_ycp, format_tcl, - format_php + format_php, + format_ocaml }; -#define NFORMATS 12 /* Number of format_type enum values. */ +#define NFORMATS 13 /* Number of format_type enum values. */ extern const char *const format_language[NFORMATS]; extern const char *const format_language_pretty[NFORMATS]; diff -Nurd gettext-0.12.1/gettext-tools/src/test.c gettext-0.12.1.ocaml/gettext-tools/src/test.c --- gettext-0.12.1/gettext-tools/src/test.c 1970-01-01 01:00:00.000000000 +0100 +++ gettext-0.12.1.ocaml/gettext-tools/src/test.c 2003-07-17 00:02:24.000000000 +0200 @@ -0,0 +1,25 @@ +#include +#include +#include "xsetenv.h" +#define _(string) gettext (string) + +int main (argc, argv) + int argc; + char *argv[]; +{ + int n = atoi (argv[2]); + + xsetenv ("LC_ALL", argv[1], 1); + if (setlocale (LC_ALL, "") == NULL) + { + fprintf (stderr, "Couldn't set locale.\n"); + exit (77); + } + + textdomain ("prog"); + bindtextdomain ("prog", "."); + + gettext("Bonjour"); + + exit (0); +} diff -Nurd gettext-0.12.1/gettext-tools/src/x-ocaml.c gettext-0.12.1.ocaml/gettext-tools/src/x-ocaml.c --- gettext-0.12.1/gettext-tools/src/x-ocaml.c 1970-01-01 01:00:00.000000000 +0100 +++ gettext-0.12.1.ocaml/gettext-tools/src/x-ocaml.c 2003-07-17 23:37:00.000000000 +0200 @@ -0,0 +1,873 @@ +/* xgettext Ocaml backend. + Copyright (C) 2003, Sylvain LE GALL + + 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 + +#include +#include +#include +#include +#include + +#include "message.h" +#include "x-ocaml.h" +#include "xgettext.h" +#include "error.h" +#include "progname.h" +#include "xmalloc.h" +#include "exit.h" +#include "hash.h" +#include "gettext.h" + +#define _(s) gettext(s) + + +/* Ocaml defines string format in +http://localhost/cgi-bin/dwww?type=file&location=/usr/share/doc/ocaml/docs/ocaml.html/manual009.html + + 1. Use the text at the adress given to lexify token from input stream + + 2. When a keyword is found find the attached string ( if any ) + + This lexer implements the above, and presents the scanner (in xgettext.c) + with a stream of Ocaml tokens. The comments are accumulated in a buffer, + and given to xgettext when asked for. */ + +enum xgettext_token_type_ty +{ + xgettext_token_type_string_literal, + xgettext_token_type_comment, + xgettext_token_type_symbol, + xgettext_token_type_keyword, + xgettext_token_type_beg_parent, + xgettext_token_type_end_parent, + xgettext_token_type_eof +}; + +typedef enum xgettext_token_type_ty xgettext_token_type_ty; + +typedef struct xgettext_token_ty xgettext_token_ty; +struct xgettext_token_ty +{ + xgettext_token_type_ty type; + + /* These fields are used only for xgettext_token_type_keyword. */ + int argnum1; + int argnum2; + + /* This field is used only for xgettext_token_type_string_literal. */ + char *string; + + /* These fields are only for + xgettext_token_type_keyword, + xgettext_token_type_string_literal. */ + lex_pos_ty pos; +}; + + +/* ========================= Lexer customization. ========================= */ + +/* ====================== Keyword set customization. ====================== */ + +/* If true extract all strings. */ +static bool extract_all = false; + +static hash_table keywords; +static bool default_keywords = true; + + +void +x_ocaml_extract_all () +{ + extract_all = true; +} + + +void +x_ocaml_keyword (const char *name) +{ + if (name == NULL) + default_keywords = false; + else + { + const char *end; + int argnum1; + int argnum2; + const char *colon; + + if (keywords.table == NULL) + init_hash (&keywords, 100); + + split_keywordspec (name, &end, &argnum1, &argnum2); + + /* The characters between name and end should form a valid Ocaml identifier. + A colon means an invalid parse in split_keywordspec(). */ + colon = strchr (name, ':'); + if (colon == NULL || colon >= end) + { + if (argnum1 == 0) + argnum1 = 1; + insert_entry (&keywords, name, end - name, + (void *) (long) (argnum1 + (argnum2 << 10))); + } + } +} + +bool +x_ocaml_any_keywords () +{ + return (keywords.filled > 0) || default_keywords; +} + +/* Finish initializing the keywords hash table. + Called after argument processing, before each file is processed. */ +static void +init_keywords () +{ + if (default_keywords) + { + x_ocaml_keyword ("gettext"); + x_ocaml_keyword ("Camlgettext.gettext"); + x_ocaml_keyword ("dgettext:2"); + x_ocaml_keyword ("Camlgettext.dgettext:2"); + x_ocaml_keyword ("dcgettext:2"); + x_ocaml_keyword ("Camlgettext.dcgettext:2"); + x_ocaml_keyword ("ngettext:1,2"); + x_ocaml_keyword ("Camlgettext.ngettext:1,2"); + x_ocaml_keyword ("dngettext:2,3"); + x_ocaml_keyword ("Camlgettext.dngettext:2,3"); + x_ocaml_keyword ("dcngettext:2,3"); + x_ocaml_keyword ("Camlgettext.dcngettext:2,3"); + x_ocaml_keyword ("gettext_noop:2,3"); + x_ocaml_keyword ("Camlgettext.gettext_noop:2,3"); + default_keywords = false; + } +} + + +/* ================== Reading of characters and tokens. =================== */ + +/* Real filename, used in error messages about the input file. */ +static const char *real_file_name; + +/* Logical filename and line number, used to label the extracted messages. */ +static char *logical_file_name; +static int line_number; + +/* The input file stream. */ +static FILE *fp; + + +/* Maximum used guaranteed to be < 4. */ +static unsigned char phase1_pushback[4]; +static int phase1_pushback_length; +static bool last_was_eof = false; + +static int +phase1_getc () +{ + int c; + + if (phase1_pushback_length) + { + c = phase1_pushback[--phase1_pushback_length]; + if ( c == '\n' ) + ++line_number; + + if ( c == EOF ) + last_was_eof = true; + + return c; + } + for (;;) + { + c = getc (fp); + switch (c) + { + case EOF: + if (ferror (fp)) + { + error (EXIT_FAILURE, errno, + _("error while reading \"%s\""), real_file_name); + }; + + if ( last_was_eof ) + { + /* We ask two time for eof... We are looping */ + error (EXIT_FAILURE, errno, + _("try to extract repeatedly eof while reading \"%s\""), real_file_name); + }; + + last_was_eof = true; + return EOF; + + case '\n': + ++line_number; + last_was_eof = false; + return '\n'; + + default: + last_was_eof = false; + return c; + } + } +} + + +static void +phase1_ungetc (int c) +{ + switch (c) + { + case EOF: + break; + + case '\n': + --line_number; + /* FALLTHROUGH */ + + default: + phase1_pushback[phase1_pushback_length++] = c; + break; + } +} + + +/* + Taken from the lexer.mll find at the adress given + */ + +static void +eof_error ( const char * where, int c ) +{ + if ( c == EOF ) + { + /* Error : we reach the end of the stream */ + + error_with_progname = false; + error (0, 0, _("%s:%d: warning: unterminated %s, we reach EOF"), + logical_file_name, line_number - 1, where); + error_with_progname = true; + } + +} + +#define IS_BLANKS(c) (c == ' ' || c == '\013' || c == '\t' || c == '\012' || c == '\010') + +#define IS_BACKSLASHES_ESCAPES(c) (( c == '\\' ) \ + || (c == '"') \ + || (c == '\'') \ + || (c == 'n') \ + || (c == 't') \ + || (c == 'b') \ + || (c == 'r')) + +#define VAL_BACKSLASHES_ESCAPES(c) \ + ( c == 'n' ? '\n' : \ + ( c == 't' ? '\t' : \ + ( c == 'b' ? '\b' : \ + ( c == 'r' ? '\r' : \ + c \ + )\ + )\ + )\ + )\ + +#define LINE_SPLIT 1000 + +static int +get_regular_char ( bool *is_backslashed ) +{ + int c, i, res; + + *is_backslashed = false; + c = phase1_getc(); + + if ( c == '\\' ) + { + c = phase1_getc(); + + if ( IS_BACKSLASHES_ESCAPES(c) ) + { + *is_backslashed = true; + res = VAL_BACKSLASHES_ESCAPES(c); + } + else if ( '0' <= c && c <= '9' ) + { + *is_backslashed = true; + for ( i = 0, res = 0 ; i < 3 ; i ++ ) + { + switch (c) + { + case '0' : case '1' : case '2' : case '3' : case '4' : + case '5' : case '6' : case '7' : case '8' : case '9' : + break; + default: + /* Error non number in the numeric definition*/ + error_with_progname = false; + error (0, 0, _( + "%s:%d: warning: numeric character constant contains non numeric char (%c)"), + logical_file_name, line_number - 1, c); + error_with_progname = true; + phase1_ungetc(c); + c = '0'; + break; + }; + res = res * 10 + (c - '0'); + c = phase1_getc(); + }; + + if ( res > 255 ) + { + /* Error number defined is too big */ + error_with_progname = false; + error (0, 0, _("%s:%d: warning: character constant too high"), + logical_file_name, line_number - 1); + error_with_progname = true; + res = 255; + }; + } + else + { + /* We have a backslash but nothing can be backslashed */ + *is_backslashed = false; + phase1_ungetc(c); + res = '\\'; + }; + } + else + { + *is_backslashed = false; + res = c; + }; + + return res; +} + +static void +extract_char ( xgettext_token_ty *tp ) +{ + int c, res; + bool is_backslashed; + char buffer[2]; + + + res = get_regular_char(&is_backslashed); + c = phase1_getc(); + + /* We verify that we reach the end of the char */ + + if ( c != '\'' ) + { + /* We have only the 'x which is a generic type */ + tp->type = xgettext_token_type_symbol; + tp->string = NULL; + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + + phase1_ungetc(c); + } + else + { + buffer[0]=res; + buffer[1]='\0'; + tp->type = xgettext_token_type_string_literal; + tp->string = xstrdup(buffer); + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + }; + +} + +static void +extract_string ( xgettext_token_ty *tp ) +{ + int bufmax = 0; + int bufpos = 0; + char *buffer = NULL; + int c, res; + bool is_backslashed; + + buffer = xrealloc (buffer, bufmax); + + c = get_regular_char(&is_backslashed); + + while ( !(c == '"' && !is_backslashed ) && c != EOF ) + { + + /* Possible start of a \\ (CR|LF|CRLF...) (' ' '\t')* ( line split ) ? */ + if ( c == '\\' && !is_backslashed ) + { + + c = phase1_getc(); + + while ( IS_BLANKS(c) ) + { + c = phase1_getc(); + }; + + phase1_ungetc(c); + } + else + { + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + } + + c = get_regular_char(&is_backslashed); + }; + + buffer[bufpos] = 0; + + tp->type = xgettext_token_type_string_literal; + tp->string = xstrdup (buffer); + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; +} + +static void +extract_comment ( xgettext_token_ty *tp ) +{ + int bufmax = 0; + int bufpos = 0; + char *buffer = NULL; + /* If we are here, it means we have gone through a leading (* */ + int comment_depth = 1; + int c1, c2; + + buffer = xrealloc (buffer, bufmax); + + c2 = phase1_getc(); + + while ( comment_depth != 0 ) + { + c1 = c2; + c2 = phase1_getc(); + /* Is it a *) ? */ + if ( c1 == '*' && c2 == ')' ) + { + comment_depth--; + } + else if ( c1 == '(' && c2 == '*' ) + { + comment_depth++; + }; + + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + }; + + /* We transform a multiline comment into a single line one */ + if ( c1 != '\r' && c1 != '\n' ) + { + buffer[bufpos++] = c1; + }; + }; + + bufpos--; /* We remove the trailing * */ + buffer[bufpos] = 0; + tp->type = xgettext_token_type_comment; + tp->string = xstrdup (buffer); + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; +} + +#define IN_RANGE(c, a, b) ( a <= c && c <= b ) +#define SKIP(c, test) \ + c = phase1_getc();\ + while ( test ) { c = phase1_getc() ; }; \ + phase1_ungetc(c) + +static void +extract_numeric ( xgettext_token_ty *tp ) +{ + int c1, c2, c; + /* We don't care about the numeric value... We just skip it */ + + c1 = phase1_getc(); + c2 = phase1_getc(); + + if ( c1 == '-' ) + { + c1 = c2; + c2 = phase1_getc(); + }; + + if ( c1 == '0' && (c2 == 'x' || c2 == 'X')) + { + SKIP(c, IN_RANGE(c, '0', '7') + || IN_RANGE(c, 'A', 'F') + || IN_RANGE(c, 'a', 'f')); + } + else if ( c1 == '0' && (c2 == 'o' || c2 == 'O')) + { + SKIP(c, IN_RANGE(c, '0', '7')); + } + else if ( c1 == '0' && (c2 == 'b' || c2 == 'B')) + { + SKIP(c, IN_RANGE(c, '0', '1')); + } + else + { + phase1_ungetc(c2); + phase1_ungetc(c1); + + SKIP(c, IN_RANGE(c, '0', '9')); + SKIP(c, (c == '.')); + SKIP(c, IN_RANGE(c, '0', '9')); + SKIP(c, (c == 'e' || c == 'E' || c == '+' || c == '-' ) ); + SKIP(c, IN_RANGE(c, '0', '9')); + } + + tp->type = xgettext_token_type_symbol; + tp->string = NULL; + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; +} + + +static void +extract_ident ( xgettext_token_ty *tp ) +{ + void *keyword_value; + int bufmax = 0; + int bufpos = 0; + char *buffer = NULL; + int c; + + buffer = xrealloc (buffer, bufmax); + + c = phase1_getc(); + + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + }; + + buffer[bufpos++] = c; + + c = phase1_getc(); + + while ( c != '(' && c != ')' && c !='"' && c!='\'' && c != EOF && !IS_BLANKS(c) ) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + }; + + buffer[bufpos++] = c; + + c = phase1_getc(); + } + + phase1_ungetc(c); + + buffer[bufpos] = 0; + + if (find_entry (&keywords, buffer, strlen(buffer), &keyword_value) == 0) + { + + tp->type = xgettext_token_type_keyword; + tp->string = NULL; + tp->argnum1 = (int) (long) keyword_value & ((1 << 10) - 1); + tp->argnum2 = (int) (long) keyword_value >> 10; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + } + else + { + tp->type = xgettext_token_type_symbol; + tp->string = NULL; + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + } +} + +static void +ocaml_lex ( xgettext_token_ty *tp ) +{ + int c; + + /* Eat white space and all this kind of stuff */ + + c = phase1_getc(); + + while ( IS_BLANKS(c) ) + { + c = phase1_getc(); + } + + + switch (c) + { + case '(' : + c = phase1_getc(); + if ( c == '*' ) + { + return extract_comment(tp); + } + else + { + phase1_ungetc(c); + tp->type = xgettext_token_type_beg_parent; + tp->string = NULL; + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + } + break; + + case ')' : + tp->type = xgettext_token_type_end_parent; + tp->string = NULL; + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + break; + + case '0' : case '1' : case '2' : case '3' : case '4' : + case '5' : case '6' : case '7' : case '8' : case '9' : + case '-' : case '.' : + phase1_ungetc(c); + return extract_numeric(tp); + break; + + case '\'' : + return extract_char(tp); + break; + + case '"' : + return extract_string(tp); + break; + + case EOF : + tp->type = xgettext_token_type_eof; + tp->string = NULL; + tp->argnum1 = 0; + tp->argnum2 = 0; + tp->pos.file_name = logical_file_name; + tp->pos.line_number = line_number; + break; + + default : + phase1_ungetc(c); + return extract_ident(tp); + break; + } +} + + +/* ========================= Extracting strings. ========================== */ + +/* The file is broken into tokens. Scan the token stream, looking for + a keyword, followed by a left paren, followed by a string. When we + see this sequence, we have something to remember. We assume we are + looking at a valid C or C++ program, and leave the complaints about + the grammar to the compiler. + + Normal handling: Look for + keyword ( ... msgid ... ) + Plural handling: Look for + keyword ( ... msgid ... msgid_plural ... ) + + We use recursion because the arguments before msgid or between msgid + and msgid_plural can contain subexpressions of the same form. */ + + +static bool +ocaml_parse ( message_list_ty *mlp ) +{ + xgettext_token_ty token; + message_ty *plural_mp = NULL; + int next_string = -1; + int next_plural = -1; + + for ( ; ; ) + { + ocaml_lex(&token); + + next_string--; + if ( next_string <= -1 ) + { + next_string = -1; + } + + next_plural--; + if ( next_plural <= -1 ) + { + next_plural = -1; + } + + if ( !extract_all ) + { + switch ( token.type ) + { + case xgettext_token_type_string_literal : + if ( next_string == 0 && next_plural > 0 ) + { + plural_mp=remember_a_message(mlp, token.string, &token.pos); + } + else if ( next_string == 0 && next_plural < 0 ) + { + remember_a_message(mlp, token.string, &token.pos); + plural_mp=NULL; + } + else if ( next_string < 0 && next_plural == 0 && plural_mp != NULL ) + { + remember_a_message_plural(plural_mp, token.string, &token.pos); + plural_mp = NULL; + } + else if ( next_string == 0 && next_plural == 0 ) + { + /* Error : we string && plural at the same time */ + error_with_progname = false; + error (0, 0, _("%s:%d: warning: plural and singular at the same position ( skipping )"), + logical_file_name, line_number - 1); + error_with_progname = true; + + next_string = -1; + next_plural = -1; + free(token.string); + } + else if ( next_string > 0 && next_plural == 0 ) + { + + /* Error : plural before singular*/ + error_with_progname = false; + error (0, 0, _("%s:%d: warning: plural before singular ( skipping )"), + logical_file_name, line_number - 1); + error_with_progname = true; + + next_string = -1; + next_plural = -1; + free(token.string); + + } + else if ( next_string < 0 && next_plural == 0 && plural_mp == NULL ) + { + /* Error : singular never found*/ + error_with_progname = false; + error (0, 0, _("%s:%d: warning: singular form never found ( skipping )"), + logical_file_name, line_number - 1); + error_with_progname = true; + + next_string = -1; + next_plural = -1; + free(token.string); + } + else + { + free(token.string); + } + break; + case xgettext_token_type_comment : + xgettext_comment_add(token.string); + free(token.string); + break; + case xgettext_token_type_symbol : + xgettext_comment_reset(); + break; + case xgettext_token_type_keyword : + next_string = token.argnum1; + next_plural = token.argnum2; + xgettext_comment_reset(); + break; + case xgettext_token_type_beg_parent : + xgettext_comment_reset(); + if ( !ocaml_parse(mlp) ) + { + /* Error : reach the end parenthized not balanced*/ + error_with_progname = false; + error (0, 0, _("%s:%d: warning: some parenthizes are not matched"), + logical_file_name, line_number - 1); + error_with_progname = true; + }; + break; + case xgettext_token_type_end_parent : + xgettext_comment_reset(); + return true; + break; + case xgettext_token_type_eof : + xgettext_comment_reset(); + return false; + break; + default : + abort(); + + } + } + else if ( token.type == xgettext_token_type_string_literal ) + { + if ( strlen(token.string) > 0 ) + remember_a_message(mlp, token.string, &token.pos); + } + else if ( token.type == xgettext_token_type_eof ) + { + return false; + } + } +} + + +void +extract_ocaml (FILE *f, + const char *real_filename, const char *logical_filename, + msgdomain_list_ty *mdlp) +{ + message_list_ty *mlp = mdlp->item[0]->messages; + + fp = f; + real_file_name = real_filename; + logical_file_name = xstrdup (logical_filename); + line_number = 1; + + init_keywords (); + + /* Eat token until eof */ + ocaml_parse(mlp); + + /* Close scanner. */ + fp = NULL; + real_file_name = NULL; + logical_file_name = NULL; + line_number = 0; +} + diff -Nurd gettext-0.12.1/gettext-tools/src/x-ocaml.h gettext-0.12.1.ocaml/gettext-tools/src/x-ocaml.h --- gettext-0.12.1/gettext-tools/src/x-ocaml.h 1970-01-01 01:00:00.000000000 +0100 +++ gettext-0.12.1.ocaml/gettext-tools/src/x-ocaml.h 2003-07-16 22:45:26.000000000 +0200 @@ -0,0 +1,35 @@ +/* xgettext Ocaml backend. + Copyright (C) 2003 Free Software Foundation, Inc. + Written by Sylvain LE GALL , 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. */ + + +#define EXTENSIONS_OCAML \ + { "ml", "Ocaml" }, \ + +#define SCANNERS_OCAML \ + { "Ocaml", extract_ocaml, &formatstring_ocaml }, \ + +/* Scan an Ocaml file and add its translatable strings to mdlp. */ +extern void extract_ocaml (FILE *fp, const char *real_filename, + const char *logical_filename, + msgdomain_list_ty *mdlp); + + +/* Handling of options specific to this language. */ + +extern void x_ocaml_extract_all (void); +extern void x_ocaml_keyword (const char *name); diff -Nurd gettext-0.12.1/gettext-tools/src/xgettext.c gettext-0.12.1.ocaml/gettext-tools/src/xgettext.c --- gettext-0.12.1/gettext-tools/src/xgettext.c 2003-05-21 12:56:46.000000000 +0200 +++ gettext-0.12.1.ocaml/gettext-tools/src/xgettext.c 2003-07-16 22:44:07.000000000 +0200 @@ -75,6 +75,7 @@ #include "x-ycp.h" #include "x-tcl.h" #include "x-php.h" +#include "x-ocaml.h" #include "x-rst.h" #include "x-glade.h" @@ -259,6 +260,7 @@ x_awk_extract_all (); x_tcl_extract_all (); x_php_extract_all (); + x_ocaml_extract_all (); x_glade_extract_all (); break; case 'c': @@ -318,6 +320,7 @@ x_awk_keyword (optarg); x_tcl_keyword (optarg); x_php_keyword (optarg); + x_ocaml_keyword (optarg); x_glade_keyword (optarg); } break; @@ -654,7 +657,7 @@ -L, --language=NAME recognise the specified language\n\ (C, C++, ObjectiveC, PO, Python, Lisp,\n\ EmacsLisp, librep, Smalltalk, Java,\n\ - JavaProperties, awk, YCP, Tcl, PHP, RST, Glade)\n")); + JavaProperties, awk, YCP, Tcl, PHP, RST, Glade, Ocaml)\n")); printf (_("\ -C, --c++ shorthand for --language=C++\n")); printf (_("\ @@ -1461,6 +1464,7 @@ SCANNERS_PHP SCANNERS_RST SCANNERS_GLADE + SCANNERS_OCAML /* Here will follow more languages and their scanners: perl, etc... Make sure new scanners honor the --exclude-file option. */ }; @@ -1509,6 +1513,7 @@ EXTENSIONS_PHP EXTENSIONS_RST EXTENSIONS_GLADE + EXTENSIONS_OCAML /* Here will follow more file extensions: sh, pl ... */ }; ocaml-gettext-0.4.2/po/000077500000000000000000000000001367051331200147115ustar00rootroot00000000000000ocaml-gettext-0.4.2/po/LINGUAS000066400000000000000000000000031367051331200157270ustar00rootroot00000000000000fr ocaml-gettext-0.4.2/po/Makefile000066400000000000000000000065321367051331200163570ustar00rootroot00000000000000########################################################################## # ocaml-gettext: a library to translate messages # # # # Copyright (C) 2003-2008 Sylvain Le Gall # # # # This library is free software; you can redistribute it and/or # # modify it under the terms of the GNU Lesser General Public # # License as published by the Free Software Foundation; either # # version 2.1 of the License, or (at your option) any later version; # # with the OCaml static compilation exception. # # # # This library 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 # # Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public # # License along with this library; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # # USA # ########################################################################## include ../ConfMakefile include ../TopMakefile OCAML_GETTEXT_PACKAGE = ocaml-gettext LINGUAS=$(shell cat LINGUAS) SOURCES=POTFILES OCAML_GETTEXT=$(BUILDBIN)/ocaml-gettext OCAML_GETTEXT_EXTRACT_OPTIONS=--extract-command $(BUILDBIN)/ocaml-xgettext OCAML_GETTEXT_COMPILE_OPTIONS= OCAML_GETTEXT_INSTALL_OPTIONS= OCAML_GETTEXT_MERGE_OPTIONS= POFILES=$(addsuffix .po,$(LINGUAS)) MOFILES=$(addsuffix .mo,$(LINGUAS)) POTFILE=$(OCAML_GETTEXT_PACKAGE).pot all: install-buildpo install: install-po uninstall: uninstall-po clean:: clean-po %.mo: %.po $(OCAML_GETTEXT) --action compile $(OCAML_GETTEXT_COMPILE_OPTIONS) \ --compile-output $@ $^ %.pot: $(SOURCES) $(OCAML_GETTEXT) --action extract $(OCAML_GETTEXT_EXTRACT_OPTIONS) \ --extract-pot $@ $^ %.po: $(POTFILE) $(OCAML_GETTEXT) --action merge $(OCAML_GETTEXT_MERGE_OPTIONS) \ --merge-pot $(POTFILE) $@ $(BUILDPO): mkdir -p $(BUILDPO) .PRECIOUS: $(POTFILE) install-buildpo: $(MOFILES) $(BUILDPO) $(OCAML_GETTEXT) $(OCAML_GETTEXT) --action install $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --install-textdomain $(OCAML_GETTEXT_PACKAGE) \ --install-destdir $(BUILDPO) $(MOFILES) install-po: $(MOFILES) $(OCAML_GETTEXT) $(OCAML_GETTEXT) --action install $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --install-textdomain $(OCAML_GETTEXT_PACKAGE) \ --install-destdir $(PODIR) $(MOFILES) uninstall-po: $(OCAML_GETTEXT) $(OCAML_GETTEXT) --action uninstall $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --uninstall-textdomain $(OCAML_GETTEXT_PACKAGE) \ --uninstall-orgdir $(PODIR) $(MOFILES) clean-po: -$(OCAML_GETTEXT) --action uninstall $(OCAML_GETTEXT_INSTALL_OPTIONS) \ --uninstall-textdomain $(OCAML_GETTEXT_PACKAGE) \ --uninstall-orgdir $(BUILDPO) $(MOFILES) -$(RM) $(MOFILES) ocaml-gettext-0.4.2/po/POTFILES000066400000000000000000000000371367051331200160610ustar00rootroot00000000000000../libgettext-ocaml/gettext.ml ocaml-gettext-0.4.2/po/fr.po000066400000000000000000000146361367051331200156720ustar00rootroot00000000000000#, fuzzy msgid "" msgstr "" "Project-Id-Version: ocaml-gettext v0.1.1\n" "Report-Msgid-Bugs-To: sylvain@le-gall.net\n" "POT-Creation-Date: 2005-03-13 17:26+0000\n" "PO-Revision-Date: 2005-03-15 01:04+0100\n" "Last-Translator: Sylvain Le Gall \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n>1;" #: ../libgettext-ocaml/gettext.ml:312 msgid " Choose how to handle failure in ocaml-gettext. Default: %s." msgstr " Choisir la façon de traiter les erreurs dans ocaml-gettext. Défaut : %s." #: ../libgettext-ocaml/gettext.ml:327 msgid " Disable the translation perform by ocaml-gettext. Default: enable." msgstr " Désactive la traduction faite par ocaml-gettext. Défaut : active." #: ../libgettext-ocaml/gettext.ml:217 msgid "An empty entry has been encounter." msgstr "Une entrée vide a été trouvée." #: ../libgettext-ocaml/gettext.ml:189 msgid "Cannot find an approriate ocaml-gettext compiled file ( %s )." msgstr "Impossible de trouver un fichier ocaml-gettext compilé approprié ( %s )." #: ../libgettext-ocaml/gettext.ml:251 msgid "Cannot find string %S." msgstr "Impossible de trouver la chaîne %S." #: ../libgettext-ocaml/gettext.ml:236 msgid "Could not open file %s." msgstr "Impossible d'ouvrir le fichier %s." #: ../libgettext-ocaml/gettext.ml:248 msgid "Error while merging two PO files: %S and %S cannot be merged." msgstr "Erreur lors de la fusion de 2 fichiers PO : %S et %S ne peuvent être fusionnés." #: ../libgettext-ocaml/gettext.ml:242 msgid "Error while processing parsing of PO file, in msgid %S, %d index is out of bound." msgstr "Erreur lors du décodage du fichier PO, au niveau de msgid %S, l'indice %d est hors limite." #: ../libgettext-ocaml/gettext.ml:239 msgid "Error while processing parsing of PO file: %S at %s." msgstr "Erreur lors du décodage du fichier PO : %S à %s." #: ../libgettext-ocaml/gettext.ml:202 msgid "Error while processing parsing of content-type at %s: %S." msgstr "Erreur lors du décodage du champs content-type à %s : %S." #: ../libgettext-ocaml/gettext.ml:194 msgid "Error while processing parsing of options at %s: %S." msgstr "Erreur lors du décodage des options à %s : %S." #: ../libgettext-ocaml/gettext.ml:198 msgid "Error while processing parsing of plural at %s: %S." msgstr "Erreur lors du décodage de la forme plurielle à %s : %S." #: ../libgettext-ocaml/gettext.ml:245 msgid "Error while trying to load PO file %s, file doesn't exist." msgstr "Erreur lors du chargement du fichier PO %s, le fichier n'existe pas." #: ../libgettext-ocaml/gettext.ml:214 msgid "Junk at the end of the plural form id %S: %s." msgstr "Caractères non utilisé à la fin de la forme plurielle %S : %s." #: ../libgettext-ocaml/gettext.ml:206 msgid "MO file provided is not encoded following ocaml-gettext convention." msgstr "Le fichier MO fourni ne suit pas les règles de la librairie ocaml-gettext." #: ../libgettext-ocaml/gettext.ml:219 msgid "Number of strings is negative." msgstr "Le nombre de chaîne de caractères est négatif." #: ../libgettext-ocaml/gettext.ml:192 msgid "Ocaml-gettext library is not initialized" msgstr "La librairie ocaml-gettext n'est pas initialisée." #: ../libgettext-ocaml/gettext.ml:221 msgid "Offset of string table is out of bound ([%ld,%ld] should be in [%ld,%ld])." msgstr "Le décalage de la table de chaîne de caractère est hors limite ( [%ld,%ld] devrait être dans l'intervalle [%ld,%ld] )." #: ../libgettext-ocaml/gettext.ml:224 msgid "Offset of translation table is out of bound ([%ld,%ld] should be in [%ld,%dl])." msgstr "Le décalage de la table de chaîne de traduction est hors limite ( [%ld,%ld] devrait être dans l'intervalle [%ld,%ld] )." #: ../libgettext-ocaml/gettext.ml:230 msgid "Out of bound access when trying to find a string (%d < %d)." msgstr "Accès hors limite lors de la recherche d'une chaîne de caractère ( %d < %d )." #: ../libgettext-ocaml/gettext.ml:233 msgid "Out of bound access when trying to find a translation (%d < %d)." msgstr "Accès hors limite lors de la recherche d'une traduction ( %d < %d )." #: ../libgettext-ocaml/gettext.ml:181 msgid "Problem reading file %s: %s." msgstr "Problème lors de la lecture du fichier %s : %s." #: ../libgettext-ocaml/gettext.ml:183 msgid "Problem while extracting %s: command %S exits with code %d." msgstr "Problème lors de l'extraction %s : la commande %S s'est terminée avec le code de sortie %d." #: ../libgettext-ocaml/gettext.ml:186 msgid "Problem while extracting %s: command %S killed by signal %d." msgstr "Problème lors de l'extraction %s : la commande %S a été tuée avec le signal %d." #: ../libgettext-ocaml/gettext.ml:227 msgid "Translation table and string table overlap ([%ld,%ld] and [%ld,%ld] have a non empty intersection)." msgstr "Les tables de traduction et de chaîne de caractères se recouvrent ( [%ld,%ld] et [%ld,%ld] ont une intersection non vide )." #: ../libgettext-ocaml/gettext.ml:208 msgid "Trying to fetch the plural form %d of a singular form %S." msgstr "Tentative de récupération de la forme plurielle %d d'une forme singulière %S." #: ../libgettext-ocaml/gettext.ml:211 msgid "Trying to fetch the plural form %d of plural form %s." msgstr "Tentative de récupération de la forme plurielle %d de la forme plurielle %d." #: ../libgettext-ocaml/gettext.ml:254 msgid "Unable to parse the POSIX language environment variable %s" msgstr "" #: ../libgettext-ocaml/gettext.ml:387 msgid "codeset Set the default codeset for outputting string with ocaml-gettext. Default: %s." msgstr "codeset Défini le jeux de caractères à utiliser pour écrire les traductions. Défaut : %s." #: ../libgettext-ocaml/gettext.ml:364 msgid "dir Add a search dir for ocaml-gettext files. Default: %s." msgstr "dir Ajoute une répertoire de recherche pour les fichiers ocaml-gettext. Défaut : %s." #: ../libgettext-ocaml/gettext.ml:373 msgid "language Set the default language for ocaml-gettext. Default: %s." msgstr "language Défini le langage par défaut pour ocaml-gettext. Défaut : %s." #: ../libgettext-ocaml/gettext.ml:176 msgid "line %d character %d" msgstr "la ligne %d au caractère %d" #: ../libgettext-ocaml/gettext.ml:343 msgid "textdomain dir Set a dir to search ocaml-gettext files for the specified domain. Default: %s." msgstr "textdomain dir Défini un répertoire de recherche des fichiers ocaml-gettext pour le domaine de texte spécifié. Défaut : %s." ocaml-gettext-0.4.2/po/ocaml-gettext.pot000066400000000000000000000104721367051331200202160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-09-16 20:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: ../libgettext-ocaml/gettext.ml:312 msgid " Choose how to handle failure in ocaml-gettext. Default: %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:327 msgid " Disable the translation perform by ocaml-gettext. Default: enable." msgstr "" #: ../libgettext-ocaml/gettext.ml:217 msgid "An empty entry has been encounter." msgstr "" #: ../libgettext-ocaml/gettext.ml:189 msgid "Cannot find an approriate ocaml-gettext compiled file ( %s )." msgstr "" #: ../libgettext-ocaml/gettext.ml:251 msgid "Cannot find string %S." msgstr "" #: ../libgettext-ocaml/gettext.ml:236 msgid "Could not open file %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:248 msgid "Error while merging two PO files: %S and %S cannot be merged." msgstr "" #: ../libgettext-ocaml/gettext.ml:242 msgid "Error while processing parsing of PO file, in msgid %S, %d index is out of bound." msgstr "" #: ../libgettext-ocaml/gettext.ml:239 msgid "Error while processing parsing of PO file: %S at %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:202 msgid "Error while processing parsing of content-type at %s: %S." msgstr "" #: ../libgettext-ocaml/gettext.ml:194 msgid "Error while processing parsing of options at %s: %S." msgstr "" #: ../libgettext-ocaml/gettext.ml:198 msgid "Error while processing parsing of plural at %s: %S." msgstr "" #: ../libgettext-ocaml/gettext.ml:245 msgid "Error while trying to load PO file %s, file doesn't exist." msgstr "" #: ../libgettext-ocaml/gettext.ml:214 msgid "Junk at the end of the plural form id %S: %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:206 msgid "MO file provided is not encoded following ocaml-gettext convention." msgstr "" #: ../libgettext-ocaml/gettext.ml:219 msgid "Number of strings is negative." msgstr "" #: ../libgettext-ocaml/gettext.ml:192 msgid "Ocaml-gettext library is not initialized" msgstr "" #: ../libgettext-ocaml/gettext.ml:221 msgid "Offset of string table is out of bound ([%ld,%ld] should be in [%ld,%ld])." msgstr "" #: ../libgettext-ocaml/gettext.ml:224 msgid "Offset of translation table is out of bound ([%ld,%ld] should be in [%ld,%dl])." msgstr "" #: ../libgettext-ocaml/gettext.ml:230 msgid "Out of bound access when trying to find a string (%d < %d)." msgstr "" #: ../libgettext-ocaml/gettext.ml:233 msgid "Out of bound access when trying to find a translation (%d < %d)." msgstr "" #: ../libgettext-ocaml/gettext.ml:181 msgid "Problem reading file %s: %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:183 msgid "Problem while extracting %s: command %S exits with code %d." msgstr "" #: ../libgettext-ocaml/gettext.ml:186 msgid "Problem while extracting %s: command %S killed by signal %d." msgstr "" #: ../libgettext-ocaml/gettext.ml:227 msgid "Translation table and string table overlap ([%ld,%ld] and [%ld,%ld] have a non empty intersection)." msgstr "" #: ../libgettext-ocaml/gettext.ml:208 msgid "Trying to fetch the plural form %d of a singular form %S." msgstr "" #: ../libgettext-ocaml/gettext.ml:211 msgid "Trying to fetch the plural form %d of plural form %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:254 msgid "Unable to parse the POSIX language environment variable %s" msgstr "" #: ../libgettext-ocaml/gettext.ml:387 msgid "codeset Set the default codeset for outputting string with ocaml-gettext. Default: %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:364 msgid "dir Add a search dir for ocaml-gettext files. Default: %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:373 msgid "language Set the default language for ocaml-gettext. Default: %s." msgstr "" #: ../libgettext-ocaml/gettext.ml:176 msgid "line %d character %d" msgstr "" #: ../libgettext-ocaml/gettext.ml:343 msgid "textdomain dir Set a dir to search ocaml-gettext files for the specified domain. Default: %s." msgstr "" ocaml-gettext-0.4.2/src/000077500000000000000000000000001367051331200150625ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/bin/000077500000000000000000000000001367051331200156325ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/bin/ocaml-gettext/000077500000000000000000000000001367051331200204075ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/bin/ocaml-gettext/OCamlGettext.ml000066400000000000000000000367051367051331200233140ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Ocaml-gettext tools. @author Sylvain Le Gall *) (** Helper program to: - extract translatable strings from OCaml source, - compile PO file, - install MO file, - merge POT and PO file. *) open GettextTypes open GettextCategory open GettextUtils open FilePath.DefaultPath module OCamlGettextRealize = GettextDummy.Generic module OcamlGettext = Gettext.Program (struct let textdomain = "ocaml-gettext" let codeset = None let dir = None let dependencies = Gettext.init end) (OCamlGettextRealize) type action = | Extract | Compile | Install | Uninstall | Merge | Version | VersionShort type t = { action_option : action option; extract_command : string; extract_default_option : string; extract_filename_options : (string * string) list; extract_pot : string; compile_output_file_option : string option; install_language_option : string option; install_category : GettextCategory.category; install_textdomain_option : string option; install_destdir : string; uninstall_language_option : string option; uninstall_category : GettextCategory.category; uninstall_textdomain_option : string option; uninstall_orgdir : string; merge_filename_pot : string; merge_backup_extension : string; input_files : string list; strict : bool; } exception ActionRequired exception InstallUninstallTooManyFilename exception CompileTooManyFilename let string_of_exception exc = let s_ x = OcamlGettext.s_ x in match exc with | ActionRequired -> s_ "You must specify one action." | InstallUninstallTooManyFilename -> s_ "You cannot specify at the same time a language, a textdomain\n\ and provide more than one file to install/uninstall : all files\n\ will have the same destination filename." | CompileTooManyFilename -> s_ "You cannot specify a output filename and more than one\n\ filename : all the compiled file will have the same output filename" | _ -> Gettext.string_of_exception exc let do_extract t = let real_lst = let rec extract_potfiles accu lst = match lst with | str :: lst when str = "POTFILES" -> let chn = open_in str in let new_accu = let rec extract_potfiles_aux accu = try let new_filename = input_line chn in extract_potfiles_aux (new_filename :: accu) with End_of_file -> accu in extract_potfiles_aux accu in close_in chn; extract_potfiles new_accu lst | str :: lst -> extract_potfiles (str :: accu) lst | [] -> List.rev accu in extract_potfiles [] t.input_files in let map_filename_options = List.fold_left (fun map (fl, options) -> MapString.add fl options map) MapString.empty t.extract_filename_options in GettextCompile.extract t.extract_command t.extract_default_option map_filename_options real_lst t.extract_pot let do_compile t = match (t.compile_output_file_option, t.input_files) with | Some fl_mo, [ fl_po ] -> GettextCompile.compile fl_po fl_mo | None, lst -> let fl_mo_of_fl_po fl_po = (* BUG: should use add_extension *) chop_extension fl_po ^ ".mo" in List.iter (fun fl_po -> GettextCompile.compile fl_po (fl_mo_of_fl_po fl_po)) lst | Some _, [] -> () | Some _, _ -> raise CompileTooManyFilename let guess_language_textdomain (language_option, textdomain_option) lst = (* Rules for guessing language : language[.textdomain].mo *) match (language_option, textdomain_option, lst) with | Some language, Some textdomain, [ fl_mo ] -> [ (language, textdomain, fl_mo) ] | Some _, Some _, [] -> [] | Some _, Some _, _ -> raise InstallUninstallTooManyFilename | Some language, None, lst -> List.map (fun fl_mo -> (language, chop_extension fl_mo, fl_mo)) lst | None, Some textdomain, lst -> List.map (fun fl_mo -> (chop_extension fl_mo, textdomain, fl_mo)) lst | None, None, lst -> List.map (fun _fl_mo -> (* BUG: should be able to have get_extension working *) (* let str_reduce = chop_extension fl_mo in * (((chop_extension str_reduce), (get_extension str_reduce)),fl_mo)*) raise (Failure "FilePath suffers from a default with the handling of\n\ chop/get_extension. This bug should disappears with\n\ newer version of ocaml-fileutils")) lst let do_install t = let install (language, textdomain, fl_mo) = GettextCompile.install t.strict t.install_destdir language t.install_category textdomain fl_mo in List.iter install (guess_language_textdomain (t.install_language_option, t.install_textdomain_option) t.input_files) let do_uninstall t = let uninstall (language, textdomain, _) = GettextCompile.uninstall t.uninstall_orgdir language t.uninstall_category textdomain in List.iter uninstall (guess_language_textdomain (t.uninstall_language_option, t.uninstall_textdomain_option) t.input_files) let do_merge t = GettextCompile.merge t.merge_filename_pot t.input_files t.merge_backup_extension let do_action t = match t.action_option with | Some Extract -> do_extract t | Some Compile -> do_compile t | Some Install -> do_install t | Some Uninstall -> do_uninstall t | Some Merge -> do_merge t | Some Version -> let _, gettext_copyright = OcamlGettext.init in print_string gettext_copyright; print_newline () | Some VersionShort -> print_string GettextConfig.version; print_newline () | None -> raise ActionRequired let () = let spf x = Printf.sprintf x in let f_ x = OcamlGettext.f_ x in let s_ x = OcamlGettext.s_ x in let t = ref { action_option = None; extract_command = "ocaml-xgettext"; extract_default_option = ""; extract_filename_options = []; extract_pot = "messages.pot"; compile_output_file_option = None; install_language_option = None; install_category = LC_MESSAGES; install_textdomain_option = None; install_destdir = GettextConfig.default_dir; uninstall_language_option = None; uninstall_category = LC_MESSAGES; uninstall_textdomain_option = None; uninstall_orgdir = GettextConfig.default_dir; merge_filename_pot = "messages.pot"; merge_backup_extension = "bak"; input_files = []; strict = false; } in let actions = [ ("extract", Extract); ("compile", Compile); ("install", Install); ("uninstall", Uninstall); ("merge", Merge); ] in let gettext_args, gettext_copyright = OcamlGettext.init in let args = Arg.align ( [ ( "--action", Arg.Symbol ( List.map fst actions, fun symbol -> try t := { !t with action_option = Some (List.assoc symbol actions); } with Not_found -> raise (Arg.Bad (spf (f_ "Invalid action: %s.") symbol)) ), s_ "Action to execute. Default: none." ); ( "--extract-command", Arg.String (fun cmd -> t := { !t with extract_command = cmd }), spf (f_ "cmd Command to extract translatable strings from an OCaml \ source file. Default: %s.") !t.extract_command ); ( "--extract-default-option", Arg.String (fun default_option -> t := { !t with extract_default_option = default_option }), spf (f_ "options Default option used when extracting translatable \ strings. Default: %S.") !t.extract_default_option ); ( "--extract-filename-option", Arg.Tuple (let filename = ref "" in [ Arg.String (fun str -> filename := str); Arg.String (fun options -> t := { !t with extract_filename_options = (!filename, options) :: !t.extract_filename_options; }); ]), spf (f_ "filename options Per filename option used when extracting \ strings from the specified filename. Default: %s.") (string_of_list (List.map (fun (str1, str2) -> spf "(%s,%s)" str1 str2) !t.extract_filename_options)) ); ( "--extract-pot", Arg.String (fun str -> t := { !t with extract_pot = str }), spf (f_ "filename POT file to write when extracting translatable \ strings. Default: %s.") !t.extract_pot ); ( "--compile-output", Arg.String (fun str -> t := { !t with compile_output_file_option = Some str }), s_ "filename MO file to write when compiling a PO file. Default: \ name of the PO file with \".mo\" extension." ); ( "--install-language", Arg.String (fun str -> t := { !t with install_language_option = Some str }), s_ "language Language to use when installing a MO file. Default: \ try to guess it from the name of the MO file." ); ( "--install-category", Arg.String (fun str -> t := { !t with install_category = GettextCategory.category_of_string str; }), spf (f_ "category Category to use when installing a MO file. \ Default: %s.") (GettextCategory.string_of_category !t.install_category) ); ( "--install-textdomain", Arg.String (fun str -> t := { !t with install_textdomain_option = Some str }), s_ "textdomain Textdomain to use when installing a MO file. \ Default: try to guess it from the name of the MO file." ); ( "--install-destdir", Arg.String (fun str -> t := { !t with install_destdir = str }), spf (f_ "dirname Base dir used when installing a MO file. Default: %s.") !t.install_destdir ); ( "--strict", Arg.Unit (fun () -> t := { !t with strict = true }), spf (f_ " Additional check are errors during install. Default: %b.") !t.strict ); ( "--uninstall-language", Arg.String (fun str -> t := { !t with uninstall_language_option = Some str }), s_ "language Language to use when uninstalling a MO file. Default: \ try to guess it from the name of the MO file." ); ( "--uninstall-category", Arg.String (fun str -> t := { !t with uninstall_category = GettextCategory.category_of_string str; }), spf (f_ "category Category to use when uninstalling a MO file. \ Default: %s.") (GettextCategory.string_of_category !t.uninstall_category) ); ( "--uninstall-textdomain", Arg.String (fun str -> t := { !t with uninstall_textdomain_option = Some str }), s_ "textdomain Textdomain to use when uninstalling a MO file. \ Default: try to guess it from the name of the MO file." ); ( "--uninstall-orgdir", Arg.String (fun str -> t := { !t with uninstall_orgdir = str }), spf (f_ "dirname Base dir used when uninstalling a MO file. Default: \ %s.") !t.uninstall_orgdir ); ( "--merge-pot", Arg.String (fun str -> t := { !t with merge_filename_pot = str }), spf (f_ "filename POT file to use as a master for merging PO file. \ Default: %s.") !t.merge_filename_pot ); ( "--merge-backup-extension", Arg.String (fun str -> t := { !t with merge_backup_extension = str }), spf (f_ "extension Backup extension to use when moving PO file which \ have been merged. Default: %s.") !t.merge_backup_extension ); ( "--version", Arg.Unit (fun () -> t := { !t with action_option = Some Version }), s_ " Returns version information on ocaml-gettext." ); ( "--short-version", Arg.Unit (fun () -> t := { !t with action_option = Some VersionShort }), s_ " Returns only the version string of ocaml-gettext." ); ] @ gettext_args ) in let () = Arg.parse args (fun str -> t := { !t with input_files = str :: !t.input_files }) (spf (f_ "%s\n\n\ Command: ocaml-gettext -action (%s) [options]\n\ When trying to guess language and textdomain from a\n\ MO file, the rules applied are: language.textdomain.mo\n\n\ Options:") gettext_copyright (String.concat "|" (List.map fst actions))) in try do_action !t with exc -> prerr_string (string_of_exception exc); prerr_newline (); prerr_string (s_ "An error occurs while processing."); prerr_newline (); exit 1 ocaml-gettext-0.4.2/src/bin/ocaml-gettext/dune000066400000000000000000000002101367051331200212560ustar00rootroot00000000000000(executable (name OCamlGettext) (public_name ocaml-gettext) (package gettext) (libraries gettext.base gettext.extension fileutils)) ocaml-gettext-0.4.2/src/bin/ocaml-xgettext/000077500000000000000000000000001367051331200205775ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/bin/ocaml-xgettext/dune000066400000000000000000000003411367051331200214530ustar00rootroot00000000000000(executable (name xgettext) (public_name ocaml-xgettext) (package gettext) (preprocess (action (run %{bin:cppo} -V OCAML:%{ocaml_version} %{input-file}))) (libraries compiler-libs.common gettext.base gettext.extension)) ocaml-gettext-0.4.2/src/bin/ocaml-xgettext/xgettext.ml000066400000000000000000000226051367051331200230120ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** PPX dumper to extract strings. @author Richard W.M. Jones @author Sylvain Le Gall *) (* Extract the string which should be used for a gettext translation. Output a po_content list through the function Marshal.to_channel Functions that are looked for : Functions Arg 1 Arg 2 Arg 3 Arg 4 Arg 5 Arg 6 ... s_ singular f_ singular sn_ singular plural _ fn_ singular plural _ gettext _ singular fgettext _ singular dgettext _ domain singular fdgettext _ domain singular dcgettext _ domain singular _ fdcgettext _ domain singular _ ngettext _ singular plural _ fngettext _ singular plural _ dngettext _ domain singular plural _ fdngettext _ domain singular plural _ dcngettext _ domain singular plural _ _ fdcngettext _ domain singular plural _ _ All this function name should also be matched when they are called using a module. *) open GettextTypes open GettextPo open Parsetree open Longident type t = { po_content : po_content; translated : SetString.t } let translations = ref { po_content = empty_po; translated = SetString.empty } let default_textdomain = ref None let current_file = ref "" let add_translation loc singular plural_opt domain = let t = !translations in let filepos = let start = loc.Location.loc_start in let fname = match start.Lexing.pos_fname with "" -> !current_file | fname -> fname in (fname, start.Lexing.pos_lnum) in let translated = SetString.add singular t.translated in let translated, translation = match plural_opt with | Some plural -> ( SetString.add plural translated, { po_comment_special = []; po_comment_filepos = [ filepos ]; po_comment_translation = PoPlural ([ singular ], [ plural ], [ [ "" ]; [ "" ] ]); } ) | None -> ( translated, { po_comment_special = []; po_comment_filepos = [ filepos ]; po_comment_translation = PoSingular ([ singular ], [ "" ]); } ) in let po_content = match (domain, !default_textdomain) with | Some domain, _ -> add_po_translation_domain domain t.po_content translation | None, Some domain -> add_po_translation_domain domain t.po_content translation | None, None -> add_po_translation_no_domain t.po_content translation in translations := { po_content; translated } let output_translations ?output_file t = let fd = match output_file with Some f -> open_out f | None -> stdout in set_binary_mode_out fd true; Marshal.to_channel fd t.po_content [] let rec is_like lid = function | [] -> false | func :: functions -> ( match lid with | (Lident f | Ldot (_, f)) when f = func -> true | _ -> is_like lid functions ) let visit_expr (iterator : Ast_iterator.iterator) expr = let loc = expr.pexp_loc in match expr.pexp_desc with | Pexp_apply ( { pexp_desc = Pexp_ident { Asttypes.txt = lid; _ }; _ }, ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (singular, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (singular, _)); _ } ) #endif :: _ ) when is_like lid [ "s_"; "f_" ] -> (* Add a singular / default domain string *) add_translation loc singular None None | Pexp_apply ( { pexp_desc = Pexp_ident { Asttypes.txt = lid; _ }; _ }, ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (singular, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (singular, _)); _ } ) #endif :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (plural, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (plural, _)); _ } ) #endif :: _ ) when is_like lid [ "sn_"; "fn_" ] -> (* Add a plural / default domain string *) add_translation loc singular (Some plural) None | Pexp_apply ( { pexp_desc = Pexp_ident { Asttypes.txt = lid; _ }; _ }, _ :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (singular, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (singular, _)); _ } ) #endif :: _ ) when is_like lid [ "gettext"; "fgettext" ] -> (* Add a singular / default domain string *) add_translation loc singular None None | Pexp_apply ( { pexp_desc = Pexp_ident { Asttypes.txt = lid; _ }; _ }, _ :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (domain, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (domain, _)); _ } ) #endif :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (singular, _, _)); _ } #else { pexp_desc = Pexp_constant (Pconst_string (singular, _)); _ } #endif ) :: _ ) when is_like lid [ "dgettext"; "fdgettext"; "dcgettext"; "fdcgettext" ] -> (* Add a singular / defined domain string *) add_translation loc singular None (Some domain) | Pexp_apply ( { pexp_desc = Pexp_ident { Asttypes.txt = lid; _ }; _ }, _ :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (singular, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (singular, _)); _ } ) #endif :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (plural, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (plural, _)); _ } ) #endif :: _ ) when is_like lid [ "ngettext"; "fngettext" ] -> (* Add a plural / default domain string *) add_translation loc singular (Some plural) None | Pexp_apply ( { pexp_desc = Pexp_ident { Asttypes.txt = lid; _ }; _ }, _ :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (domain, _, _)); _ } ) #else { pexp_desc = Pexp_constant (Pconst_string (domain, _)); _ } ) #endif :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (singular, _, _)); _ } #else { pexp_desc = Pexp_constant (Pconst_string (singular, _)); _ } #endif ) :: ( Asttypes.Nolabel, #if OCAML_VERSION >= (4, 11, 0) { pexp_desc = Pexp_constant (Pconst_string (plural, _, _)); _ } #else { pexp_desc = Pexp_constant (Pconst_string (plural, _)); _ } #endif ) :: _ ) when is_like lid [ "dngettext"; "fdngettext"; "dcngettext"; "fdcngettext" ] -> (* Add a plural / defined domain string *) add_translation loc singular (Some plural) (Some domain) | _ -> Ast_iterator.default_iterator.expr iterator expr let ast_iterator = { Ast_iterator.default_iterator with expr = visit_expr } let go fn = current_file := fn; try let lexbuf = Lexing.from_channel (open_in fn) in let structure = Parse.implementation lexbuf in ast_iterator.Ast_iterator.structure ast_iterator structure with exn -> failwith (fn ^ ": " ^ Printexc.to_string exn) let () = (* XXX Add -default-textdomain option which sets default_textdomain. *) Arg.parse [] go ""; output_translations !translations ocaml-gettext-0.4.2/src/lib/000077500000000000000000000000001367051331200156305ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/lib/gettext-camomile/000077500000000000000000000000001367051331200211005ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/lib/gettext-camomile/dune000066400000000000000000000002101367051331200217470ustar00rootroot00000000000000(library (name gettextCamomile) (public_name gettext-camomile) (wrapped false) (libraries gettext.extension gettext.base camomile)) ocaml-gettext-0.4.2/src/lib/gettext-camomile/gettextCamomile.ml000066400000000000000000000076021367051331200245720ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open CamomileLibraryDefault.Camomile open GettextTypes (** Error reported when something goes wrong during Camomile initialization. *) exception GettextCamomileCreate of string * exn (** Error reported when something goes wrong during Camomile operation. *) exception GettextCamomileRecode of string * exn (** Charset module, that is derived directly from the camomile library. *) module Charset : GettextCharset.CHARSET_TYPE = struct (**/**) type encoding = string type u = { failsafe : failsafe; in_enc : CharEncoding.t; out_enc : CharEncoding.t; } let create t in_enc out_enc = try { failsafe = t.GettextTypes.failsafe; in_enc = CharEncoding.of_name in_enc; out_enc = CharEncoding.of_name out_enc; } with e -> GettextUtils.fail_or_continue t.GettextTypes.failsafe (GettextCamomileCreate ( Printf.sprintf "Cannot create conversion from %s to %s" in_enc out_enc, e )) { failsafe = t.GettextTypes.failsafe; in_enc = CharEncoding.of_name "ISO-8859-1"; out_enc = CharEncoding.of_name "ISO-8859-1"; } let recode u str = try CharEncoding.recode_string ~in_enc:u.in_enc ~out_enc:u.out_enc str with e -> GettextUtils.fail_or_continue u.failsafe (GettextCamomileCreate ( Printf.sprintf "Cannot create convert string %s from %s to %s" str (CharEncoding.name_of u.in_enc) (CharEncoding.name_of u.out_enc), e )) str end (** Implementation based on a Map storage for string. *) module Map : GettextTypes.REALIZE_TYPE = GettextRealize.Generic (GettextTranslate.Map) (* Map translation *) (Charset) (* Camomile charset *) (GettextLocale.Posix) (** Implementation based on a Hashtbl storage for string. *) module Hashtbl : GettextTypes.REALIZE_TYPE = GettextRealize.Generic (GettextTranslate.Hashtbl) (* Hashtbl translation *) (Charset) (* Camomile charset *) (GettextLocale.Posix) (** Low memory and fast initialization implementation, files are opened only when needed. *) module Open : GettextTypes.REALIZE_TYPE = GettextRealize.Generic (GettextTranslate.Open) (* Open translation *) (Charset) (* Camomile charset *) (GettextLocale.Posix) ocaml-gettext-0.4.2/src/lib/gettext-camomile/gettextCamomile.mli000066400000000000000000000004141367051331200247350ustar00rootroot00000000000000exception GettextCamomileCreate of string * exn exception GettextCamomileRecode of string * exn module Charset : GettextCharset.CHARSET_TYPE module Map : GettextTypes.REALIZE_TYPE module Hashtbl : GettextTypes.REALIZE_TYPE module Open : GettextTypes.REALIZE_TYPE ocaml-gettext-0.4.2/src/lib/gettext-stub/000077500000000000000000000000001367051331200202675ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/lib/gettext-stub/dune000066400000000000000000000005741367051331200211530ustar00rootroot00000000000000(library (name gettextStub) (public_name gettext-stub) (c_names gettextStubCompat_stubs) (c_flags (:include c_flags.sexp)) (c_library_flags (:include c_library_flags.sexp)) (wrapped false) (libraries gettext.base gettext.extension)) (rule (targets c_flags.sexp c_library_flags.sexp) (deps (:discover ../../tools/discover-stub/discover.exe)) (action (run %{discover}))) ocaml-gettext-0.4.2/src/lib/gettext-stub/gettextStub.ml000066400000000000000000000136351367051331200231530ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Concrete implementation based on native gettext library. @see Gettext library @author Sylvain Le Gall *) (** {1 Concrete implementations} *) open GettextTypes open GettextUtils open GettextCategory (** Native implementation of gettext. All translation are bound to C library call. Still use check_format, to ensure that strings follow printf format. *) module Native : GettextTypes.REALIZE_TYPE = struct (**/**) let realize t = (* Here we do the binding between C library call and the information we have in parameter t. *) let native_category_of_category cat = match cat with | GettextCategory.LC_CTYPE -> GettextStubCompat.LC_CTYPE | GettextCategory.LC_NUMERIC -> GettextStubCompat.LC_NUMERIC | GettextCategory.LC_TIME -> GettextStubCompat.LC_TIME | GettextCategory.LC_COLLATE -> GettextStubCompat.LC_COLLATE | GettextCategory.LC_MONETARY -> GettextStubCompat.LC_MONETARY | GettextCategory.LC_MESSAGES -> GettextStubCompat.LC_MESSAGES | GettextCategory.LC_ALL -> GettextStubCompat.LC_ALL in let default_dir = match t.path with default_dir :: _ -> Some default_dir | [] -> None in let bind_textdomain_one textdomain (codeset_opt, dir_opt) = (let codeset = match codeset_opt with Some codeset -> codeset | None -> t.codeset in ignore (GettextStubCompat.bind_textdomain_codeset textdomain codeset)); match dir_opt with | Some dir -> ignore (GettextStubCompat.bindtextdomain textdomain dir) | None -> ( match default_dir with | Some dir -> ignore (GettextStubCompat.bindtextdomain textdomain dir) | None -> () ) in (* We only use the first path of t.path, since there is no notion of search path in native gettext. So the MO file should be in : - first component of t.path, - directory pointed by bindtextdomain, - default directory of gettext. *) let _ = GettextStubCompat.textdomain t.default in let _ = match t.language with | Some language -> ( try GettextStubCompat.setlocale GettextStubCompat.LC_ALL language with Failure _ as exc -> let () = fail_or_continue t.failsafe exc () in GettextStubCompat.setlocale GettextStubCompat.LC_ALL "" ) | None -> GettextStubCompat.setlocale GettextStubCompat.LC_ALL "" in let () = MapCategory.iter (fun cat locale -> ignore (GettextStubCompat.setlocale (native_category_of_category cat) locale)) t.categories in let () = MapTextdomain.iter bind_textdomain_one t.textdomains in fun printf_format textdomain_opt str_id str_plural_opt cat -> let check x = if printf_format then match GettextFormat.check_format t.failsafe (Singular (str_id, x)) with | Singular (_, str) -> str | _ -> str_id else x in let ncat = native_category_of_category cat in let textdomain = match textdomain_opt with | Some textdomain -> textdomain | None -> t.default in let translation = match str_plural_opt with | Some (str_plural, n) -> GettextStubCompat.dcngettext textdomain str_id str_plural n ncat | None -> GettextStubCompat.dcgettext textdomain str_id ncat in check translation end (** Native implementation of gettext. Use the Native module, but use informations provided to preload all textdomain translation. The preload is made by trying to translate the string "", which is mandatory in MO file. This is not the default behavior of gettext. Use this module if you know that it is better to preload all string. Don't use this module if you think you will only have a few strings to translate. *) module Preload : GettextTypes.REALIZE_TYPE = struct (**/**) let realize t = let t' = Native.realize t in let () = MapTextdomain.iter (fun textdomain _ -> (* We only load LC_MESSAGES, since it is what is mainly use with * gettext. Anyway, this is just a local optimization... *) ignore (t' false (Some textdomain) "" None LC_MESSAGES)) t.textdomains in t' end ocaml-gettext-0.4.2/src/lib/gettext-stub/gettextStubCompat.ml000066400000000000000000000075241367051331200243170ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Low level interface to gettext C library. @author Sylvain Le Gall *) type lc = | LC_CTYPE | LC_NUMERIC | LC_TIME | LC_COLLATE | LC_MONETARY | LC_MESSAGES | LC_ALL external setlocale : lc -> string -> string option = "gettextStubCompat_setlocale" (** Set the current localization for the category *) external gettext : string -> string = "gettextStubCompat_gettext" (** Look up MSGID in the current default message catalog for the current * LC_MESSAGES locale. If not found, returns MSGID itself (the default text). *) external dgettext : string -> string -> string = "gettextStubCompat_dgettext" (** Look up MSGID in the DOMAINNAME message catalog for the current LC_MESSAGES * locale. *) external dcgettext : string -> string -> lc -> string = "gettextStubCompat_dcgettext" (** Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY * locale. *) external ngettext : string -> string -> int -> string = "gettextStubCompat_ngettext" (** Similar to `gettext' but select the plural form corresponding to the number * N. *) external dngettext : string -> string -> string -> int -> string = "gettextStubCompat_dngettext" (** Similar to `dgettext' but select the plural form corresponding to the number * N. *) external dcngettext : string -> string -> string -> int -> lc -> string = "gettextStubCompat_dcngettext" (** Similar to `dcgettext' but select the plural form corresponding to the * number N. *) external textdomain : string -> string option = "gettextStubCompat_textdomain" (** Set the current default message catalog to DOMAINNAME.If DOMAINNAME is "", * reset to the default of "messages". *) external get_textdomain : unit -> string option = "gettextStubCompat_get_textdomain" (** Get the current default message catalog to DOMAINNAME. *) external bindtextdomain : string -> string -> string option = "gettextStubCompat_bindtextdomain" (** Specify that the DOMAINNAME message catalog will be foundin DIRNAME rather * than in the system locale data base. *) external bind_textdomain_codeset : string -> string -> string option = "gettextStubCompat_bind_textdomain_codeset" (** Specify the character encoding in which the messages from theDOMAINNAME * message catalog will be returned. *) ocaml-gettext-0.4.2/src/lib/gettext-stub/gettextStubCompat_stubs.c000066400000000000000000000121711367051331200253430ustar00rootroot00000000000000/**************************************************************************/ /* ocaml-gettext: a library to translate messages */ /* */ /* Copyright (C) 2003-2008 Sylvain Le Gall */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version; */ /* with the OCaml static compilation exception. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ /* USA */ /**************************************************************************/ #include #include #include #include #include #define STRINGIFY(x) #x /* Make a string option value from a const string which might be NULL. */ static value return_string_option (const char *str) { CAMLparam0 (); CAMLlocal2 (rv, strv); if (str == NULL) rv = Val_int (0); /* None */ else { strv = caml_copy_string (str); rv = caml_alloc (1, 0); Store_field (rv, 0, strv); } CAMLreturn (rv); } int ml2c_lc_tab[7] = { LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, LC_ALL }; inline int ml2c_lc(value v) { return ml2c_lc_tab[Int_val(v)]; } CAMLprim value gettextStubCompat_setlocale( value v_n, value v_val) { CAMLparam2(v_n, v_val); CAMLreturn( return_string_option ( setlocale( ml2c_lc(v_n), String_val(v_val)))); } CAMLprim value gettextStubCompat_gettext( value v_msgid) { CAMLparam1(v_msgid); CAMLreturn(copy_string(gettext(String_val(v_msgid)))); } CAMLprim value gettextStubCompat_dgettext( value v_domainname, value v_msgid) { CAMLparam2(v_domainname, v_msgid); CAMLreturn( copy_string( dgettext( String_val(v_domainname), String_val(v_msgid)))); } CAMLprim value gettextStubCompat_dcgettext( value v_domainname, value v_msgid, value v_category) { CAMLparam3(v_domainname, v_msgid, v_category); CAMLreturn( copy_string( dcgettext( String_val(v_domainname), String_val(v_msgid), ml2c_lc(v_category)))); } CAMLprim value gettextStubCompat_ngettext( value v_msgid1, value v_msgid2, value v_n) { CAMLparam3(v_msgid1, v_msgid2, v_n); CAMLreturn( copy_string( ngettext( String_val(v_msgid1), String_val(v_msgid2), Long_val(v_n)))); } CAMLprim value gettextStubCompat_dngettext( value v_domainname, value v_msgid1, value v_msgid2, value v_n) { CAMLparam4(v_domainname, v_msgid1, v_msgid2, v_n); CAMLreturn( copy_string( dngettext( String_val(v_domainname), String_val(v_msgid1), String_val(v_msgid2), Long_val(v_n)))); } CAMLprim value gettextStubCompat_dcngettext( value v_domainname, value v_msgid1, value v_msgid2, value v_n, value v_category) { char *res = NULL; CAMLparam5(v_domainname, v_msgid1, v_msgid2, v_n, v_category); res = dcngettext( String_val(v_domainname), String_val(v_msgid1), String_val(v_msgid2), Long_val(v_n), ml2c_lc(v_category)); if (res == NULL) { caml_failwith( "NULL string not expected at "STRINGIFY(__LINE__)" in "__FILE__); }; CAMLreturn(copy_string(res)); } CAMLprim value gettextStubCompat_textdomain( value v_domainname) { CAMLparam1(v_domainname); CAMLreturn(return_string_option(textdomain(String_val(v_domainname)))); } CAMLprim value gettextStubCompat_get_textdomain(value v_unit) { CAMLparam1(v_unit); CAMLreturn(return_string_option(textdomain(NULL))); } CAMLprim value gettextStubCompat_bindtextdomain( value v_domainname, value v_dirname) { CAMLparam2(v_domainname, v_dirname); CAMLreturn( return_string_option ( bindtextdomain( String_val(v_domainname), String_val(v_dirname)))); } CAMLprim value gettextStubCompat_bind_textdomain_codeset( value v_domainname, value v_codeset) { CAMLparam2(v_domainname, v_codeset); CAMLreturn( return_string_option ( bind_textdomain_codeset( String_val(v_domainname), String_val(v_codeset)))); } ocaml-gettext-0.4.2/src/lib/gettext/000077500000000000000000000000001367051331200173145ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/lib/gettext/base/000077500000000000000000000000001367051331200202265ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/lib/gettext/base/dune000066400000000000000000000005451367051331200211100ustar00rootroot00000000000000(ocamllex (modules gettextFormat_lexer gettextMo_lexer)) (ocamlyacc (modules gettextFormat_parser gettextMo_parser)) (library (name gettextBase) (wrapped false) (public_name gettext.base) (private_modules GettextConfigGen GettextFormat_lexer GettextFormat_parser GettextMo_int32 GettextMo_lexer GettextMo_parser) (libraries fileutils)) ocaml-gettext-0.4.2/src/lib/gettext/base/gettext.ml000066400000000000000000000277741367051331200222650ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open GettextTypes open GettextCompat open GettextUtils open GettextModules open Lexing (* Function the main global variable of gettext with/without thread *) type global_type = { t : t option; realize : t -> t'; t' : t' option } (* Default value *) let dummy_realize _t _printf_format _textdomain str _str_plural _category = str let default_realize = dummy_realize (* Referenced function used to manage access to global variable, in other word to be fullfiled with mutex locking/unlocking if needed *) let global_lock = ref (fun () -> ()) let global_unlock = ref (fun () -> ()) let global = ref { t = None; realize = default_realize; t' = None } let get_global_t () = let t = !global_lock (); !global.t in !global_unlock (); match t with Some t -> t | None -> raise GettextUninitialized let set_global_t t = let () = !global_lock (); global := { !global with t = Some t; t' = None } in !global_unlock () let set_global_realize realize = let () = !global_lock (); global := { !global with realize; t' = None } in !global_unlock () let get_global_t' () = let t' = !global_lock (); match !global.t' with | None -> (* Try to build it out of the other value provided *) let t = match !global.t with | Some t -> t | None -> raise GettextUninitialized in let t' = !global.realize t in global := { !global with t' = Some t' }; t' | Some t' -> t' in !global_unlock (); t' (* High level functions *) module Library (Init : INIT_TYPE) = struct let init = (Init.textdomain, Init.codeset, Init.dir) :: Init.dependencies let s_ str = dgettext (get_global_t' ()) Init.textdomain str let f_ str = fdgettext (get_global_t' ()) Init.textdomain str let sn_ str = dngettext (get_global_t' ()) Init.textdomain str let fn_ str = fdngettext (get_global_t' ()) Init.textdomain str end (* i18n/l10n of gettext it self *) module GettextGettext = Library (struct let textdomain = "ocaml-gettext" let codeset = None let dir = None let dependencies = [] (* Off course, we don't depend on anything because we are the root of translation *) end) (* Initialization of gettext library *) let init = GettextGettext.init (* Exception *) let string_of_exception exc = (* It is important to keep the name f_ and s_, in order to allow ocaml-gettext program to extract the string *) let f_ x = GettextGettext.f_ x in let s_ x = GettextGettext.s_ x in let spf x = Printf.sprintf x in let string_of_pos lexbuf = let char_pos = lexbuf.lex_curr_p.pos_cnum - lexbuf.lex_curr_p.pos_bol in let line_pos = lexbuf.lex_curr_p.pos_lnum in spf (f_ "line %d character %d") line_pos char_pos in match exc with | CompileProblemReadingFile (fln, error) -> spf (f_ "Problem reading file %s: %s.") fln error | CompileExtractionFailed (fln, cmd, status) -> spf (f_ "Problem while extracting %s: command %S exits with code %d.") fln cmd status | CompileExtractionInterrupted (fln, cmd, signal) -> spf (f_ "Problem while extracting %s: command %S killed by signal %d.") fln cmd signal | DomainFileDoesntExist lst -> spf (f_ "Cannot find an approriate ocaml-gettext compiled file ( %s ).") (string_of_list lst) | GettextUninitialized -> s_ "Ocaml-gettext library is not initialized" | MoInvalidOptions (lexbuf, text) -> spf (f_ "Error while processing parsing of options at %s: %S.") (string_of_pos lexbuf) text | MoInvalidPlurals (lexbuf, text) -> spf (f_ "Error while processing parsing of plural at %s: %S.") (string_of_pos lexbuf) text | MoInvalidContentType (lexbuf, text) -> spf (f_ "Error while processing parsing of content-type at %s: %S.") (string_of_pos lexbuf) text | MoInvalidFile -> s_ "MO file provided is not encoded following ocaml-gettext convention." | MoInvalidTranslationSingular (str, x) -> spf (f_ "Trying to fetch the plural form %d of a singular form %S.") x str | MoInvalidTranslationPlural (lst, x) -> spf (f_ "Trying to fetch the plural form %d of plural form %s.") x (string_of_list lst) | MoJunk (id, lst) -> spf (f_ "Junk at the end of the plural form id %S: %s.") id (string_of_list lst) | MoEmptyEntry -> s_ "An empty entry has been encounter." | MoInvalidHeaderNegativeStrings -> s_ "Number of strings is negative." | MoInvalidHeaderTableStringOutOfBound ((b1, e1), (b2, e2)) -> spf (f_ "Offset of string table is out of bound ([%ld,%ld] should be in \ [%ld,%ld]).") b1 e1 b2 e2 | MoInvalidHeaderTableTranslationOutOfBound ((b1, e1), (b2, e2)) -> spf (f_ "Offset of translation table is out of bound ([%ld,%ld] should be \ in [%ld,%ld]).") b1 e1 b2 e2 | MoInvalidHeaderTableTranslationStringOverlap ((b1, e1), (b2, e2)) -> spf (f_ "Translation table and string table overlap ([%ld,%ld] and \ [%ld,%ld] have a non empty intersection).") b1 e1 b2 e2 | MoInvalidStringOutOfBound (max, cur) -> spf (f_ "Out of bound access when trying to find a string (%d < %d).") max cur | MoInvalidTranslationOutOfBound (max, cur) -> spf (f_ "Out of bound access when trying to find a translation (%d < %d).") max cur | MoCannotOpenFile fln -> spf (f_ "Could not open file %s.") fln | PoInvalidFile (s, lexbuf, _chn) -> spf (f_ "Error while processing parsing of PO file: %S at %s.") s (string_of_pos lexbuf) | PoFileInvalidIndex (id, i) -> spf (f_ "Error while processing parsing of PO file, in msgid %S, %d index \ is out of bound.") id i | PoFileDoesntExist fl -> spf (f_ "Error while trying to load PO file %s, file doesn't exist.") fl | PoInconsistentMerge (str1, str2) -> spf (f_ "Error while merging two PO files: %S and %S cannot be merged.") str1 str2 | TranslateStringNotFound str -> spf (f_ "Cannot find string %S.") str | LocalePosixUnparseable str -> spf (f_ "Unable to parse the POSIX language environment variable %s") str | _ -> Printexc.to_string exc module Program (Init : INIT_TYPE) (Realize : REALIZE_TYPE) = struct let textdomain = Init.textdomain let dependencies = (Init.textdomain, Init.codeset, Init.dir) :: Init.dependencies let init = (* Initialization from all the known textdomain/codeset/dir provided by library linked with the program *) (* It is important to keep f_ and s_, for the same reason as in string_of_exception *) let f_ x = GettextGettext.f_ x in let s_ x = GettextGettext.s_ x in let spf x = Printf.sprintf x in let () = set_global_t (GettextModules.create textdomain) in let () = set_global_t (List.fold_left (fun t (textdomain, codeset_opt, dir_opt) -> upgrade_textdomain t textdomain (codeset_opt, dir_opt)) (get_global_t ()) dependencies) in let () = set_global_realize Realize.realize in ( [ ( "--gettext-failsafe", Arg.Symbol ( [ "ignore"; "inform-stderr"; "raise-exception" ], fun x -> match x with | "ignore" -> set_global_t { (get_global_t ()) with failsafe = Ignore } | "inform-stderr" -> set_global_t { (get_global_t ()) with failsafe = InformStderr string_of_exception; } | "raise-exception" -> set_global_t { (get_global_t ()) with failsafe = RaiseException } | _ -> () ), spf (f_ " Choose how to handle failure in ocaml-gettext. Default: %s.") ( match (get_global_t ()).failsafe with | Ignore -> "ignore" | InformStderr _ -> "inform-stderr" | RaiseException -> "raise-exception" ) ); ( "--gettext-disable", Arg.Unit (fun () -> set_global_realize dummy_realize), s_ " Disable the translation perform by ocaml-gettext. Default: \ enable." ); ( "--gettext-domain-dir", (let current_textdomain = ref textdomain in Arg.Tuple [ Arg.String (fun textdomain -> current_textdomain := textdomain); Arg.String (fun dir -> set_global_t (bindtextdomain !current_textdomain dir (get_global_t ()))); ]), spf (f_ "textdomain dir Set a dir to search ocaml-gettext files for \ the specified domain. Default: %s.") (string_of_list (MapTextdomain.fold (fun textdomain (_, dir_opt) lst -> match dir_opt with | Some dir -> spf "%s: %s" textdomain dir :: lst | None -> lst) (get_global_t ()).textdomains [])) ); ( "--gettext-dir", Arg.String (fun s -> set_global_t { (get_global_t ()) with path = s :: (get_global_t ()).path }), spf (f_ "dir Add a search dir for ocaml-gettext files. Default: %s.") (string_of_list (get_global_t ()).path) ); ( "--gettext-language", Arg.String (fun s -> set_global_t { (get_global_t ()) with language = Some s }), spf (f_ "language Set the default language for ocaml-gettext. Default: \ %s.") ( match (get_global_t ()).language with | Some s -> s | None -> "(none)" ) ); ( "--gettext-codeset", Arg.String (fun s -> set_global_t { (get_global_t ()) with codeset = s }), spf (f_ "codeset Set the default codeset for outputting string with \ ocaml-gettext. Default: %s.") (get_global_t ()).codeset ); ], GettextConfig.copyright ) let s_ str = dgettext (get_global_t' ()) textdomain str let f_ str = fdgettext (get_global_t' ()) textdomain str let sn_ str = dngettext (get_global_t' ()) textdomain str let fn_ str = fdngettext (get_global_t' ()) textdomain str end ocaml-gettext-0.4.2/src/lib/gettext/base/gettext.mli000066400000000000000000000103721367051331200224200ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Modules to use in libraries and programs. @author Sylvain Le Gall *) (** This module defines all the function required to use gettext. The primary design is to use applicative function. The "side effect" of such a choice is that you must defines, before using any function, all the text domains, codeset et al. When building a library, you should give access to [Library.init] (by defining a [gettext_init = YouLibrary.init]). This is required to enable string translation in the library and programs that uses the library. The only function missing here is the [realize] function. This function is defined in a real implementation library : {ul {- {!GettextDummy}} {- {!GettextCamomile}} {- {!GettextStub}} } *) (** {1 Exception} *) (** Return the string representation of a ocaml-gettext exception. *) val string_of_exception : exn -> string (** {1 High level interfaces} *) (** Value of the dependencies for the initialization of the library Gettext (for translating exception and help message). *) val init : GettextTypes.dependencies (** Module to handle typical library requirement *) module Library (Init : GettextTypes.INIT_TYPE) : sig (** Definition of all variables required by ocaml-gettext to use this module (includes all the dependencies of the library, as defined in {!GettextTypes.Init}). *) val init : GettextTypes.dependencies (** Translate a singular string. *) val s_ : string -> string (** Translate a [Printf] singular argument. *) val f_ : ('a, 'b, 'c, 'c, 'c, 'd) format6 -> ('a, 'b, 'c, 'c, 'c, 'd) format6 (** Translate a plural string. *) val sn_ : string -> string -> int -> string (** Translate a [Printf] plural argument. *) val fn_ : ('a, 'b, 'c, 'c, 'c, 'd) format6 -> ('a, 'b, 'c, 'c, 'c, 'd) format6 -> int -> ('a, 'b, 'c, 'c, 'c, 'd) format6 end (** Module to handle typical program requirement *) module Program (Init : GettextTypes.INIT_TYPE) (Realize : GettextTypes.REALIZE_TYPE) : sig (** The first element is a [Arg] argument list. The second element contains some information about the gettext library (version, build date and author). *) val init : (Arg.key * Arg.spec * Arg.doc) list * string (** See {!Library.s_} *) val s_ : string -> string (** See {!Library.f_} *) val f_ : ('a, 'b, 'c, 'c, 'c, 'd) format6 -> ('a, 'b, 'c, 'c, 'c, 'd) format6 (** See {!Library.sn_} *) val sn_ : string -> string -> int -> string (** See {!Library.fn_} *) val fn_ : ('a, 'b, 'c, 'c, 'c, 'd) format6 -> ('a, 'b, 'c, 'c, 'c, 'd) format6 -> int -> ('a, 'b, 'c, 'c, 'c, 'd) format6 end ocaml-gettext-0.4.2/src/lib/gettext/base/gettextCategory.ml000066400000000000000000000054261367051331200237510ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Functions to manipulate category. @author Sylvain Le Gall *) type category = | LC_CTYPE | LC_NUMERIC | LC_TIME | LC_COLLATE | LC_MONETARY | LC_MESSAGES | LC_ALL let string_of_category cat = match cat with | LC_CTYPE -> "LC_CTYPE" | LC_NUMERIC -> "LC_NUMERIC" | LC_TIME -> "LC_TIME" | LC_COLLATE -> "LC_COLLATE" | LC_MONETARY -> "LC_MONETARY" | LC_MESSAGES -> "LC_MESSAGES" | LC_ALL -> "LC_ALL" let category_of_string str = match str with | "LC_CTYPE" -> LC_CTYPE | "LC_NUMERIC" -> LC_NUMERIC | "LC_TIME" -> LC_TIME | "LC_COLLATE" -> LC_COLLATE | "LC_MONETARY" -> LC_MONETARY | "LC_MESSAGES" -> LC_MESSAGES | "LC_ALL" -> LC_ALL | _ -> raise (Invalid_argument "category_of_string") let categories = [ LC_CTYPE; LC_NUMERIC; LC_TIME; LC_COLLATE; LC_MONETARY; LC_MESSAGES; LC_ALL; ] let compare c1 c2 = let val_category x = match x with | LC_CTYPE -> 0 | LC_NUMERIC -> 1 | LC_TIME -> 2 | LC_COLLATE -> 3 | LC_MONETARY -> 4 | LC_MESSAGES -> 5 | LC_ALL -> 6 in compare (val_category c1) (val_category c2) module MapCategory = Map.Make (struct type t = category let compare = compare end) ocaml-gettext-0.4.2/src/lib/gettext/base/gettextCompat.ml000066400000000000000000000071761367051331200234230ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open GettextTypes open GettextCategory open GettextModules let unsafe_format_of_string fmt str = if false then Obj.magic str else format_of_string fmt let bindtextdomain textdomain dir t = upgrade_textdomain t textdomain (None, Some dir) let bind_textdomain_codeset textdomain codeset t = upgrade_textdomain t textdomain (Some codeset, None) let textdomain default t = { t with default } let get_textdomain t = t.default let gettext t' str = t' false None str None LC_MESSAGES let fgettext t' fmt = unsafe_format_of_string fmt (t' true None (string_of_format fmt) None LC_MESSAGES) let dgettext t' textdomain str = t' false (Some textdomain) str None LC_MESSAGES let fdgettext t' textdomain fmt = unsafe_format_of_string fmt (t' true (Some textdomain) (string_of_format fmt) None LC_MESSAGES) let dcgettext t' textdomain str category = t' false (Some textdomain) str None category let fdcgettext t' textdomain fmt category = unsafe_format_of_string fmt (t' true (Some textdomain) (string_of_format fmt) None category) let ngettext t' str str_plural n = t' false None str (Some (str_plural, n)) LC_MESSAGES let fngettext t' fmt fmt_plural n = if true then unsafe_format_of_string fmt (t' true None (string_of_format fmt) (Some (string_of_format fmt_plural, n)) LC_MESSAGES) else fmt_plural let dngettext t' textdomain str str_plural n = t' false (Some textdomain) str (Some (str_plural, n)) LC_MESSAGES let fdngettext t' textdomain fmt fmt_plural n = if true then unsafe_format_of_string fmt (t' true (Some textdomain) (string_of_format fmt) (Some (string_of_format fmt_plural, n)) LC_MESSAGES) else fmt_plural let dcngettext t' textdomain str str_plural n category = t' false (Some textdomain) str (Some (str_plural, n)) category let fdcngettext t' textdomain fmt fmt_plural n category = if true then unsafe_format_of_string fmt (t' true (Some textdomain) (string_of_format fmt) (Some (string_of_format fmt_plural, n)) category) else fmt_plural ocaml-gettext-0.4.2/src/lib/gettext/base/gettextCompat.mli000066400000000000000000000112721367051331200235640ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Gettext compatibility with the native gettext API @author Sylvain Le Gall *) open GettextTypes open GettextCategory val textdomain : textdomain -> t -> t (** [textdomain domain t] Set the current text domain. *) val get_textdomain : t -> textdomain (** [get_textdomain t] Returns the current text domain. *) val bindtextdomain : textdomain -> dir -> t -> t (** [bindtextdomain textdomain dir] Set the default base directory for the specified domain. *) val bind_textdomain_codeset : textdomain -> codeset -> t -> t (** [bind_textdomain_codeset textdomain codeset] Set the codeset to use for the specified domain. [codeset] must be a valid codeset for the underlying character encoder/decoder (iconv, camomile, extlib...) *) val gettext : t' -> string -> string (** [gettext t' str] Translate the string [str]. *) val fgettext : t' -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) format6 (** [fgettext t' str] [gettext] returning format. *) val dgettext : t' -> textdomain -> string -> string (** [dgettext t' textdomain str] Translate the string [str] for the specified domain. *) val fdgettext : t' -> textdomain -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) format6 (** [fdgettext t' textdomain str] [dgettext] returning format. *) val dcgettext : t' -> textdomain -> string -> category -> string (** [dcgettext t' textdomain str category] Translate the string [str] for the specified domain and category. *) val fdcgettext : t' -> textdomain -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> category -> ('a, 'b, 'c, 'd, 'e, 'f) format6 (** [fdcgettext t' textdomain str category] [dcgettext] returning format. *) val ngettext : t' -> string -> string -> int -> string (** [ngettext t' str str_plural n] Translate the string [str] using a plural form. str_plural is the default english plural. n is the relevant number for plural (i.e. the number of objects deals with the string). *) val fngettext : t' -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> int -> ('a, 'b, 'c, 'd, 'e, 'f) format6 (** [fngettext t' str str_plural n] [ngettext] returning format. *) val dngettext : t' -> textdomain -> string -> string -> int -> string (** [dngettext t' textdomain str str_plural n] Translate the string [str] using a plural form for the specified domain. *) val fdngettext : t' -> textdomain -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> int -> ('a, 'b, 'c, 'd, 'e, 'f) format6 (** [fdngettext t' textdomain str str_plural n] [dngettext] returning format. *) val dcngettext : t' -> textdomain -> string -> string -> int -> category -> string (** [dcngettext t' textdomain str str_plural n category] Translate the string [str] using a plural form for the specified domain and category. *) val fdcngettext : t' -> textdomain -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) format6 -> int -> category -> ('a, 'b, 'c, 'd, 'e, 'f) format6 (** [fdcngettext t' textdomain str str_plural n category] [dcngettext] returning format. *) ocaml-gettext-0.4.2/src/lib/gettext/base/gettextConfig.ml000066400000000000000000000037431367051331200234010ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) let default_dir = GettextConfigGen.default_localedir let default_path = [ GettextConfigGen.localedir; GettextConfigGen.default_localedir ] let default_codeset = "" let copyright = "ocaml-gettext v" ^ GettextConfigGen.version ^ "\n" ^ "Copyright (C) 2003-2008 Sylvain Le Gall \n" ^ "Licenced under LGPL v2.1 with Ocaml exception" let version = GettextConfigGen.version ocaml-gettext-0.4.2/src/lib/gettext/base/gettextConfigGen.ml000066400000000000000000000001541367051331200240240ustar00rootroot00000000000000let default_localedir = "/usr/share/locale" let localedir = "/usr/local/share/locale" let version = "dev" ocaml-gettext-0.4.2/src/lib/gettext/base/gettextDummy.ml000066400000000000000000000036571367051331200232730ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Concrete implementation based on nothing. @author Sylvain Le Gall *) open GettextTypes module Generic : REALIZE_TYPE = struct let realize _t _printf_format _opt str plural_form _category = match plural_form with | Some (str_plural, n) -> if GettextMo.germanic_plural n = 0 then str else str_plural | None -> str end ocaml-gettext-0.4.2/src/lib/gettext/base/gettextFormat.ml000066400000000000000000000064211367051331200234200ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Check string equivalence regarding printf use. @author Sylvain Le Gall *) open GettextTypes open GettextUtils (** [check_format failsafe translation] Returns a translation structure if all the string contained in the translation are equivalent of str_id, regarding printf format. If not, replace each string which conflict by str_id, in the result. *) let check_format failsafe translation = let format_lst_of_string str = let lexbuf = Lexing.from_string str in GettextFormat_parser.main GettextFormat_lexer.token lexbuf in (* return true in case of problem *) let check_format_lst_lst lst1 lst2 = let check_format_lst_lst_aux b s1 s2 = b || String.compare s1 s2 <> 0 in try List.fold_left2 check_format_lst_lst_aux false lst1 lst2 with Invalid_argument _ -> true in let check_format_lst_str lst str = check_format_lst_lst lst (format_lst_of_string str) in let choose_format lst_ref str_ref str = if check_format_lst_str lst_ref str then fail_or_continue failsafe (FormatInconsistent (str, str_ref)) str_ref else str in match translation with | Singular (str_id, str) -> let lst_id = format_lst_of_string str_id in Singular (str_id, choose_format lst_id str_id str) | Plural (str_id, str_plural, lst) -> let lst_id = format_lst_of_string str_id in let valid_str_plural = choose_format lst_id str_id str_plural in let valid_lst = match lst with | trans_singular :: trans_plurals -> choose_format lst_id str_id trans_singular :: List.map (choose_format lst_id valid_str_plural) trans_plurals | [] -> [] in Plural (str_id, valid_str_plural, valid_lst) ocaml-gettext-0.4.2/src/lib/gettext/base/gettextFormat_lexer.mll000066400000000000000000000045671367051331200250040ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) { open GettextFormat_parser;; } let flags = ['-''0''+'' ']* ['0'-'9']* ('.'['0'-'9']*)? rule token = parse '%' flags { format_char lexbuf } | eof { EOF } | _ { token lexbuf } and format_char = parse "d" as fc | "i" as fc | "n" as fc | "N" as fc | "u" as fc | "x" as fc | "X" as fc | "o" as fc | "s" as fc | "S" as fc | "c" as fc | "C" as fc | "f" as fc | "F" as fc | "e" as fc | "E" as fc | "g" as fc | "G" as fc | "B" as fc | "b" as fc | "ld" as fc | "li" as fc | "lu" as fc | "lx" as fc | "lX" as fc | "lo" as fc | "nd" as fc | "ni" as fc | "nu" as fc | "nx" as fc | "nX" as fc | "no" as fc | "Ld" as fc | "Li" as fc | "Lu" as fc | "Lx" as fc | "LX" as fc | "Lo" as fc | "a" as fc | "t" as fc { FORMAT_CHAR fc } | "!" | "%" { token lexbuf } ocaml-gettext-0.4.2/src/lib/gettext/base/gettextFormat_parser.mly000066400000000000000000000034641367051331200251710ustar00rootroot00000000000000/**************************************************************************/ /* ocaml-gettext: a library to translate messages */ /* */ /* Copyright (C) 2003-2008 Sylvain Le Gall */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version; */ /* with the OCaml static compilation exception. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ /* USA */ /**************************************************************************/ %{ %} %token FORMAT_CHAR %token EOF %type < string list > main %start main %% main: format_char EOF { List.rev $1 } ; format_char: format_char FORMAT_CHAR { $2 :: $1 } | { [] } ; %% ocaml-gettext-0.4.2/src/lib/gettext/base/gettextMo.ml000066400000000000000000000363131367051331200225460ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open GettextUtils (** @author Sylvain Le Gall *) open GettextTypes open GettextMo_int32 let mo_sig_be = int32_of_byte (0x95, 0x04, 0x12, 0xde) let mo_sig_le = int32_of_byte (0xde, 0x12, 0x04, 0x95) let check_mo_header chn hdr = let offset_min = Int32.of_int 28 in let offset_max = Int32.of_int (in_channel_length chn) in let range_offset start_bound = let end_bound = Int32.add start_bound (Int32.mul (Int32.pred hdr.number_of_strings) (Int32.of_int 8)) in ((offset_min, offset_max), (start_bound, end_bound)) in let val_in_range (start_bound, end_bound) value = Int32.compare start_bound value <= 0 && Int32.compare value end_bound <= 0 in (* check_* function return true in case of problem *) let check_overlap start_bound1 start_bound2 = let _, (_, end_bound1) = range_offset start_bound1 in let _, (_, end_bound2) = range_offset start_bound2 in val_in_range (start_bound1, end_bound1) start_bound2 || val_in_range (start_bound1, end_bound1) end_bound2 || val_in_range (start_bound2, end_bound2) start_bound1 || val_in_range (start_bound2, end_bound2) end_bound1 in let check_range_offset start_bound = let file, (start_bound, end_bound) = range_offset start_bound in not (val_in_range file start_bound && val_in_range file end_bound) in if Int32.compare hdr.number_of_strings Int32.zero < 0 then raise MoInvalidHeaderNegativeStrings else if check_range_offset hdr.offset_table_strings then raise (MoInvalidHeaderTableStringOutOfBound ( fst (range_offset hdr.offset_table_strings), snd (range_offset hdr.offset_table_strings) )) else if check_range_offset hdr.offset_table_translation then raise (MoInvalidHeaderTableTranslationOutOfBound ( fst (range_offset hdr.offset_table_translation), snd (range_offset hdr.offset_table_translation) )) else if check_overlap hdr.offset_table_translation hdr.offset_table_strings then raise (MoInvalidHeaderTableTranslationStringOverlap ( snd (range_offset hdr.offset_table_translation), snd (range_offset hdr.offset_table_strings) )) (* We don't care of hashing table, since we don't use it *) else hdr let input_mo_header chn = let endianess = let magic_number = seek_in chn 0; input_int32 chn BigEndian in if magic_number = mo_sig_be then BigEndian else if magic_number = mo_sig_le then LittleEndian else raise MoInvalidFile in let seek_and_input x = seek_in chn x; input_int32 chn endianess in check_mo_header chn { endianess; file_format_revision = seek_and_input 4; number_of_strings = seek_and_input 8; offset_table_strings = seek_and_input 12; offset_table_translation = seek_and_input 16; size_of_hashing_table = seek_and_input 20; offset_of_hashing_table = seek_and_input 24; } let output_mo_header chn hdr = let output = output_int32 chn hdr.endianess in (* magic_number : be is the native way to * specify it, it will be translated through * the output_int32*) output mo_sig_be; output hdr.file_format_revision; output hdr.number_of_strings; output hdr.offset_table_strings; output hdr.offset_table_translation; output hdr.size_of_hashing_table; output hdr.offset_of_hashing_table let string_of_mo_header mo_header = let buff = Buffer.create 256 in Printf.bprintf buff "File format revision : %ld\n" mo_header.file_format_revision; Printf.bprintf buff "Number of string : %ld\n" mo_header.number_of_strings; Printf.bprintf buff "Offset of table with original strings : %lx\n" mo_header.offset_table_strings; Printf.bprintf buff "Offset of table with translation strings : %lx\n" mo_header.offset_table_translation; Printf.bprintf buff "Size of hashing table : %lx\n" mo_header.size_of_hashing_table; Printf.bprintf buff "Offset of hashing table : %lx\n" mo_header.offset_of_hashing_table; Buffer.contents buff let input_mo_untranslated _failsafe chn mo_header number = if number < Int32.to_int mo_header.number_of_strings then let offset_pair = Int32.to_int mo_header.offset_table_strings + (number * 8) in let str = try seek_in chn offset_pair; input_int32_pair_string chn mo_header.endianess with End_of_file -> raise (MoInvalidStringOutOfBound (in_channel_length chn, offset_pair)) in split_plural str else raise (MoInvalidStringOutOfBound (Int32.to_int mo_header.number_of_strings, number)) let input_mo_translated _failsafe chn mo_header number = if number < Int32.to_int mo_header.number_of_strings then let offset_pair = Int32.to_int mo_header.offset_table_translation + (number * 8) in let str = try seek_in chn offset_pair; input_int32_pair_string chn mo_header.endianess with End_of_file -> raise (MoInvalidTranslationOutOfBound (in_channel_length chn, offset_pair)) in split_plural str else raise (MoInvalidStringOutOfBound (Int32.to_int mo_header.number_of_strings, number)) let input_mo_translation failsafe chn mo_header number = let untranslated = input_mo_untranslated failsafe chn mo_header number in let translated = input_mo_translated failsafe chn mo_header number in match untranslated with | [ id ] -> Singular (id, String.concat "\000" translated) | [ id; id_plural ] -> Plural (id, id_plural, translated) | id :: id_plural :: tl -> fail_or_continue failsafe (MoJunk (id, tl)) (Plural (id, id_plural, translated)) | [] -> fail_or_continue failsafe MoEmptyEntry (Singular ("", "")) let get_translated_value failsafe translation plural_number = match (translation, plural_number) with | Singular (_, str), 0 -> str | Singular (_, str), x -> fail_or_continue failsafe (MoInvalidTranslationSingular (str, x)) str | Plural (str, str_plural, []), x -> if x = 0 then str else str_plural | Plural (_, _, lst), x when x < List.length lst -> List.nth lst x | Plural (_, _, lst), x -> fail_or_continue failsafe (MoInvalidTranslationPlural (lst, x)) List.nth lst 0 let germanic_plural (* The germanic default *) n = if n = 1 then 1 else 0 let input_mo_informations failsafe chn mo_header = (* La position de "" est forcment 0 *) let empty_translation = get_translated_value failsafe (input_mo_translation failsafe chn mo_header 0) 0 in let field_value = let lexbuf = Lexing.from_string empty_translation in try GettextMo_parser.main GettextMo_lexer.token_field_name lexbuf with Parsing.Parse_error | Failure _ -> fail_or_continue failsafe (MoInvalidOptions (lexbuf, empty_translation)) [] in let nplurals, fun_plural_forms = try let field_plural_forms = List.assoc "Plural-Forms" field_value in let lexbuf = Lexing.from_string field_plural_forms in try GettextMo_parser.plural_forms GettextMo_lexer.token_field_plural_value lexbuf with Parsing.Parse_error | Failure _ -> fail_or_continue failsafe (MoInvalidPlurals (lexbuf, field_plural_forms)) (2, germanic_plural) with Not_found -> (2, germanic_plural) in let _content_type, content_type_charset = let gettext_content = ("text/plain", GettextConfig.default_codeset) in try let field_content_type = List.assoc "Content-Type" field_value in let lexbuf = Lexing.from_string field_content_type in try GettextMo_parser.content_type GettextMo_lexer.token_field_content_type lexbuf with Parsing.Parse_error | Failure _ -> fail_or_continue failsafe (MoInvalidContentType (lexbuf, field_content_type)) gettext_content with Not_found -> gettext_content in let extract_field_string name = try Some (List.assoc name field_value) with Not_found -> None in { project_id_version = extract_field_string "Project-Id-Version"; report_msgid_bugs_to = extract_field_string "Report-Msgid-Bugs-To"; pot_creation_date = extract_field_string "POT-Creation-Date"; po_revision_date = extract_field_string "PO-Revision-Date"; last_translator = extract_field_string "Last-Translator"; language_tream = extract_field_string "Language-Team"; mime_version = extract_field_string "MIME-Version"; content_type = extract_field_string "Content-Type"; content_transfer_encoding = extract_field_string "Content-Transfer-Encoding"; plural_forms = extract_field_string "Plural-Forms"; content_type_charset; nplurals; fun_plural_forms; } let string_of_mo_informations ?(compute_plurals = (0, 3)) mo_translation = let buff = Buffer.create 1024 in let p = Printf.bprintf in let extract_string x = match x with Some s -> s | None -> "" in p buff "Project-Id-Version : %s\n" (extract_string mo_translation.project_id_version); p buff "Report-Msgid-Bugs-To : %s\n" (extract_string mo_translation.report_msgid_bugs_to); p buff "POT-Creation-Date : %s\n" (extract_string mo_translation.pot_creation_date); p buff "PO-Revision-Date : %s\n" (extract_string mo_translation.po_revision_date); p buff "Last-Translator : %s\n" (extract_string mo_translation.last_translator); p buff "Language-Team : %s\n" (extract_string mo_translation.language_tream); p buff "MIME-Version : %s\n" (extract_string mo_translation.mime_version); p buff "Content-Type : %s\n" (extract_string mo_translation.content_type); p buff "Plurals-Forms : %s\n" (extract_string mo_translation.plural_forms); p buff "Content-Transfer-Encoding : %s\n" (extract_string mo_translation.content_transfer_encoding); p buff "Content-Type-Charset : %s\n" mo_translation.content_type_charset; p buff "NPlurals : %d\n" mo_translation.nplurals; p buff "Fun plural : "; (let a, b = compute_plurals in for i = a to b do p buff "%d -> %d ; " i (mo_translation.fun_plural_forms i) done); p buff "\n"; Buffer.contents buff let output_mo ?(endianess = LittleEndian) chn lst = (* There could have potential issue with alignment, but it seems to be fixed * at 1 in gettext-0.14.1/gettext-tools/configure.ac, so there is no probleme * *) let null_terminated lst = List.map (fun str -> str ^ "\000") lst in let compute_table start_pos lst = let compute_length lst = List.map String.length lst in let compute_offset (current_pos, lst_pos) length = (* Remove 1 since we have NULL terminated strings *) (current_pos + length, (length - 1, current_pos) :: lst_pos) in let final_pos, lst_rev = List.fold_left compute_offset (start_pos, []) (compute_length lst) in (final_pos, List.rev lst_rev) in let no_empty_lst = (* Avoid using empty translated string *) List.filter (function | Singular (_, "") -> false | Plural (_, _, lst) when String.concat "" lst = "" -> false | _ -> true) lst in let sorted_lst = let compare_entry entry1 entry2 = let value_of_entry entry = match entry with Singular (id, _) -> id | Plural (id, _, _) -> id in String.compare (value_of_entry entry1) (value_of_entry entry2) in List.sort compare_entry no_empty_lst in let untranslated = let to_string entry = match entry with | Singular (id, _) -> id | Plural (id, id_plural, _) -> id ^ "\000" ^ id_plural in null_terminated (List.map to_string sorted_lst) in let translated = let to_string entry = match entry with | Singular (_, str) -> str | Plural (_, _, lst) -> String.concat "\000" lst in null_terminated (List.map to_string sorted_lst) in let gN = List.length sorted_lst in let gO = 28 (* Size of the header *) in let gT = gO + (8 * gN) in let gS = 0 (* Hashtable is not implemented, since algorithm is not public -- documented *) in let gH = gT + (8 * gN) in let final_untranslated, untranslated_table = compute_table (gH + (gS * 4)) untranslated in let _, translated_table = compute_table final_untranslated translated in let header = { endianess; file_format_revision = Int32.zero; number_of_strings = Int32.of_int gN; offset_table_strings = Int32.of_int gO; offset_table_translation = Int32.of_int gT; size_of_hashing_table = Int32.of_int gS; offset_of_hashing_table = Int32.of_int gH; } in output_mo_header chn header; List.iter (List.iter (fun (a, b) -> output_int32_pair chn endianess (Int32.of_int a, Int32.of_int b))) [ untranslated_table; translated_table ]; List.iter (output_string chn) untranslated; List.iter (output_string chn) translated let fold_mo failsafe f init fl_mo = let chn = open_in_bin fl_mo in let res = try (* Processing of the file *) let mo_header = input_mo_header chn in let informations = input_mo_informations failsafe chn mo_header in let fun_plural_forms = informations.GettextTypes.fun_plural_forms in let rec fold_mo_aux accu i = if i < Int32.to_int mo_header.number_of_strings then let new_translation = input_mo_translation failsafe chn mo_header i in let new_accu = f new_translation accu in fold_mo_aux new_accu (i + 1) else accu in let translations = fold_mo_aux init 0 in (translations, fun_plural_forms) with Sys_error _ -> fail_or_continue failsafe (MoCannotOpenFile fl_mo) (init, germanic_plural) in close_in chn; res ocaml-gettext-0.4.2/src/lib/gettext/base/gettextMo_int32.ml000066400000000000000000000063761367051331200235730ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** @author Sylvain Le Gall *) open GettextTypes let int32_of_byte (a0, a1, a2, a3) = Int32.add (Int32.shift_left (Int32.of_int a0) 24) (Int32.of_int ((a1 lsl 16) + (a2 lsl 8) + a3)) let byte_of_int32 i = let one_byte = Int32.of_int 0xFF in let extract_byte sb = let mask = Int32.shift_left one_byte (sb * 8) in let i_masked = Int32.logand i mask in Int32.to_int (Int32.shift_right i_masked (sb * 8)) in (extract_byte 3, extract_byte 2, extract_byte 1, extract_byte 0) let input_int32 chn endian = let a0, a1, a2, a3 = (input_byte chn, input_byte chn, input_byte chn, input_byte chn) in match endian with | BigEndian -> int32_of_byte (a0, a1, a2, a3) | LittleEndian -> int32_of_byte (a3, a2, a1, a0) let output_int32 chn endian vl = let a0, a1, a2, a3 = byte_of_int32 vl in let order = match endian with | BigEndian -> [ a0; a1; a2; a3 ] | LittleEndian -> [ a3; a2; a1; a0 ] in List.iter (output_byte chn) order let input_int32_pair chn endian = let a = input_int32 chn endian in let b = input_int32 chn endian in (a, b) let output_int32_pair chn endian (a, b) = output_int32 chn endian a; output_int32 chn endian b let input_int32_pair_string chn endian = let length, offset = input_int32_pair chn endian in let ilength, ioffset = (Int32.to_int length, Int32.to_int offset) in if 0 <= ioffset + ilength && ioffset + ilength < in_channel_length chn then ( let str = Bytes.make ilength 'X' in seek_in chn ioffset; really_input chn str 0 ilength; Bytes.to_string str ) else (* We use this exception, because that what should happen if we try to read the string *) raise End_of_file ocaml-gettext-0.4.2/src/lib/gettext/base/gettextMo_lexer.mll000066400000000000000000000070111367051331200241120ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) { open GettextMo_parser;; } rule token_field_name = parse "Content-Type" [' ''\t']* ':' { CONTENT_TYPE(token_field_value lexbuf) } | "Plural-Forms" [' ''\t']* ':' { PLURAL_FORMS(token_field_value lexbuf) } | ([^'\n''\r''\t'' ']+ as id) [' ''\t']* ':' { FIELD_NAME(id, token_field_value lexbuf) } | eof { EOF } | _ { token_field_name lexbuf} and token_field_value = parse [^'\n''\r']* as str { str } and token_field_plural_value = parse "nplurals" { NPLURALS } | ';' { SEMICOLON } | "plural" { PLURAL } | "?" { QUESTION_MARK } | ":" { COLON } | "||" { OR } | "&&" { AND } | "==" { EQ } | '=' { EQUAL } | "!=" { NEQ } | "<=" { LE } | "<" { L } | ">=" { GE } | ">" { G } | "+" { PLUS } | "-" { MINUS } | "*" { MUL } | "/" { DIV } | "%" { MOD } | "!" { NOT } | '(' { LPAREN } | ')' { RPAREN } | "n" { ID } | ['0'-'9']+ as nbr { (NUMBER (int_of_string nbr) ) } | eof { EOF } | [' ''\t'] { token_field_plural_value lexbuf } and token_field_content_type = parse "charset" { CHARSET } | ';' { SEMICOLON } | '=' { EQUAL } | [^' ''\t'';''=']+ as str { (STRING str) } | [' ''\t'] { token_field_content_type lexbuf } | eof { EOF } ocaml-gettext-0.4.2/src/lib/gettext/base/gettextMo_parser.mly000066400000000000000000000102011367051331200242770ustar00rootroot00000000000000/**************************************************************************/ /* ocaml-gettext: a library to translate messages */ /* */ /* Copyright (C) 2003-2008 Sylvain Le Gall */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version; */ /* with the OCaml static compilation exception. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ /* USA */ /**************************************************************************/ %{ %} %token EOF %token NPLURALS %token SEMICOLON %token PLURAL %token EQUAL %token CHARSET %token QUESTION_MARK %token COLON %token OR %token AND %token EQ %token NEQ %token LE %token L %token GE %token G %token PLUS %token MINUS %token MUL %token DIV %token MOD %token NOT %token ID %token RPAREN %token LPAREN %token FIELD_NAME %token CONTENT_TYPE %token PLURAL_FORMS %token NUMBER %token STRING %right QUESTION_MARK %left OR %left AND %left EQ NEQ %left G L GE LE %left PLUS MINUS %left MUL DIV MOD %right NOT %type < (string * string) list > main %start main %type < int * ( int -> int ) > plural_forms %start plural_forms %type < string * string > content_type %start content_type %% main: lines EOF { $1 } ; lines: lines line { $2 :: $1 } | line { [$1] } ; line: FIELD_NAME { let (a,b) = $1 in (a, b) } | CONTENT_TYPE { ("Content-Type", $1) } | PLURAL_FORMS { ("Plural-Forms", $1) } ; plural_forms: NPLURALS EQUAL NUMBER SEMICOLON PLURAL EQUAL expr { ($3,$7) } | NPLURALS EQUAL NUMBER SEMICOLON PLURAL EQUAL expr SEMICOLON { ($3,$7) } ; content_type: STRING SEMICOLON CHARSET EQUAL STRING { ($1,String.uppercase_ascii $5) } ; expr: ID { fun x -> x } | NUMBER { fun _x -> $1 } | expr QUESTION_MARK expr COLON expr { fun x -> if ($1 x) != 0 then ($3 x) else ($5 x) } | expr OR expr { fun x -> if ($1 x) != 0 then 1 else ($3 x) } | expr AND expr { fun x -> if ($1 x) != 0 then 0 else ($3 x) } | expr EQ expr { fun x -> if ($1 x) = ($3 x) then 1 else 0 } | expr NEQ expr { fun x -> if ($1 x) != ($3 x) then 1 else 0 } | expr LE expr { fun x -> if ($1 x) <= ($3 x) then 1 else 0 } | expr L expr { fun x -> if ($1 x) < ($3 x) then 1 else 0 } | expr GE expr { fun x -> if ($1 x) >= ($3 x) then 1 else 0 } | expr G expr { fun x -> if ($1 x) > ($3 x) then 1 else 0 } | expr PLUS expr { fun x -> ($1 x) + ($3 x) } | expr MINUS expr { fun x -> ($1 x) - ($3 x) } | expr MUL expr { fun x -> ($1 x) * ($3 x) } | expr DIV expr { fun x -> ($1 x) / ($3 x) } | expr MOD expr { fun x -> ($1 x) mod ($3 x) } | NOT expr { fun x -> if ($2 x) = 0 then 1 else 0 } | LPAREN expr RPAREN { fun x -> $2 x} ; %% ocaml-gettext-0.4.2/src/lib/gettext/base/gettextModules.ml000066400000000000000000000067761367051331200236150ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** @author Sylvain Le Gall *) open GettextTypes open GettextCategory (** Function for manipulation the type t *) let upgrade_textdomain t k value = let current_codeset, current_dir = try MapTextdomain.find k t.textdomains with Not_found -> (None, None) in let new_value = match value with | None, None -> (current_codeset, current_dir) | None, new_dir -> (current_codeset, new_dir) | new_codeset, None -> (new_codeset, current_dir) | new_codeset, new_dir -> (new_codeset, new_dir) in { t with textdomains = MapTextdomain.add k new_value t.textdomains } let create ?(failsafe = Ignore) ?(categories = []) ?(codesets = []) ?(dirs = []) ?(textdomains = []) ?(codeset = GettextConfig.default_codeset) ?(path = GettextConfig.default_path) ?language textdomain = let map_categories = List.fold_left (fun map (category, locale) -> MapCategory.add category locale map) MapCategory.empty categories in let result = { failsafe; textdomains = MapTextdomain.empty; categories = map_categories; language; codeset; path; default = textdomain; } in (* Apply any upgrade required by the different settings provided *) let apply_upgrade t lst = List.fold_left (fun t (textdomain, changes) -> upgrade_textdomain t textdomain changes) t lst in (* All changes from the setting of textdomains *) let textdomains_changes = List.map (fun textdomain -> (textdomain, (None, None))) (textdomain :: textdomains) in (* All changes from the setting of codesets *) let codesets_changes = List.map (fun (textdomain, codeset) -> (textdomain, (Some codeset, None))) codesets in (* All changes from the setting of dirs *) let dirs_changes = List.map (fun (textdomain, dir) -> (textdomain, (None, Some dir))) dirs in apply_upgrade result (textdomains_changes @ codesets_changes @ dirs_changes) ocaml-gettext-0.4.2/src/lib/gettext/base/gettextTypes.ml000066400000000000000000000276321367051331200233030ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Types and exception of ocaml-gettext. @author Sylvain Le Gall *) open GettextCategory (** {1 Core types of ocaml-gettext library} *) type range = Int32.t * Int32.t type textdomain = string type locale = string type dir = string type filename = string type codeset = string (** {1 Exceptions} *) exception CompileProblemReadingFile of filename * string (** Filename wich generates the error message str *) exception CompileExtractionFailed of filename * string * int (** While extracting filename the command str returns exit code i. *) exception CompileExtractionInterrupted of filename * string * int (** While extracting filename the command receive signal i. *) exception DomainFileDoesntExist of filename list (** Cannot the filename corresponding to a textdomain among the specified files. *) exception FormatInconsistent of string * string (** The two strings returned doesn't have the same meaning regarding [Printf] syntax. *) exception GettextUninitialized (** A part of the code try to translate a string, but ocaml-gettext is not initialized. *) exception MoInvalidOptions of Lexing.lexbuf * string (** There is an invalid field in the content information of a MO file. *) exception MoInvalidPlurals of Lexing.lexbuf * string (** The plural-form field is not correct. *) exception MoInvalidContentType of Lexing.lexbuf * string (** The content-type field is not correct. *) exception MoInvalidTranslationSingular of string * int (** A plural translation of a singular string has occured. *) exception MoInvalidTranslationPlural of string list * int (** An out-of-bound plural translation has occured. *) exception MoJunk of string * string list (** There is more plural translation than the number of plural forms. *) exception MoEmptyEntry (** *) exception MoInvalidFile (** A MO corrupted file has been read. *) exception MoInvalidHeaderNegativeStrings (** The MO file specified a negative number of strings. *) exception MoInvalidHeaderTableStringOutOfBound of range * range (** Offset of the string table is out of bound. *) exception MoInvalidHeaderTableTranslationOutOfBound of range * range (** Offset of the translation table is out of bound. *) exception MoInvalidHeaderTableTranslationStringOverlap of range * range (** String and translation table overlap. *) exception MoInvalidStringOutOfBound of int * int (** The offset and length of a string entry leads to an access beyond the end of the MO file. *) exception MoInvalidTranslationOutOfBound of int * int (** The offset and length of a translation entry leads to an access beyond the end of the MO file. *) exception MoCannotOpenFile of string (** An error occured when trying to open a MO file. *) exception PoInvalidFile of string * Lexing.lexbuf * in_channel (** A PO file cannot be parsed. *) exception PoFileInvalidIndex of string * int (** When parsing a PO file, found an out of order table indices in a plural form. *) exception PoFileDoesntExist of string (** The PO file doesn't exist. *) exception PoInconsistentMerge of string * string (** Cannot merge two PO files. *) exception TranslateStringNotFound of string (** A string to translate cannot be found. *) exception LocalePosixUnparseable of string (** Cannot parse the POSIX representation of the locale. *) (** {1 Modules signatures} *) type dependencies = (textdomain * codeset option * dir option) list module type INIT_TYPE = sig val textdomain : textdomain val codeset : codeset option val dir : dir option val dependencies : dependencies end (* We stop documentation here, for the gettext API reference, all those types are internals : use at your own risk. *) (**/**) (** {1 Extended core types} *) module MapString = Map.Make (String) module SetString = Set.Make (String) module MapTextdomain = Map.Make (struct type t = textdomain let compare = String.compare end) (** Defines behavior regarding exception in the ocaml-gettext library *) type failsafe = Ignore | InformStderr of (exn -> string) | RaiseException type t = { failsafe : failsafe; textdomains : (codeset option * dir option) MapTextdomain.t; categories : locale MapCategory.t; language : locale option; codeset : codeset; path : dir list; default : textdomain; } (** Data structure handling initialization variable of ocaml-gettext *) type t' = bool -> textdomain option -> string -> (string * int) option -> category -> string (** Function to translate effectively a string *) (** {1 Types for MO file processing} *) (** Endianess of a MO file *) type endianess = BigEndian | LittleEndian type mo_header = { endianess : endianess; file_format_revision : int32; number_of_strings : int32; offset_table_strings : int32; offset_table_translation : int32; size_of_hashing_table : int32; offset_of_hashing_table : int32; } (** Specification of .MO file @see GNU Gettext documentation. Format of MO file : byte +------------------------------------------+ 0 | magic number = 0x950412de | | | 4 | file format revision = 0 | | | 8 | number of strings | == N | | 12 | offset of table with original strings | == O | | 16 | offset of table with translation strings | == T | | 20 | size of hashing table | == S | | 24 | offset of hashing table | == H | | . . . (possibly more entries later) . . . | | O | length & offset 0th string ----------------. O + 8 | length & offset 1st string ------------------. ... ... | | O + ((N-1)*8)| length & offset (N-1)th string | | | | | | | T | length & offset 0th translation ---------------. T + 8 | length & offset 1st translation -----------------. ... ... | | | | T + ((N-1)*8)| length & offset (N-1)th translation | | | | | | | | | | | H | start hash table | | | | | ... ... | | | | H + S * 4 | end hash table | | | | | | | | | | | | NUL terminated 0th string <----------------' | | | | | | | | | NUL terminated 1st string <------------------' | | | | | | ... ... | | | | | | | NUL terminated 0th translation <---------------' | | | | | NUL terminated 1st translation <-----------------' | | ... ... | | +------------------------------------------+ *) type mo_translation = { project_id_version : string option; report_msgid_bugs_to : string option; pot_creation_date : string option; po_revision_date : string option; last_translator : string option; language_tream : string option; mime_version : string option; content_type : string option; content_transfer_encoding : string option; plural_forms : string option; (* The only interesting fields *) (* Those field are precomputed for regular use *) content_type_charset : string; nplurals : int; fun_plural_forms : int -> int; } (** Details associated with "" Project-Id-Version: PACKAGE VERSION\n Report-Msgid-Bugs-To: \n POT-Creation-Date: 2004-05-31 16:53+0200\n PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n Last-Translator: FULL NAME \n Language-Team: LANGUAGE \n MIME-Version: 1.0\n Content-Type: text/plain; charset=CHARSET\n Content-Transfer-Encoding: 8bit\n Plural-Forms: specific ( 0 is false and 1 is true *) (** Base type of MO content : translation of string. The first string members are the string identifier ( singular form ). *) type translation = | Singular of string * string | Plural of string * string * string list (** Types for the PO processing. The main difference with the type translation comes from the necessity of keeping a maximum of comment. *) type po_translation = | PoSingular of string list * string list | PoPlural of string list * string list * string list list type po_filepos = filename * int (** PO string localizator : represents in which file/lineno a string can be found. *) type po_special = string (** PO keyword: represents special keyword like fuzzy, wrap, c-format... *) type po_commented_translation = { po_comment_special : po_special list; po_comment_filepos : po_filepos list; po_comment_translation : po_translation; } type po_translations = po_commented_translation MapString.t (** Mapping of PO content using the string identifier as the key. *) type po_content = { no_domain : po_translations; domain : po_translations MapTextdomain.t; } (** Content of a PO file. Since comments should be saved, and that we only save comments before and in message translation, we need to keep trace of the last comments, which is not attached to any translation. *) (** {1 Modules signatures} *) (** Signature for module handling transformation of initialization parameters to concrete translation function. *) module type REALIZE_TYPE = sig val realize : t -> t' end ocaml-gettext-0.4.2/src/lib/gettext/base/gettextUtils.ml000066400000000000000000000045701367051331200232730ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Misc. utilities. @author Sylvain Le Gall *) open GettextTypes let string_of_list lst = "[ " ^ String.concat "; " (List.map (fun str -> Printf.sprintf "%S" str) lst) ^ " ]" let split_plural str = let rec split_plural_one start = let next_sep = try String.index_from str start '\000' with Not_found -> String.length str in let new_plural = String.sub str start (next_sep - start) in if next_sep + 1 >= String.length str then [ new_plural ] else new_plural :: split_plural_one (next_sep + 1) in split_plural_one 0 let fail_or_continue failsafe exc cont_value = match failsafe with | Ignore -> cont_value | InformStderr exc_printer -> prerr_string (exc_printer exc); prerr_newline (); cont_value | RaiseException -> raise exc ocaml-gettext-0.4.2/src/lib/gettext/dune000066400000000000000000000001021367051331200201630ustar00rootroot00000000000000(library (name gettext) (wrapped false) (public_name gettext)) ocaml-gettext-0.4.2/src/lib/gettext/extension/000077500000000000000000000000001367051331200213305ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/lib/gettext/extension/dune000066400000000000000000000007471367051331200222160ustar00rootroot00000000000000(ocamllex (modules gettextLocale_lexer gettextPoComment_lexer gettextPo_lexer)) (ocamlyacc (modules gettextLocale_parser gettextPoComment_parser gettextPo_parser)) (library (name gettextExtension) (public_name gettext.extension) (private_modules GettextDomain GettextLocale_lexer GettextLocale_parser GettextLocale_types GettextPoComment_lexer GettextPoComment_parser GettextPo_lexer GettextPo_parser GettextPo_utils) (wrapped false) (libraries gettext.base)) ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextCharset.ml000066400000000000000000000042361367051331200246650ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Signature of module for charset conversion @author Sylvain Le Gall *) open GettextTypes module type CHARSET_TYPE = sig type encoding = string type u val create : t -> encoding -> encoding -> u (** create in_enc out_enc : create a new charset converter from charset in_enc to out_enc. *) val recode : u -> string -> string (** recode str enc : return a transcoded string according to enc. *) end module Dummy : CHARSET_TYPE = struct type encoding = string type u = unit let create _t _in_enc _out_enc = () let recode () str = str end ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextCompile.ml000066400000000000000000000172651367051331200246720ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Functions for extraction/compilation/installation of PO/MO file. @author Sylvain Le Gall *) open GettextTypes open FileUtil open FilePath let po_of_filename filename = let chn = try open_in filename with Sys_error str -> raise (CompileProblemReadingFile (filename, str)) in let po = GettextPo.input_po chn in close_in chn; po (** extract cmd default_option file_options src_files ppf : extract the translatable strings from all the src_files provided. Each source file will be extracted using the command cmd, which should be an executable that has the same output as ocaml-xgettext. If cmd is not provided, it will be searched in the current path. The command will be called with default_option, or if the file being extracted is mapped in file_options, with the option associated to the filename in file_options. The result will be written using module Format to the formatter ppf. The result of the extraction should be used as a po template file. *) let extract command default_options filename_options filename_lst filename_pot = let make_command options filename = Printf.sprintf "%s %s %s" command options filename in let extract_one po filename = let options = try MapString.find filename filename_options with Not_found -> default_options in let real_command = make_command options filename in let chn = Unix.open_process_in real_command in let value = set_binary_mode_in chn true; (Marshal.from_channel chn : po_content) in match Unix.close_process_in chn with | Unix.WEXITED 0 -> GettextPo.merge_po po value | Unix.WEXITED exit_code -> raise (CompileExtractionFailed (filename, real_command, exit_code)) | Unix.WSIGNALED signal | Unix.WSTOPPED signal -> raise (CompileExtractionInterrupted (filename, real_command, signal)) in let extraction = List.fold_left extract_one GettextPo.empty_po filename_lst in let chn = open_out filename_pot in let date = let current_time = Unix.time () in let gmt_time = Unix.gmtime current_time in Printf.sprintf "%04d-%02d-%02d %02d:%02d+0000" (gmt_time.Unix.tm_year + 1900) (gmt_time.Unix.tm_mon + 1) gmt_time.Unix.tm_mday gmt_time.Unix.tm_hour gmt_time.Unix.tm_min in Printf.fprintf chn "# SOME DESCRIPTIVE TITLE.\n\ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n\ # This file is distributed under the same license as the PACKAGE package.\n\ # FIRST AUTHOR , YEAR.\n\ #\n\ #, fuzzy\n\ msgid \"\"\n\ msgstr \"\"\n\ \"Project-Id-Version: PACKAGE VERSION\\n\"\n\ \"Report-Msgid-Bugs-To: \\n\"\n\ \"POT-Creation-Date: %s\\n\"\n\ \"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\ \"Last-Translator: FULL NAME \\n\"\n\ \"Language-Team: LANGUAGE \\n\"\n\ \"MIME-Version: 1.0\\n\"\n\ \"Content-Type: text/plain; charset=CHARSET\\n\"\n\ \"Content-Transfer-Encoding: 8bit\\n\"\n\ \"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n\n" date; GettextPo.output_po chn extraction; close_out chn (** compile input_po output_mo : create a binary representation of the PO file provided as input_pot. The output file is output_mo. *) let compile filename_po filename_mo = let po = po_of_filename filename_po in let output_one_map filename map = let lst = MapString.fold (fun _ commented_po_translation lst -> let po_translation = commented_po_translation.po_comment_translation in GettextPo.translation_of_po_translation po_translation :: lst) map [] in let chn = open_out_bin filename in GettextMo.output_mo chn lst; close_out chn in let make_filename domain filename_mo = let dirname = dirname filename_mo in let basename = basename filename_mo in (* BUG : should use add_extension *) make_filename [ dirname; domain ^ "." ^ basename ] in output_one_map filename_mo po.no_domain; MapTextdomain.iter (fun domain map -> output_one_map (make_filename domain filename_mo) map) po.domain (** install destdir language category textdomain fln : copy the given filename ( should be a MO file ) to the filename defined by all the other parameters ( typically destdir/language/category/textdomain.mo ). *) let install strict destdir language category textdomain filename_mo_src = let filename_mo_dst = GettextDomain.make_filename destdir language category textdomain in let dirname_mo_dst = dirname filename_mo_dst in (* Test of the mo file, it will raise an exception if there is any problem in the MO structure *) let (), _ = GettextMo.fold_mo ( if strict then RaiseException else InformStderr (function | MoInvalidPlurals _ as e -> Gettext.string_of_exception e | e -> raise e) ) (fun _x () -> ()) () filename_mo_src in mkdir ~parent:true dirname_mo_dst; cp [ filename_mo_src ] filename_mo_dst (** uninstall orgdir language category textdomain : remove the MO file defined by all the other parameters ( typically destdir/language/category/textdomain.mo ). *) let uninstall orgdir language category textdomain = let filename_mo_org = GettextDomain.make_filename orgdir language category textdomain in rm [ filename_mo_org ] (** merge fln_pot fln_po_lst backup_ext : use fln_pot as a POT file and merge the current content of the listed PO file ( fln_po_lst ) with it. Backup all the PO file using the provided backup extension backup_ext and produce a merged PO file in place. *) let merge filename_pot filename_po_lst backup_extension = let pot = po_of_filename filename_pot in let merge_one filename_po = let po = po_of_filename filename_po in let po_merged = GettextPo.merge_pot pot po in let _ = (* BUG: should use add_extension *) (* BUG: should use mv *) Sys.rename filename_po (filename_po ^ "." ^ backup_extension) in let chn = open_out filename_po in GettextPo.output_po chn po_merged; close_out chn in List.iter merge_one filename_po_lst ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextDomain.ml000066400000000000000000000073311367051331200245020ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Signature of module for domain management. @author Sylvain Le Gall *) open FilePath open FileUtil open GettextTypes open GettextCategory (* BUG : a mettre jour *) (** compute_path textdomain category t : return the path to the mo file corresponding to textdomain and category. Language is guessed from category binding. If the textdomain is not found, it tries to use the build default to find the file. The file returned exists and is readable. If such a file doesn't exists an exception DomainFileDoesntExist is thrown. If the function is unable to guess the current language an exception DomainLanguageNotSet is thrown. *) let make_filename dir language category textdomain = (* http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC148 dir_name/locale/LC_category/domain_name.mo *) make_filename [ (* BUG : should use add_extension *) dir; language; string_of_category category; textdomain ^ ".mo"; ] let find t languages category textdomain = let search_path = ( try match MapTextdomain.find textdomain t.textdomains with | _, Some dir -> [ dir ] | _, None -> [] with Not_found -> [] ) @ t.path in let ctest = test (And (Exists, Is_readable)) in let rec find_mo_file_aux dir languages = match languages with | language :: tl -> let current_filename = make_filename dir language category textdomain in if ctest current_filename then current_filename else find_mo_file_aux dir tl | [] -> raise Not_found in let rec find_mo_file path languages = match path with | dir :: tl -> ( try find_mo_file_aux dir languages with Not_found -> find_mo_file tl languages ) | [] -> raise Not_found in try find_mo_file search_path languages with Not_found -> raise (DomainFileDoesntExist (List.flatten (List.map (fun dir -> List.map (fun language -> make_filename dir language category textdomain) languages) search_path))) ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextLocale.ml000066400000000000000000000121361367051331200244710ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Implements different operation over locale/category. @author Sylvain Le Gall *) open GettextTypes open GettextCategory open GettextUtils module type LOCALE_TYPE = sig val get_locale : t -> category -> locale list * codeset (** get_locale t cat : Return the value of locale and encoding for cat. The value returned is in ASCII. Priority should be given to the values language/codeset provided in variable t. *) end (** Return the best value of environnement variable, that can be found according to the priority defined in gettext. The choice take into account t and category, but may ignore it, if a variable with a best priority is set. This function can be used to get a value for a LOCALE_TYPE implementation. Raise Not_found if nothing appropriate. *) let posix_getenv t category = (* http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC155 In the function dcgettext at every call the current setting of the highest priority environment variable is determined and used. Highest priority means here the following list with decreasing priority: 1. LANGUAGE 2. LC_ALL 3. LC_xxx, according to selected locale 4. LANG *) match t.language with | Some str -> str | None -> ( try let best_env = List.find (fun s -> try ignore (Sys.getenv s); true with Not_found -> false) [ "LANGUAGE"; string_of_category LC_ALL; string_of_category category; "LANG"; ] in Sys.getenv best_env with Not_found -> "C" ) module Posix : LOCALE_TYPE = struct (* Extract from "man setlocale" A locale name is typically of the form language[_territory][.codeset][@modi- fier], where language is an ISO 639 language code, territory is an ISO 3166 country code, and codeset is a character set or encoding identifier like ISO-8859-1 or UTF-8. For a list of all supported locales, try "locale -a", cf. locale(1). *) let get_locale t category = let posix_lang = posix_getenv t category in let locale = try let lexbuf = Lexing.from_string posix_lang in GettextLocale_parser.main GettextLocale_lexer.token lexbuf with x -> fail_or_continue t.failsafe (LocalePosixUnparseable (posix_lang ^ " " ^ Printexc.to_string x)) (GettextLocale_types.create_locale posix_lang) in let locales = match ( locale.GettextLocale_types.territory, locale.GettextLocale_types.modifier ) with | Some territory, Some modifier -> [ locale.GettextLocale_types.language ^ "_" ^ territory ^ "@" ^ modifier; locale.GettextLocale_types.language ^ "_" ^ territory; locale.GettextLocale_types.language; ] | None, Some modifier -> [ locale.GettextLocale_types.language ^ "@" ^ modifier; locale.GettextLocale_types.language; ] | Some territory, None -> [ locale.GettextLocale_types.language ^ "_" ^ territory; locale.GettextLocale_types.language; ] | None, None -> [ locale.GettextLocale_types.language ] in let codeset = match locale.GettextLocale_types.codeset with | Some codeset -> codeset | None -> t.codeset in (locales, codeset) end ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextLocale_lexer.mll000066400000000000000000000034601367051331200260440ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) { open GettextLocale_parser;; } rule token = parse '_' { UNDERSCORE } | '.' { DOT } | '@' { AT } | eof { EOF } | [^'_''.''@']* as id { ID(id) } ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextLocale_parser.mly000066400000000000000000000042041367051331200262330ustar00rootroot00000000000000/**************************************************************************/ /* ocaml-gettext: a library to translate messages */ /* */ /* Copyright (C) 2003-2008 Sylvain Le Gall */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version; */ /* with the OCaml static compilation exception. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ /* USA */ /**************************************************************************/ %{ open GettextLocale_types;; %} %token UNDERSCORE %token DOT %token AT %token EOF %token ID %start main %type main %% main: locale EOF { (*print_endline "eof";*) $1 } ; locale: | locale UNDERSCORE ID { (*print_endline "underscore";*) { $1 with territory = Some $3 } } | locale DOT ID { (*print_endline "dot";*) { $1 with codeset = Some $3 } } | locale AT ID { (*print_endline "at";*) { $1 with modifier = Some $3 } } | ID { (*print_endline "id";*) create_locale $1 } ; ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextLocale_types.ml000066400000000000000000000035231367051331200257150ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** @author Sylvain Le Gall *) type locale = { language : string; territory : string option; codeset : string option; modifier : string option; } let create_locale language = { language; territory = None; codeset = None; modifier = None } ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextPo.ml000066400000000000000000000251401367051331200236470ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** @author Sylvain Le Gall *) open GettextTypes (** empty_po : value representing an empty PO *) let empty_po = GettextPo_utils.empty_po (** add_po_translation_no_domain po (comment_lst,location_lst,translation) : add a translation to a corpus of already defined translation with no domain defined. If the translation already exist, they are merged concerning location, and follow these rules for the translation itself : - singular and singular : if there is an empty string ( "" ) in one of the translation, use the other translation, - plural and plural : if there is an empty string list ( [ "" ; "" ] ) in one of the translaiton, use the other translation, - singular and plural : merge into a plural form. There is checks during the merge that can raise PoInconsistentMerge : - for one singular string if the two plural strings differs - if there is some elements that differs (considering the special case of the empty string ) in the translation *) let add_po_translation_no_domain po po_translation = try GettextPo_utils.add_po_translation_no_domain po po_translation with PoInconsistentMerge (str1, str2) -> raise (PoInconsistentMerge (str1, str2)) (** add_po_translation_domain po domain (comment_lst,location_lst,translation): add a translation to the already defined translation with the domain defined. See add_translation_no_domain for details. *) let add_po_translation_domain po domain po_translation = try GettextPo_utils.add_po_translation_domain po domain po_translation with PoInconsistentMerge (str1, str2) -> raise (PoInconsistentMerge (str1, str2)) (** merge_po po1 po2 : merge two PO. The rule for merging are the same as defined in add_po_translation_no_domain. Can raise PoInconsistentMerge *) let merge_po po1 po2 = (* We take po2 as the initial set, we merge po1 into po2 beginning with po1.no_domain and then po1.domain *) let merge_no_domain = MapString.fold (fun _ translation po -> add_po_translation_no_domain po translation) po1.no_domain po2 in let merge_one_domain domain map_domain po = MapString.fold (fun _ translation po -> add_po_translation_domain domain po translation) map_domain po in MapTextdomain.fold merge_one_domain po1.domain merge_no_domain (** merge_pot po pot : merge a PO with a POT. Only consider strings that exists in the pot. Always use location as defined in the POT. If a string is not found, use the translation provided in the POT. If a plural is found and a singular should be used, downgrade the plural to singular. If a singular is found and a plural should be used, upgrade singular to plural, using the strings provided in the POT for ending the translation. *) let merge_pot pot po = let order_po_map ?domain () = match domain with | None -> po.no_domain :: MapTextdomain.fold (fun _ x lst -> x :: lst) po.domain [] | Some domain -> ( let tl = po.no_domain :: MapTextdomain.fold (fun key x lst -> if key = domain then lst else x :: lst) po.domain [] in try MapTextdomain.find domain po.domain :: tl with Not_found -> tl ) in let merge_translation map_lst key commented_translation_pot = let translation_pot = commented_translation_pot.po_comment_translation in let translation_merged = try let commented_translation_po = let map_po = List.find (MapString.mem key) map_lst in MapString.find key map_po in let translation_po = commented_translation_po.po_comment_translation in (* Implementation of the rule given above *) match (translation_pot, translation_po) with | PoSingular (str_id, _), PoPlural (_, _, str :: _) -> PoSingular (str_id, str) | PoPlural (str_id, str_plural, _ :: tl), PoSingular (_, str) -> PoPlural (str_id, str_plural, str :: tl) | PoPlural (str_id, str_plural, []), PoSingular (_, str) -> PoPlural (str_id, str_plural, [ str ]) | _, translation -> translation with Not_found -> (* Fallback to the translation provided in the POT *) translation_pot in { commented_translation_pot with po_comment_translation = translation_merged; } in (* We begin with an empty po, and merge everything according to the rule above. *) let merge_no_domain = MapString.fold (fun key pot_translation po -> add_po_translation_no_domain po (merge_translation (order_po_map ()) key pot_translation)) pot.no_domain empty_po in let merge_one_domain domain map_domain po = MapString.fold (fun key pot_translation po -> add_po_translation_domain domain po (merge_translation (order_po_map ~domain ()) key pot_translation)) map_domain po in MapTextdomain.fold merge_one_domain pot.domain merge_no_domain let input_po chn = let lexbuf = Lexing.from_channel chn in try GettextPo_parser.msgfmt GettextPo_lexer.token lexbuf with | Parsing.Parse_error -> raise (PoInvalidFile ("parse error", lexbuf, chn)) | Failure s -> raise (PoInvalidFile (s, lexbuf, chn)) | PoInconsistentMerge (str1, str2) -> raise (PoInconsistentMerge (str1, str2)) let output_po chn po = let () = set_binary_mode_out chn true in let comment_max_length = 80 in let fpf x = Printf.fprintf chn x in let escape_string str = let rec escape_string_aux buff i = if i < String.length str then let () = match str.[i] with | '\n' -> Buffer.add_string buff "\\n" | '\t' -> Buffer.add_string buff "\\t" | '\b' -> Buffer.add_string buff "\\b" | '\r' -> Buffer.add_string buff "\\r" | '\012' -> Buffer.add_string buff "\\f" | '\011' -> Buffer.add_string buff "\\v" | '\007' -> Buffer.add_string buff "\\a" | '"' -> Buffer.add_string buff "\\\"" | '\\' -> Buffer.add_string buff "\\\\" | e -> Buffer.add_char buff e in escape_string_aux buff (i + 1) else () in let buff = Buffer.create (String.length str + 2) in Buffer.add_char buff '"'; escape_string_aux buff 0; Buffer.add_char buff '"'; Buffer.contents buff in let hyphens chn lst = match lst with | [] -> () | lst -> Printf.fprintf chn "%s" (String.concat "\n" (List.map escape_string lst)) in let comment_line str_hyphen str_sep line_max_length token_lst = let str_len = List.fold_left (fun acc str -> acc + String.length str) 0 token_lst + (List.length token_lst * String.length str_sep) in let buff = Buffer.create (str_len + (String.length str_hyphen * (str_len / line_max_length))) in let rec comment_line_aux first_token line_length lst = match lst with | str :: tl -> let sep_length = if first_token then 0 else if String.length str + line_length > line_max_length then ( Buffer.add_char buff '\n'; Buffer.add_string buff str_hyphen; Buffer.add_string buff str_sep; String.length str_hyphen + String.length str_sep ) else ( Buffer.add_string buff str_sep; String.length str_sep ) in Buffer.add_string buff str; comment_line_aux false (sep_length + String.length str + line_length) tl | [] -> Buffer.contents buff in comment_line_aux true 0 token_lst in let output_po_translation_aux _ commented_translation = ( match commented_translation.po_comment_filepos with | [] -> () | lst -> fpf "%s\n" (comment_line "#." " " comment_max_length ( "#:" :: List.map (fun (str, line) -> Printf.sprintf "%s:%d" str line) lst )) ); ( match commented_translation.po_comment_special with | [] -> () | lst -> fpf "%s\n" (comment_line "#." " " comment_max_length ("#," :: lst)) ); ( match commented_translation.po_comment_translation with | PoSingular (id, str) -> fpf "msgid %a\n" hyphens id; fpf "msgstr %a\n" hyphens str | PoPlural (id, id_plural, lst) -> fpf "msgid %a\n" hyphens id; fpf "msgid_plural %a\n" hyphens id_plural; let _ = List.fold_left (fun i s -> fpf "msgstr[%i] %a\n" i hyphens s; i + 1) 0 lst in () ); fpf "\n" in MapString.iter output_po_translation_aux po.no_domain; MapTextdomain.iter (fun domain map -> fpf "domain %S\n\n" domain; MapString.iter output_po_translation_aux map) po.domain let translation_of_po_translation po_translation = match po_translation with | PoSingular (id, str) -> Singular (String.concat "" id, String.concat "" str) | PoPlural (id, id_plural, lst) -> Plural ( String.concat "" id, String.concat "" id_plural, List.map (String.concat "") lst ) ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextPoComment_lexer.mll000066400000000000000000000042201367051331200265410ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) { open GettextPoComment_parser;; } rule comment_filepos = parse | [' ''\t''\r'] { comment_filepos lexbuf } | ':' { COLON } | ['0'-'9']+ as nbr { LINE (int_of_string nbr) } | ([^' ''\t''\r''\n''"'':''0'-'9''['']''#'][^' ''\t''\r''\n''"'':''['']''#']*) as str { FILENAME(str) } | eof { COMMENT_EOF } and comment_special = parse | [' ''\t''\r'] { comment_special lexbuf } | [^' ''\t''\r']+ as str { KEYWORD str } | eof { COMMENT_EOF } ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextPoComment_parser.mly000066400000000000000000000043561367051331200267450ustar00rootroot00000000000000/**************************************************************************/ /* ocaml-gettext: a library to translate messages */ /* */ /* Copyright (C) 2003-2008 Sylvain Le Gall */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version; */ /* with the OCaml static compilation exception. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ /* USA */ /**************************************************************************/ %{ %} %token COLON %token LINE %token KEYWORD %token FILENAME %token COMMENT_EOF %type comment_filepos %type comment_special %start comment_filepos comment_special %% comment_filepos: filepos_list COMMENT_EOF { List.rev $1 } | COMMENT_EOF { [] } ; filepos_list: filepos_list filepos { $2 :: $1 } | filepos { [$1] } ; filepos: FILENAME COLON LINE { ($1,$3) } ; comment_special: special_list COMMENT_EOF { List.rev $1 } | COMMENT_EOF { [] } ; special_list: special_list KEYWORD { $2 :: $1 } | KEYWORD { [$1] } ; ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextPo_lexer.mll000066400000000000000000000105441367051331200252240ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) { open GettextPo_parser;; let next_line lexbuf = lexbuf.Lexing.lex_curr_p <- { lexbuf.Lexing.lex_curr_p with Lexing.pos_lnum = lexbuf.Lexing.lex_curr_p.Lexing.pos_lnum + 1; Lexing.pos_bol = lexbuf.Lexing.lex_curr_p.Lexing.pos_cnum; } ;; } rule token = parse "msgstr" { MSGSTR } | "msgid" { MSGID } | "msgid_plural" { MSGID_PLURAL } | "domain" { DOMAIN } | '[' { LBRACKET } | ']' { RBRACKET } | ['0'-'9']+ as nbr { NUMBER (int_of_string nbr) } | '"' { STRING (string_val lexbuf) } | "#:" { COMMENT_FILEPOS(comment_join (Buffer.create 80) lexbuf)} | "#," { COMMENT_SPECIAL(comment_join (Buffer.create 80) lexbuf)} | '#' { comment_skip lexbuf } | [' ''\t'] { token lexbuf } | ['\r''\n'] { next_line lexbuf; token lexbuf } | eof { EOF } and string_val = parse "\\n" { "\n" ^ ( string_val lexbuf) } | "\\t" { "\t" ^ ( string_val lexbuf) } | "\\b" { "\b" ^ ( string_val lexbuf) } | "\\r" { "\r" ^ ( string_val lexbuf) } | "\\f" { "\012" ^ ( string_val lexbuf) } | "\\v" { "\011" ^ ( string_val lexbuf) } | "\\a" { "\007" ^ ( string_val lexbuf) } | "\\\"" { "\"" ^ ( string_val lexbuf) } | "\\\\" { "\\" ^ ( string_val lexbuf) } | '\\' (['0'-'7'] ['0'-'7']? ['0'-'7']?) as oct { let chr = try char_of_int (int_of_string ( "0o" ^ oct )) with _ -> char_of_int 255 in ( String.make 1 chr ) ^ ( string_val lexbuf ) } | "\\x" (['0'-'9''A'-'F''a'-'f'] ['0'-'9''A'-'F''a'-'f']?) as hex { let chr = try char_of_int (int_of_string ("0x" ^ hex )) with _ -> char_of_int 255 in ( String.make 1 chr ) ^ ( string_val lexbuf ) } | [^'"''\\']+ as str { str ^ (string_val lexbuf) } | '"' { "" } and comment_skip = parse ['\n'] { next_line lexbuf; token lexbuf } | _ { comment_skip lexbuf } and comment_join strbuf = parse | "\n#." { next_line lexbuf; comment_join strbuf lexbuf } | '\n' { next_line lexbuf; Buffer.contents strbuf } | '\r' { comment_join strbuf lexbuf } | [^'\n''\r']* as str { Buffer.add_string strbuf str; comment_join strbuf lexbuf } ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextPo_parser.mly000066400000000000000000000125121367051331200254130ustar00rootroot00000000000000/**************************************************************************/ /* ocaml-gettext: a library to translate messages */ /* */ /* Copyright (C) 2003-2008 Sylvain Le Gall */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version; */ /* with the OCaml static compilation exception. */ /* */ /* This library 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 */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ /* USA */ /**************************************************************************/ %{ open GettextTypes;; open GettextPo_utils;; type comment = | CommentFilePos of po_filepos list | CommentSpecial of string list ;; let check_string_format _ref str = str ;; let rec add_comment comments po_commented_translation = match comments with | CommentFilePos e :: comments_tl -> add_comment comments_tl { po_commented_translation with po_comment_filepos = List.append e po_commented_translation.po_comment_filepos } | CommentSpecial e :: comments_tl -> add_comment comments_tl { po_commented_translation with po_comment_special = List.append e po_commented_translation.po_comment_special } | [] -> po_commented_translation ;; let check_plural id id_plural lst = let check_plural_one index lst = List.rev ( snd ( List.fold_left ( fun (index,lst) (cur_index,cur_elem) -> if index + 1 = cur_index then (cur_index, (check_string_format id cur_elem) :: lst) else raise (PoFileInvalidIndex(String.concat "" id,cur_index)) ) (index,[]) lst ) ) in { po_comment_special = []; po_comment_filepos = []; po_comment_translation = PoPlural(id, (check_string_format id id_plural), (check_plural_one (-1) lst)); } ;; let check_singular id str = { po_comment_special = []; po_comment_filepos = []; po_comment_translation = PoSingular(id, check_string_format id str) } ;; %} %token MSGSTR %token MSGID %token MSGID_PLURAL %token DOMAIN %token LBRACKET %token RBRACKET %token NUMBER %token STRING %token EOF %token COMMENT_FILEPOS %token COMMENT_SPECIAL %type msgfmt %start msgfmt %% msgfmt: msgfmt domain { let (d,l) = $2 in List.fold_left (add_po_translation_domain d) $1 l } | domain { let (d,l) = $1 in List.fold_left (add_po_translation_domain d) empty_po l } | msgfmt message_list { List.fold_left add_po_translation_no_domain $1 $2 } | message_list { List.fold_left add_po_translation_no_domain empty_po $1 } | EOF { empty_po } ; comment: | COMMENT_FILEPOS { let lexbuf = Lexing.from_string $1 in let lst = GettextPoComment_parser.comment_filepos GettextPoComment_lexer.comment_filepos lexbuf in CommentFilePos lst } | COMMENT_SPECIAL { let lexbuf = Lexing.from_string $1 in let lst = GettextPoComment_parser.comment_special GettextPoComment_lexer.comment_special lexbuf in CommentSpecial lst } ; comment_list: comment_list comment { $2 :: $1 } | comment { [$1] } ;; domain: DOMAIN STRING message_list { ($2,$3) } | DOMAIN STRING { ($2,[]) } ; message_list: message_list message { $2 :: $1 } | message { [$1] } ; message: comment_list MSGID string_list MSGSTR string_list { add_comment $1 (check_singular (List.rev $3) (List.rev $5)) } | MSGID string_list MSGSTR string_list { (check_singular (List.rev $2) (List.rev $4)) } | comment_list MSGID string_list msgid_pluralform pluralform_list { add_comment $1 (check_plural (List.rev $3) $4 (List.rev $5)) } | MSGID string_list msgid_pluralform pluralform_list { (check_plural (List.rev $2) $3 (List.rev $4)) } ; msgid_pluralform: MSGID_PLURAL string_list { (List.rev $2) } ; pluralform_list: pluralform_list pluralform { $2 :: $1 } | pluralform { [$1] } ; pluralform: MSGSTR LBRACKET NUMBER RBRACKET string_list { ($3,(List.rev $5)) } ; string_list: string_list STRING { $2 :: $1 } | STRING { [$1] } ; ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextPo_utils.ml000066400000000000000000000132371367051331200250730ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** @author Sylvain Le Gall *) open GettextTypes let empty_po = { no_domain = MapString.empty; domain = MapTextdomain.empty } (* See GettextPo for details concerning merge of the translation *) let add_po_translation_aux map commented_translation = let translation = commented_translation.po_comment_translation in let is_lst_empty lst = List.for_all (fun lst -> String.concat "" lst = "") lst in let is_lst_same lst1 lst2 = try not (List.exists2 (fun a b -> a <> b) lst1 lst2) with Invalid_argument _ -> false in let string_of_list lst = let lst_escaped = List.map (fun s -> Printf.sprintf "%S" (String.concat "" s)) lst in Printf.sprintf "[ %a ]" (fun () lst -> String.concat ";" lst) lst_escaped in let str_id = match translation with | PoSingular (str_lst, _) | PoPlural (str_lst, _, _) -> str_lst in let new_commented_translation = try let previous_commented_translation = MapString.find (String.concat "" str_id) map in let previous_location_lst = previous_commented_translation.po_comment_filepos in let previous_translation = previous_commented_translation.po_comment_translation in let location_lst = commented_translation.po_comment_filepos in let merged_translation = match (previous_translation, translation) with | PoSingular (_, str1), PoSingular (_, str2) when is_lst_same str1 str2 -> PoSingular (str_id, str1) | PoSingular (_, [ "" ]), PoSingular (_, str2) -> PoSingular (str_id, str2) | PoSingular (_, str1), PoSingular (_, [ "" ]) -> PoSingular (str_id, str1) | PoSingular (_, str1), PoSingular (_, str2) -> raise (PoInconsistentMerge (String.concat "" str1, String.concat "" str2)) | PoPlural (_, str1, lst1), PoPlural (_, str2, lst2) when is_lst_same str1 str2 && is_lst_empty lst1 -> PoPlural (str_id, str2, lst2) | PoPlural (_, str1, lst1), PoPlural (_, str2, lst2) when is_lst_same str1 str2 && is_lst_empty lst2 -> PoPlural (str_id, str1, lst1) | PoPlural (_, str1, lst1), PoPlural (_, str2, lst2) when is_lst_same str1 str2 && is_lst_same lst1 lst2 -> PoPlural (str_id, str1, lst1) | PoPlural (_, str1, lst1), PoPlural (_, str2, lst2) when is_lst_same str1 str2 -> raise (PoInconsistentMerge (string_of_list lst1, string_of_list lst2)) | PoPlural (_, str1, _), PoPlural (_, str2, _) -> raise (PoInconsistentMerge (String.concat "" str1, String.concat "" str2)) | PoSingular (_, str), PoPlural (_, str_plural, lst) | PoPlural (_, str_plural, lst), PoSingular (_, str) -> ( match lst with | x :: tl when String.concat "" x = "" -> PoPlural (str_id, str_plural, str :: tl) | [] -> PoPlural (str_id, str_plural, [ str ]) | _ -> raise (PoInconsistentMerge (String.concat "" str, string_of_list lst)) ) in (* TODO: merge po_comment_special and use fuzzy when merging *) { po_comment_special = previous_commented_translation.po_comment_special @ commented_translation.po_comment_special; po_comment_filepos = location_lst @ previous_location_lst; po_comment_translation = merged_translation; } with Not_found -> commented_translation in MapString.add (String.concat "" str_id) new_commented_translation map let add_po_translation_no_domain po po_translation = { po with no_domain = add_po_translation_aux po.no_domain po_translation } let add_po_translation_domain domain po po_translation = { po with domain = (let map_domain = try MapTextdomain.find domain po.domain with Not_found -> MapString.empty in let map_domain = add_po_translation_aux map_domain po_translation in MapTextdomain.add domain map_domain po.domain); } ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextRealize.ml000066400000000000000000000103241367051331200246620ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Module type for the function realize. @author Sylvain Le Gall *) open GettextTypes open GettextCategory module Generic : functor (Translate : GettextTranslate.TRANSLATE_TYPE) (Charset : GettextCharset.CHARSET_TYPE) (Locale : GettextLocale.LOCALE_TYPE) -> REALIZE_TYPE = functor (Translate : GettextTranslate.TRANSLATE_TYPE) (Charset : GettextCharset.CHARSET_TYPE) (Locale : GettextLocale.LOCALE_TYPE) -> struct module MapTranslate = Map.Make (struct type t = textdomain * category let compare (t1, c1) (t2, c2) = match String.compare t1 t2 with | 0 -> GettextCategory.compare c1 c2 | x -> x end) let add_textdomain_category t map_translate textdomain category = try let filename = GettextDomain.find t (fst (Locale.get_locale t category)) category textdomain in let in_enc = let chn = open_in_bin filename in let mo_header = GettextMo.input_mo_header chn in let mo_informations = GettextMo.input_mo_informations t.failsafe chn mo_header in close_in chn; mo_informations.content_type_charset in let out_enc = try match MapTextdomain.find textdomain t.textdomains with | Some codeset, _ -> codeset | None, _ -> snd (Locale.get_locale t category) with Not_found -> snd (Locale.get_locale t category) in let recode = Charset.recode (Charset.create t in_enc out_enc) in MapTranslate.add (textdomain, category) (Translate.create t filename recode) map_translate with DomainFileDoesntExist _filenames -> map_translate let add_textdomain t map_translate textdomain = List.fold_left (fun m category -> add_textdomain_category t m textdomain category) map_translate GettextCategory.categories let realize t = let map_translate = MapTextdomain.fold (fun textdomain _ m -> add_textdomain t m textdomain) t.textdomains MapTranslate.empty in let dummy_translate = GettextTranslate.Dummy.create t "(none)" (fun s -> s) in fun printf_format opt str plural_form category -> let textdomain = match opt with Some textdomain -> textdomain | None -> t.default in try Translate.translate (MapTranslate.find (textdomain, category) map_translate) printf_format str plural_form with Not_found -> GettextTranslate.Dummy.translate dummy_translate printf_format str plural_form end ocaml-gettext-0.4.2/src/lib/gettext/extension/gettextTranslate.ml000066400000000000000000000201361367051331200252260ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) (** Signature of module for translation storage / access. @author Sylvain Le Gall *) open GettextTypes open GettextUtils open GettextMo open GettextFormat module type TRANSLATE_TYPE = sig type u val create : t -> filename -> (string -> string) -> u (** create t filename recode : Create a translation table using filename as the mo file and recode as the encoding converter. *) (* BUG : need update *) val translate : u -> bool -> string -> (string * int) option -> string (** translate str (plural_form,number) tbl : translate the string str using tbl. It is possible that the operation modify tbl, so it is returned also. It is also possible to get the plural form of the translated string using plural_form and number. *) end module Dummy : TRANSLATE_TYPE = struct type u = string -> string let create _t _filename charset = charset let translate charset printf_format str plural_form = match plural_form with | None -> charset str | Some (str_plural, x) -> let check = if printf_format then check_format Ignore else fun x -> x in charset (get_translated_value Ignore (check (Plural (str, str_plural, []))) (germanic_plural x)) end module Map : TRANSLATE_TYPE = struct type u = { dummy : Dummy.u; map : translation MapString.t; failsafe : failsafe; fun_plural_forms : int -> int; } let create t filename charset = let map, fun_plural_forms = fold_mo t.GettextTypes.failsafe (fun translation accu -> match translation with | Singular (str_id, str) -> MapString.add str_id (Singular (str_id, charset str)) accu | Plural (str_id, str_plural, lst) -> MapString.add str_id (Plural (str_id, str_plural, List.map charset lst)) accu) MapString.empty filename in { dummy = Dummy.create t filename charset; map; failsafe = t.GettextTypes.failsafe; fun_plural_forms; } let translate u printf_format str plural_form = try let plural_number = u.fun_plural_forms (match plural_form with Some (_, x) -> x | None -> 0) in let check = if printf_format then check_format u.failsafe else fun x -> x in get_translated_value u.failsafe (check (MapString.find str u.map)) plural_number with Not_found -> fail_or_continue u.failsafe (TranslateStringNotFound str) (Dummy.translate u.dummy printf_format str plural_form) end module Hashtbl : TRANSLATE_TYPE = struct type u = { dummy : Dummy.u; hashtbl : (string, translation) Hashtbl.t; failsafe : failsafe; fun_plural_forms : int -> int; } let create t filename charset = let hashtbl, fun_plural_forms = fold_mo t.GettextTypes.failsafe (fun translation accu -> match translation with | Singular (str_id, str) -> Hashtbl.add accu str_id (Singular (str_id, charset str)); accu | Plural (str_id, str_plural, lst) -> Hashtbl.add accu str_id (Plural (str_id, str_plural, List.map charset lst)); accu) (* 32 is only a guest on the number of string contains in the future table *) (Hashtbl.create 32) filename in { dummy = Dummy.create t filename charset; hashtbl; failsafe = t.GettextTypes.failsafe; fun_plural_forms; } let translate u printf_format str plural_form = try let plural_number = u.fun_plural_forms (match plural_form with Some (_, x) -> x | None -> 0) in let check = if printf_format then check_format u.failsafe else fun x -> x in get_translated_value u.failsafe (check (Hashtbl.find u.hashtbl str)) plural_number with Not_found -> fail_or_continue u.failsafe (TranslateStringNotFound str) (Dummy.translate u.dummy printf_format str plural_form) end module Open : TRANSLATE_TYPE = struct type u = { dummy : Dummy.u; filename : filename; charset : string -> string; failsafe : failsafe; fun_plural_forms : int -> int; number_of_strings : int; } let create t filename charset = (* Processing of the file *) let chn = open_in_bin filename in let header = input_mo_header chn in let informations = input_mo_informations t.GettextTypes.failsafe chn header in close_in chn; { dummy = Dummy.create t filename charset; filename; charset; failsafe = t.GettextTypes.failsafe; fun_plural_forms = informations.GettextTypes.fun_plural_forms; number_of_strings = Int32.to_int header.GettextTypes.number_of_strings; } let translate u printf_format str plural_form = let chn = open_in_bin u.filename in let res = try let plural_number = u.fun_plural_forms (match plural_form with Some (_, x) -> x | None -> 0) in let header = input_mo_header chn in let rec find_str_id (start_index, end_index) = let middle_index = (start_index + end_index) / 2 in let str_id = let lst_str_id = input_mo_untranslated u.failsafe chn header middle_index in match lst_str_id with | str_id :: _ -> str_id | [] -> (* BUG : should be a real exception *) raise Not_found in match String.compare str str_id with | x when x < 0 && start_index <= middle_index - 1 -> find_str_id (start_index, middle_index - 1) | x when x > 0 && middle_index + 1 <= end_index -> find_str_id (middle_index + 1, end_index) | x when x = 0 -> middle_index | _ -> raise Not_found in let translation = let translation = input_mo_translation u.failsafe chn header (find_str_id (0, u.number_of_strings - 1)) in match translation with | Singular (str_id, str) -> Singular (str_id, u.charset str) | Plural (str_id, str_plural, lst) -> Plural (str_id, str_plural, List.map u.charset lst) in get_translated_value u.failsafe translation plural_number with Not_found -> fail_or_continue u.failsafe (TranslateStringNotFound str) (Dummy.translate u.dummy printf_format str plural_form) in close_in chn; res end ocaml-gettext-0.4.2/src/tools/000077500000000000000000000000001367051331200162225ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/tools/discover-stub/000077500000000000000000000000001367051331200210135ustar00rootroot00000000000000ocaml-gettext-0.4.2/src/tools/discover-stub/discover.ml000066400000000000000000000025561367051331200231730ustar00rootroot00000000000000module C = Configurator.V1 let gettext_code = {| #include int main() { gettext("abcd"); return 0; } |} let () = C.main ~name:"gettext" (fun c -> let is_working (c_flags, link_flags) = C.c_test c gettext_code ~link_flags ~c_flags in let c_flags, link_flags = try List.find is_working [ (* Default that should work on standard Linux distributions. *) ([], []); (* MacOS with Homebrew. * The library is "keg-only" to prevent conflict with system * installed BSD gettext library, so we have to pull it from * /usr/local. * https://formulae.brew.sh/formula/gettext *) (["-I/usr/local/opt/gettext/include"], ["-L/usr/local/opt/gettext/lib"; "-lintl"]); (* MacOS with MacPorts. * -- This is untested, a patch is welcome if you use MacPorts -- * https://ports.macports.org/port/gettext/summary *) (["-I/usr/local/include"], ["-L/usr/local/lib"; "-lintl"]); ] with Not_found -> C.die "no ways to compile with gettext library" in C.Flags.write_sexp "c_flags.sexp" c_flags; C.Flags.write_sexp "c_library_flags.sexp" link_flags) ocaml-gettext-0.4.2/src/tools/discover-stub/dune000066400000000000000000000000751367051331200216730ustar00rootroot00000000000000(executable (name discover) (libraries dune.configurator)) ocaml-gettext-0.4.2/test/000077500000000000000000000000001367051331200152525ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/bench/000077500000000000000000000000001367051331200163315ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/bench/bench.ml000066400000000000000000000213351367051331200177460ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open Benchmark open Common open GettextTypes type benchs = { verbose : bool; search_path : string list; time : int } (* Different implementation of realize. *) let realize_data = [ ("Camomile.Map", GettextCamomile.Map.realize); ("Camomile.Hashtbl", GettextCamomile.Hashtbl.realize); ("Camomile.Open", GettextCamomile.Open.realize); ("Stub.Native", GettextStub.Native.realize); ("Stub.Preload", GettextStub.Preload.realize); ] let parse_arg () = let benchs = ref { verbose = false; search_path = []; time = 1 } in Arg.parse (Arg.align [ ( "--search", Arg.String (fun dir -> benchs := { !benchs with search_path = dir :: !benchs.search_path }), "dir Search the specified directory for MO file." ); ( "--verbose", Arg.Unit (fun () -> benchs := { !benchs with verbose = true }), "Processs with a lot of message." ); ( "--time", Arg.Int (fun sec -> benchs := { !benchs with time = sec }), Printf.sprintf "second Process each test during the specified number of second. \ Default : %d." !benchs.time ); ]) (fun _str -> ()) ( "Benchmark utility for ocaml-gettext v" ^ GettextConfig.version ^ " by Sylvain Le Gall\n" ^ "Copyright (C) 2004-2008 Sylvain Le Gall \n" ^ "Licensed under LGPL v2.1 with Ocaml exception." ); !benchs let print_debug benchs str = if benchs.verbose then ( print_string str; print_newline () ) else () let make_buffer lst = (lst, []) let get_buffer (lst1, lst2) = match (lst1, lst2) with | hd :: tl, lst2 -> (hd, (tl, hd :: lst2)) | [], hd :: tl -> (hd, (tl, [ hd ])) | [], [] -> failwith "Buffer is empty" (* Generic function to benchmark gettextCompat function *) let gettext_bench benchs str_gettext fun_gettext = let f ref_translations = let (debug_str, t', textdomain, tr), buffer = get_buffer !ref_translations in print_debug benchs (Printf.sprintf "Translation of %S from %s" (string_of_translation tr) debug_str); ignore (fun_gettext t' textdomain tr); ref_translations := buffer in let parameters_lst = List.map parameters_of_filename mo_files_data in let create_translation (str_realize, realize) = let rec create_one_translation accu lst = match lst with | parameters :: tl -> let t = t_of_parameters parameters in let t' = realize t in let new_accu = List.fold_left (fun lst tr -> ( str_realize ^ " with textdomain " ^ parameters.textdomain, t', parameters.textdomain, tr ) :: lst) accu parameters.translations in create_one_translation new_accu tl | [] -> make_buffer accu in ref (create_one_translation [] parameters_lst) in let bench_lst = List.map (fun (str_realize, realize) -> (str_realize, f, create_translation (str_realize, realize))) realize_data in print_debug benchs ("Benchmarking " ^ str_gettext ^ ":"); (str_gettext ^ " benchmark", throughputN benchs.time bench_lst) (*******************************) (* Performance of check_format *) (*******************************) let format_bench benchs = let f ref_buffer = let elem, buffer = get_buffer !ref_buffer in let translation = print_debug benchs ("Checking format of : " ^ string_of_translation elem); GettextFormat.check_format Ignore elem in print_debug benchs ("Result of the check : " ^ string_of_translation translation); ref_buffer := buffer in print_debug benchs "Benchmarking format :"; ( "Format benchmark", throughputN benchs.time [ ("Singular", f, ref (make_buffer format_translation_singular_data)); ("Plural", f, ref (make_buffer format_translation_plural_data)); ("All", f, ref (make_buffer format_translation_all_data)); ] ) (***************************) (* Performance of realize *) (***************************) let realize_bench benchs = let f (realize, parameters_lst) = let f_one parameters = let t = print_debug benchs ("Creating t for " ^ parameters.fl_mo); t_of_parameters parameters in print_debug benchs ("Realizing t for " ^ parameters.fl_mo); ignore (realize t) in List.iter f_one parameters_lst in let parameters_lst = List.map parameters_of_filename mo_files_data in let bench_lst = List.map (fun (str_implementation, realize) -> (str_implementation, f, (realize, parameters_lst))) realize_data in print_debug benchs "Benchmarking realize:"; ("Realize benchmark", throughputN benchs.time bench_lst) (**********************) (* Performance of s_ *) (**********************) let s_bench benchs = let fun_gettext t' textdomain translation = match translation with | Singular (str, _) -> ignore (GettextCompat.dgettext t' textdomain str) | _ -> () in gettext_bench benchs "s_" fun_gettext (*********************) (* Performance of f_ *) (*********************) let f_bench benchs = let fun_gettext t' textdomain translation = match translation with | Singular (str, _) -> ignore (GettextCompat.fdgettext t' textdomain (Obj.magic str)) | _ -> () in gettext_bench benchs "f_" fun_gettext (**********************) (* Performance of sn_ *) (**********************) let sn_bench benchs = let fun_gettext t' textdomain translation = match translation with | Plural (str_id, str_plural, _) -> ignore (GettextCompat.dngettext t' textdomain str_id str_plural 0); ignore (GettextCompat.dngettext t' textdomain str_id str_plural 1); ignore (GettextCompat.dngettext t' textdomain str_id str_plural 2); ignore (GettextCompat.dngettext t' textdomain str_id str_plural 3) | _ -> () in gettext_bench benchs "sn_" fun_gettext (**********************) (* Performance of fn_ *) (**********************) let fn_bench benchs = let fun_gettext t' textdomain translation = match translation with | Plural (str_id, str_plural, _) -> ignore (GettextCompat.fdngettext t' textdomain (Obj.magic str_id) (Obj.magic str_plural) 0); ignore (GettextCompat.fdngettext t' textdomain (Obj.magic str_id) (Obj.magic str_plural) 1); ignore (GettextCompat.fdngettext t' textdomain (Obj.magic str_id) (Obj.magic str_plural) 2); ignore (GettextCompat.fdngettext t' textdomain (Obj.magic str_id) (Obj.magic str_plural) 3) | _ -> () in gettext_bench benchs "fn_" fun_gettext (**************************) (* Main benchmark routine *) (**************************) ;; let benchs = parse_arg () in let all_bench = [ format_bench; realize_bench; s_bench; f_bench; sn_bench; fn_bench ] in print_env "benchmarks"; (* Running *) let all_results = List.map (fun x -> x benchs) all_bench in List.iter (fun (str, results) -> print_newline (); print_newline (); print_endline str; tabulate results) all_results ocaml-gettext-0.4.2/test/bench/dune000066400000000000000000000000711367051331200172050ustar00rootroot00000000000000(executable (name bench) (libraries benchmark common)) ocaml-gettext-0.4.2/test/common/000077500000000000000000000000001367051331200165425ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/common/common.ml000066400000000000000000000430451367051331200203720ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open GettextTypes open GettextCategory open FilePath.DefaultPath open OUnit2 (* Print a translation *) let string_of_translation trans = match trans with | Singular (str_id, str) -> Printf.sprintf "Singular(%S, %S)" str_id str | Plural (str_id, str_plural, lst) -> Printf.sprintf "Plural(%S, %S, [ %s ])" str_id str_plural (String.concat " ; " (List.map (fun x -> Printf.sprintf "%S" x) lst)) (* Function for extracting all information of MO file *) type parameters = { fl_mo : filename; base_dir : dir; language : locale; category : category; textdomain : textdomain; translations : translation list; } let parameters_of_filename fl_mo = (* File scheme: base_dir/lang/category/domain.mo *) let textdomain = chop_extension (basename fl_mo) in let category = GettextCategory.category_of_string (basename (dirname fl_mo)) in let language = basename (dirname (dirname fl_mo)) in let base_dir = dirname (dirname (dirname fl_mo)) in let translations, _ = GettextMo.fold_mo RaiseException (fun x lst -> x :: lst) [] fl_mo in { fl_mo; base_dir; language; category; textdomain; translations } (* Build the parameter t out of parameters extracted above *) let t_of_parameters parameters = (* We use a UTF-8 binding, this is the most generic encoding * for all strings *) GettextModules.create ~failsafe:RaiseException ~codesets:[ (parameters.textdomain, "UTF-8") ] ~path:[ parameters.base_dir ] ~language:parameters.language parameters.textdomain (* Data for format test/bench *) let format_translation_check_data = [ (* Identity *) (Singular ("%d", "%d"), Singular ("%d", "%d")); (Singular ("%i", "%i"), Singular ("%i", "%i")); (Singular ("%n", "%n"), Singular ("%n", "%n")); (Singular ("%N", "%N"), Singular ("%N", "%N")); (Singular ("%u", "%u"), Singular ("%u", "%u")); (Singular ("%x", "%x"), Singular ("%x", "%x")); (Singular ("%X", "%X"), Singular ("%X", "%X")); (Singular ("%o", "%o"), Singular ("%o", "%o")); (Singular ("%s", "%s"), Singular ("%s", "%s")); (Singular ("%S", "%S"), Singular ("%S", "%S")); (Singular ("%c", "%c"), Singular ("%c", "%c")); (Singular ("%C", "%C"), Singular ("%C", "%C")); (Singular ("%f", "%f"), Singular ("%f", "%f")); (Singular ("%F", "%F"), Singular ("%F", "%F")); (Singular ("%e", "%e"), Singular ("%e", "%e")); (Singular ("%E", "%E"), Singular ("%E", "%E")); (Singular ("%g", "%g"), Singular ("%g", "%g")); (Singular ("%G", "%G"), Singular ("%G", "%G")); (Singular ("%B", "%B"), Singular ("%B", "%B")); (Singular ("%b", "%b"), Singular ("%b", "%b")); (Singular ("%ld", "%ld"), Singular ("%ld", "%ld")); (Singular ("%li", "%li"), Singular ("%li", "%li")); (Singular ("%lu", "%lu"), Singular ("%lu", "%lu")); (Singular ("%lx", "%lx"), Singular ("%lx", "%lx")); (Singular ("%lX", "%lX"), Singular ("%lX", "%lX")); (Singular ("%lo", "%lo"), Singular ("%lo", "%lo")); (Singular ("%nd", "%nd"), Singular ("%nd", "%nd")); (Singular ("%ni", "%ni"), Singular ("%ni", "%ni")); (Singular ("%nu", "%nu"), Singular ("%nu", "%nu")); (Singular ("%nx", "%nx"), Singular ("%nx", "%nx")); (Singular ("%nX", "%nX"), Singular ("%nX", "%nX")); (Singular ("%no", "%no"), Singular ("%no", "%no")); (Singular ("%Ld", "%Ld"), Singular ("%Ld", "%Ld")); (Singular ("%Li", "%Li"), Singular ("%Li", "%Li")); (Singular ("%Lu", "%Lu"), Singular ("%Lu", "%Lu")); (Singular ("%Lx", "%Lx"), Singular ("%Lx", "%Lx")); (Singular ("%LX", "%LX"), Singular ("%LX", "%LX")); (Singular ("%Lo", "%Lo"), Singular ("%Lo", "%Lo")); (Singular ("%a", "%a"), Singular ("%a", "%a")); (Singular ("%t", "%t"), Singular ("%t", "%t")); (Singular ("%!", "%!"), Singular ("%!", "%!")); (Singular ("%%", "%%"), Singular ("%%", "%%")); (* Always fails *) (Singular ("%d", ""), Singular ("%d", "%d")); (Singular ("%i", ""), Singular ("%i", "%i")); (Singular ("%n", ""), Singular ("%n", "%n")); (Singular ("%N", ""), Singular ("%N", "%N")); (Singular ("%u", ""), Singular ("%u", "%u")); (Singular ("%x", ""), Singular ("%x", "%x")); (Singular ("%X", ""), Singular ("%X", "%X")); (Singular ("%o", ""), Singular ("%o", "%o")); (Singular ("%s", ""), Singular ("%s", "%s")); (Singular ("%S", ""), Singular ("%S", "%S")); (Singular ("%c", ""), Singular ("%c", "%c")); (Singular ("%C", ""), Singular ("%C", "%C")); (Singular ("%f", ""), Singular ("%f", "%f")); (Singular ("%F", ""), Singular ("%F", "%F")); (Singular ("%e", ""), Singular ("%e", "%e")); (Singular ("%E", ""), Singular ("%E", "%E")); (Singular ("%g", ""), Singular ("%g", "%g")); (Singular ("%G", ""), Singular ("%G", "%G")); (Singular ("%B", ""), Singular ("%B", "%B")); (Singular ("%b", ""), Singular ("%b", "%b")); (Singular ("%ld", ""), Singular ("%ld", "%ld")); (Singular ("%li", ""), Singular ("%li", "%li")); (Singular ("%lu", ""), Singular ("%lu", "%lu")); (Singular ("%lx", ""), Singular ("%lx", "%lx")); (Singular ("%lX", ""), Singular ("%lX", "%lX")); (Singular ("%lo", ""), Singular ("%lo", "%lo")); (Singular ("%nd", ""), Singular ("%nd", "%nd")); (Singular ("%ni", ""), Singular ("%ni", "%ni")); (Singular ("%nu", ""), Singular ("%nu", "%nu")); (Singular ("%nx", ""), Singular ("%nx", "%nx")); (Singular ("%nX", ""), Singular ("%nX", "%nX")); (Singular ("%no", ""), Singular ("%no", "%no")); (Singular ("%Ld", ""), Singular ("%Ld", "%Ld")); (Singular ("%Li", ""), Singular ("%Li", "%Li")); (Singular ("%Lu", ""), Singular ("%Lu", "%Lu")); (Singular ("%Lx", ""), Singular ("%Lx", "%Lx")); (Singular ("%LX", ""), Singular ("%LX", "%LX")); (Singular ("%Lo", ""), Singular ("%Lo", "%Lo")); (Singular ("%a", ""), Singular ("%a", "%a")); (Singular ("%t", ""), Singular ("%t", "%t")); (* Mismatch *) (Singular ("%d", "%i"), Singular ("%d", "%d")); (Singular ("%i", "%d"), Singular ("%i", "%i")); (Singular ("%n", "%d"), Singular ("%n", "%n")); (Singular ("%N", "%d"), Singular ("%N", "%N")); (Singular ("%u", "%d"), Singular ("%u", "%u")); (Singular ("%x", "%d"), Singular ("%x", "%x")); (Singular ("%X", "%d"), Singular ("%X", "%X")); (Singular ("%o", "%d"), Singular ("%o", "%o")); (Singular ("%s", "%d"), Singular ("%s", "%s")); (Singular ("%S", "%d"), Singular ("%S", "%S")); (Singular ("%c", "%d"), Singular ("%c", "%c")); (Singular ("%C", "%d"), Singular ("%C", "%C")); (Singular ("%f", "%d"), Singular ("%f", "%f")); (Singular ("%F", "%d"), Singular ("%F", "%F")); (Singular ("%e", "%d"), Singular ("%e", "%e")); (Singular ("%E", "%d"), Singular ("%E", "%E")); (Singular ("%g", "%d"), Singular ("%g", "%g")); (Singular ("%G", "%d"), Singular ("%G", "%G")); (Singular ("%B", "%d"), Singular ("%B", "%B")); (Singular ("%b", "%d"), Singular ("%b", "%b")); (Singular ("%ld", "%d"), Singular ("%ld", "%ld")); (Singular ("%li", "%d"), Singular ("%li", "%li")); (Singular ("%lu", "%d"), Singular ("%lu", "%lu")); (Singular ("%lx", "%d"), Singular ("%lx", "%lx")); (Singular ("%lX", "%d"), Singular ("%lX", "%lX")); (Singular ("%lo", "%d"), Singular ("%lo", "%lo")); (Singular ("%nd", "%d"), Singular ("%nd", "%nd")); (Singular ("%ni", "%d"), Singular ("%ni", "%ni")); (Singular ("%nu", "%d"), Singular ("%nu", "%nu")); (Singular ("%nx", "%d"), Singular ("%nx", "%nx")); (Singular ("%nX", "%d"), Singular ("%nX", "%nX")); (Singular ("%no", "%d"), Singular ("%no", "%no")); (Singular ("%Ld", "%d"), Singular ("%Ld", "%Ld")); (Singular ("%Li", "%d"), Singular ("%Li", "%Li")); (Singular ("%Lu", "%d"), Singular ("%Lu", "%Lu")); (Singular ("%Lx", "%d"), Singular ("%Lx", "%Lx")); (Singular ("%LX", "%d"), Singular ("%LX", "%LX")); (Singular ("%Lo", "%d"), Singular ("%Lo", "%Lo")); (Singular ("%a", "%d"), Singular ("%a", "%a")); (Singular ("%t", "%d"), Singular ("%t", "%t")); (Singular ("%!", "%d"), Singular ("%!", "%!")); (Singular ("%%", "%d"), Singular ("%%", "%%")); (* All in one *) ( Singular ( "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%", "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%" ), Singular ( "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%", "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%" ) ); ( Singular ( "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%", "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E g %G %B %b %ld %li %lu %lx %lX " ^ "lo nd ni nu nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%" ), Singular ( "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%", "%d %i %n %N %u %x %X %o %s %S %c %C " ^ "%f %F %e %E %g %G %B %b %ld %li %lu %lx %lX " ^ "%lo %nd %ni %nu %nx %nX %no %Ld %Li %Lu %Lx " ^ "%LX %Lo %a %t %! %%" ) ); (* Plural forms *) ( Plural ("singular %d", "plural %i", [ "%d"; "%d" ]), Plural ("singular %d", "singular %d", [ "%d"; "%d" ]) ); ( Plural ("singular %d", "plural %d", [ "%i"; "%d" ]), Plural ("singular %d", "plural %d", [ "singular %d"; "%d" ]) ); ( Plural ("singular %d", "plural %d", [ "%d"; "%i" ]), Plural ("singular %d", "plural %d", [ "%d"; "plural %d" ]) ); ( Plural ("singular %d", "plural %d", [ "%d"; "%d" ]), Plural ("singular %d", "plural %d", [ "%d"; "%d" ]) ); (* Idem potent *) (Singular ("%%", ""), Singular ("%%", "")); (Singular ("%!", ""), Singular ("%!", "")); (Singular ("", ""), Singular ("", "")); (Singular ("a", "b"), Singular ("a", "b")); ] let format_translation_all_data = List.fold_left (fun lst (a, b) -> a :: b :: lst) [] format_translation_check_data let format_translation_plural_data = List.filter (function Plural (_, _, _) -> true | _ -> false) format_translation_all_data let format_translation_singular_data = List.filter (function Singular (_, _) -> true | _ -> false) format_translation_all_data (* Files installed for testing purpose. "." refers to the directory where common.ml is installed. *) let mo_files_data = [ make_filename [ "fr_FR"; "LC_MESSAGES"; "test1.mo" ]; make_filename [ "fr_FR"; "LC_MESSAGES"; "test2.mo" ]; make_filename [ "fr_FR"; "LC_MESSAGES"; "test3.mo" ]; make_filename [ "fr_FR"; "LC_MESSAGES"; "test4.mo" ]; make_filename [ "fr_FR"; "LC_MESSAGES"; "test10.mo" ]; make_filename [ "fr_FR"; "LC_MESSAGES"; "test11.mo" ]; ] type tests = { ocaml_xgettext : string; ocaml_gettext : string; test_dir : string; install_dir : string; } let ocaml_xgettext = Conf.make_exec "ocaml_xgettext" let ocaml_gettext = Conf.make_exec "ocaml_gettext" let test_dir = Conf.make_string "test_dir" (make_filename [ current_dir; "testdata" ]) "Specify the location of the testdata directory" let make_tests ctxt = { ocaml_xgettext = ocaml_xgettext ctxt; ocaml_gettext = ocaml_gettext ctxt; test_dir = test_dir ctxt; install_dir = make_filename [ current_dir; "testinstall" ]; } (**********************************) (* Test of Gettext implementation *) (**********************************) let implementation_test realize_data = (* Generate a test case of simple load of a MO file using an implementation *) let test_load parameters_lst (realize_str, realize) = let test_load_one realize fl_mo = fl_mo >:: fun ctx -> (* Extract usefull information out of parameters *) let tests = make_tests ctx in let parameters = parameters_of_filename (Filename.concat tests.test_dir fl_mo) in let test_translations = parameters.translations in (* Build t *) let t = t_of_parameters parameters in (* Build t' *) let t' = realize t in let test_one_translation translation = (* We cannot compare directly extracted values and t' extracted value , since we have a charset translation *) try match translation with | Singular (str_id, _) -> ignore (GettextCompat.gettext t' str_id) | Plural (str_id, str_plural, _) -> (* Using values from 0 to 2, we cover most of the plural cases *) ignore (GettextCompat.ngettext t' str_id str_plural 0); ignore (GettextCompat.ngettext t' str_id str_plural 1); ignore (GettextCompat.ngettext t' str_id str_plural 2) with exc -> assert_failure ( Printexc.to_string exc ^ " in " ^ string_of_translation translation ) in List.iter test_one_translation test_translations in realize_str >::: List.map (test_load_one realize) parameters_lst in (* Generate a cross test of string extracted, using different implementation *) let test_cross implementation_lst fl_mo = fl_mo >:: fun ctxt -> (* Extract usefull information out of parameters *) let tests = make_tests ctxt in let parameters = parameters_of_filename (Filename.concat tests.test_dir fl_mo) in let test_translations = parameters.translations in (* Build t *) let t = t_of_parameters parameters in (* Build all t' *) let t'_lst = List.map (fun (realize_str, realize) -> (realize_str, realize t)) implementation_lst in let check_translation str lst = let _, same_str = List.fold_left (fun (prev_str_opt, res) (_, cur_str) -> match prev_str_opt with | Some prev_str -> (Some cur_str, res && prev_str = cur_str) | None -> (Some cur_str, res)) (None, true) lst in if same_str then () else assert_failure (Printf.sprintf "All values should be identical in [ %s ] in function %s" (String.concat " ; " (List.map (fun (realize_str, str) -> Printf.sprintf "(%s,%S)" realize_str str) lst)) str) in let test_cross_one translation = match translation with | Singular (str_id, _) -> check_translation (Printf.sprintf "GettextCompat.gettext t' %S" str_id) (List.map (fun (realize_str, t') -> (realize_str, GettextCompat.gettext t' str_id)) t'_lst) | Plural (str_id, str_plural, _) -> List.iter (fun n -> check_translation (Printf.sprintf "GettextCompat.ngettext t' %S %S %d" str_id str_plural n) (List.map (fun (realize_str, t') -> ( realize_str, GettextCompat.ngettext t' str_id str_plural n )) t'_lst)) [ 0; 1; 2 ] in List.iter test_cross_one test_translations in (* Extract and test *) "Gettext implementation test" >::: [ "Load" >::: List.map (test_load mo_files_data) realize_data; "Cross check" >::: List.map (test_cross realize_data) mo_files_data; ] ocaml-gettext-0.4.2/test/common/dune000066400000000000000000000000711367051331200174160ustar00rootroot00000000000000(library (name common) (libraries gettext.base oUnit)) ocaml-gettext-0.4.2/test/dune000066400000000000000000000006551367051331200161360ustar00rootroot00000000000000(test (name test) (package gettext) (deps ../src/bin/ocaml-gettext/OCamlGettext.exe ../src/bin/ocaml-xgettext/xgettext.exe (glob_files testdata/*) (glob_files testdata/fr_FR/LC_MESSAGES/*)) (libraries oUnit str fileutils gettext.extension common) (action (run %{test} -runner sequential -ocaml-gettext ../src/bin/ocaml-gettext/OCamlGettext.exe -ocaml-xgettext ../src/bin/ocaml-xgettext/xgettext.exe))) ocaml-gettext-0.4.2/test/test-camomile/000077500000000000000000000000001367051331200200155ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/test-camomile/dune000066400000000000000000000003461367051331200206760ustar00rootroot00000000000000(test (name test) (package gettext-camomile) (deps (glob_files testdata/*) (glob_files ../testdata/fr_FR/LC_MESSAGES/*)) (libraries common gettext-camomile oUnit fileutils) (action (run %{test} -test-dir ../testdata))) ocaml-gettext-0.4.2/test/test-camomile/test.ml000066400000000000000000000037301367051331200213310ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open OUnit2 open Common (* Different implementation of realize. *) let realize_data = [ ("Camomile.Map", GettextCamomile.Map.realize); ("Camomile.Hashtbl", GettextCamomile.Hashtbl.realize); ("Camomile.Open", GettextCamomile.Open.realize); ] (* mkdir ~parent:true tests.test_dir; *) let () = run_test_tt_main ("test-camomile" >::: [ implementation_test realize_data ]) ocaml-gettext-0.4.2/test/test-stub/000077500000000000000000000000001367051331200172045ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/test-stub/dune000066400000000000000000000003271367051331200200640ustar00rootroot00000000000000(test (name test) (package gettext-stub) (deps (glob_files ../testdata/*) (glob_files ../testdata/fr_FR/LC_MESSAGES/*)) (libraries common gettext-stub oUnit) (action (run %{test} -test-dir ../testdata))) ocaml-gettext-0.4.2/test/test-stub/test.ml000066400000000000000000000044711367051331200205230ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open OUnit2 open Common (* Different implementation of realize. *) let realize_data = [ ("Stub.Native", GettextStub.Native.realize); ("Stub.Preload", GettextStub.Preload.realize); ] (************************************************) (* Set bad locale and spot error when setlocale *) (* returns NULL *) (************************************************) let bad_setlocale = "Call setlocale with bad locale" >::: [ ( "setlocale with bad locale" >:: fun _ -> ignore (GettextStubCompat.setlocale GettextStubCompat.LC_ALL "xx") ); ] let () = run_test_tt_main ("test-stub" >::: [ bad_setlocale; implementation_test realize_data; ]) ocaml-gettext-0.4.2/test/test.ml000066400000000000000000000376301367051331200165740ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) open OUnit2 open FileUtil open FilePath open GettextTypes open GettextCategory open Common let load_mo_file ctxt f_test_mo fl_mo = let mo = open_in_bin fl_mo in let mo_header = GettextMo.input_mo_header mo in let mo_informations = GettextMo.input_mo_informations RaiseException mo mo_header in logf ctxt `Info "%s" (GettextMo.string_of_mo_header mo_header); logf ctxt `Info "%s" (GettextMo.string_of_mo_informations mo_informations); close_in mo; f_test_mo fl_mo (**********************************) (* Test of Printf format checking *) (**********************************) let format_test = let format_test_one (trans_src, trans_dst) = let lst_str_equal lst1 lst2 = try List.fold_left2 (fun b str1 str2 -> b && str1 = str2) true lst1 lst2 with Invalid_argument _ -> false in Printf.sprintf "%s -> %s format checking" (string_of_translation trans_src) (string_of_translation trans_dst) >:: fun _ctxt -> let trans_res = GettextFormat.check_format Ignore trans_src in match (trans_res, trans_dst) with | Singular (str_id1, str1), Singular (str_id2, str2) when str_id1 = str_id2 && str1 = str2 -> () | Plural (str_id1, str_plural1, lst1), Plural (str_id2, str_plural2, lst2) when str_id1 = str_id2 && str_plural1 = str_plural2 && lst_str_equal lst1 lst2 -> () | trans1, trans2 -> assert_failure ( string_of_translation trans1 ^ " differs from " ^ string_of_translation trans2 ) in "Printf format test" >::: List.map format_test_one format_translation_check_data (**************************) (* Split plural functions *) (**************************) let split_plural_test = let split_plural_test_one (str, res_lst) = Printf.sprintf "Split plural test %S" str >:: fun _ -> let lst = GettextUtils.split_plural str in List.iter2 (fun str1 str2 -> if str1 = str2 then () else assert_failure (Printf.sprintf "%S should be %S" str2 str1)) res_lst lst in "Split plural test" >::: List.map split_plural_test_one [ ("%d coffee\000more %d coffee", [ "%d coffee"; "more %d coffee" ]) ] (*************************) (* Test of PO processing *) (*************************) let po_test = let po_test_one f_test_mo fl_po = Printf.sprintf "Load and compile %s" fl_po >:: fun ctxt -> let tests = make_tests ctxt in let fl_mo = concat tests.test_dir (replace_extension fl_po "mo") in let fl_po = concat tests.test_dir fl_po in let chn = open_in fl_po in ignore (GettextPo.input_po chn); close_in chn; GettextCompile.compile fl_po fl_mo; load_mo_file ctxt f_test_mo fl_mo in "PO processing test" >::: List.map (po_test_one ignore) [ "test1.po"; "test2.po"; "test3.po"; "test4.po"; "test11.po" ] @ [ po_test_one (fun fl_mo -> let (), _ = GettextMo.fold_mo RaiseException (fun trslt () -> match trslt with | Singular (id, "") | Plural (id, _, []) | Plural (id, _, [ "" ]) -> assert_failure (Printf.sprintf "%s contains an empty translation for %s" fl_mo id) | _ -> ()) () fl_mo in ()) "test12.po"; ] (*******************************************) (* Test of OCaml source file PO extraction *) (*******************************************) let extract_test = let default_options = "" in let filename_options = MapString.empty in let extract_test_one (fl_ml, contents) = fl_ml >::: [ ("Extracting" >:: fun ctxt -> let tests = make_tests ctxt in let fl_pot = concat tests.test_dir (replace_extension fl_ml "pot") in let fl_ml = concat tests.test_dir fl_ml in begin try let ocaml_xgettext = if FilePath.is_relative tests.ocaml_xgettext then FilePath.make_absolute (Sys.getcwd ()) tests.ocaml_xgettext else tests.ocaml_xgettext in (* Extract data from files *) GettextCompile.extract ocaml_xgettext default_options filename_options [ fl_ml ] fl_pot with x -> assert_failure ( fl_ml ^ " doesn't extract correctly: " ^ Gettext.string_of_exception x ) end; (* Load POT file *) let po = let chn = open_in fl_pot in let res = GettextPo.input_po chn in close_in chn; res in (* Check result *) List.iter (fun str -> if MapString.mem str po.no_domain then () else assert_failure (Printf.sprintf "Cannot find %S in %s" str fl_pot)) contents ); ] in "OCaml file extraction test" >::: List.map extract_test_one [ ("test4.ml", []); ( "escape-char.ml", [ "hello world!\n"; "goodbye world!\n"; "goodby world 2!"; "and then\tbye-bye"; ] ); ] (********************************) (* Test of MO file installation *) (********************************) let install_test = let install_test_one (language, category, textdomain, fl_mo, fl_dsts) = fl_mo >:: fun ctxt -> let tests = make_tests ctxt in let fl_mo = concat tests.test_dir fl_mo in let fl_dst = make_filename (tests.install_dir :: fl_dsts) in GettextCompile.install true tests.install_dir language category textdomain fl_mo; assert_bool (Printf.sprintf "%s is not installed at %s" fl_mo fl_dst) (test Exists fl_dst) in let install_fail_test_one (fl_mo, exc) = let error = Printexc.to_string exc in Printf.sprintf "%s (%s)" fl_mo error >:: fun ctxt -> let tests = make_tests ctxt in let fl_mo = concat tests.test_dir fl_mo in assert_raises ~msg: (Printf.sprintf "Installation of %s should have failed with error %s" fl_mo error) exc (fun () -> GettextCompile.install true tests.install_dir "fr" LC_MESSAGES "gettext-fail" fl_mo) in let install_warning_test_one (language, category, textdomain, fl_mo, exp_err, fl_dsts) = Printf.sprintf "%s warning" fl_mo >:: fun ctxt -> let tests = make_tests ctxt in let out = Buffer.create 13 in let capture_out strm = Stream.iter (Buffer.add_char out) strm in let fl_mo = concat tests.test_dir fl_mo in let fl_dst = make_filename (tests.install_dir :: fl_dsts) in assert_command ~ctxt ~use_stderr:true ~foutput:capture_out tests.ocaml_gettext [ "--action"; "install"; "--install-language"; language; "--install-category"; category; "--install-textdomain"; textdomain; "--install-destdir"; tests.install_dir; fl_mo; ]; assert_equal ~msg:("error output") ~printer:(Printf.sprintf "%S") exp_err (Buffer.contents out); assert_bool (Printf.sprintf "File %s doesn't exist" fl_dst) (test Exists fl_dst) in "MO file installation test" >::: List.map install_test_one [ ( "fr", LC_MESSAGES, "gettext-test1", "test1.mo", [ "fr"; "LC_MESSAGES"; "gettext-test1.mo" ] ); ( "fr_FR", LC_MESSAGES, "gettext-test2", "test2.mo", [ "fr_FR"; "LC_MESSAGES"; "gettext-test2.mo" ] ); ( "fr", LC_TIME, "gettext-test3", "test3.mo", [ "fr"; "LC_TIME"; "gettext-test3.mo" ] ); ( "fr_FR@euro", LC_MESSAGES, "gettext-test4", "test4.mo", [ "fr_FR@euro"; "LC_MESSAGES"; "gettext-test4.mo" ] ); ] @ List.map install_fail_test_one [ ("test5.mo", MoInvalidFile); ( "test6.mo", MoInvalidHeaderTableStringOutOfBound ((28l, 2626l), (-1l, 159l)) ); ( "test7.mo", MoInvalidHeaderTableTranslationOutOfBound ((28l, 2626l), (-49l, 111l)) ); ("test8.mo", MoInvalidStringOutOfBound (2626, 36)); ("test9.mo", MoInvalidTranslationOutOfBound (2626, 196)); ] @ List.map install_warning_test_one [ ( "fr", "LC_MESSAGES", "test10", "test10.mo", "Error while processing parsing of plural at line 1 character \ 10: \" nplurals=INTEGER; plural=EXPRESSION;\".\n", [ "fr"; "LC_MESSAGES"; "test10.mo" ] ); ] (************************) (* Test of POT/PO merge *) (************************) let merge_test = let merge_one (fl_pot, fl_po, backup_ext) = fl_pot ^ "+" ^ fl_po >::: [ ("Merging" >:: fun ctxt -> let tests = make_tests ctxt in let fl_pot = concat tests.test_dir fl_pot in let fl_po = concat tests.test_dir fl_po in try (* Copying the file to the good place *) let fl_backup = add_extension fl_po backup_ext in cp [ fl_po ] fl_pot; GettextCompile.merge fl_pot [ fl_po ] backup_ext; ( match cmp fl_po fl_po with | Some -1 -> assert_failure (fl_po ^ " or " ^ fl_po ^ " doesn't exist") | Some _ -> assert_failure (fl_po ^ " differs from " ^ fl_po) | None -> () ); match cmp fl_po fl_backup with | Some -1 -> assert_failure (fl_po ^ " or " ^ fl_backup ^ " doesn't exist") | Some _ -> assert_failure (fl_po ^ " differs from " ^ fl_backup) | None -> () with x -> assert_failure ( "Unexpected error while processing " ^ fl_po ^ " ( " ^ Printexc.to_string x ^ " )" ) ); ] in "POT/PO file merge test" >::: List.map merge_one [ ( "test4.pot", "test4.po", "bak" ); ] (**********************************) (* Test for PO processing comment *) (**********************************) let po_process_test = let copy_merge_compare fn_po = let src_po = make_filename [ current_dir; fn_po ] in let tgt_po = make_filename [ current_dir; fn_po ] in GettextCompile.merge tgt_po [ tgt_po ] "bak"; match cmp tgt_po src_po with | Some -1 -> assert_failure (tgt_po ^ " or " ^ src_po ^ " doesn't exist") | Some _ -> assert_failure (tgt_po ^ " differs from " ^ src_po) | None -> () in "Gettext po process test" >::: [ ("multiline-comment.po" >:: fun ctxt -> let tests = make_tests ctxt in copy_merge_compare (concat tests.test_dir "multiline-comment.po") ); ("utf8-fr.po" >:: fun ctxt -> let tests = make_tests ctxt in copy_merge_compare (concat tests.test_dir "utf8-fr.po") ); ("utf8-ja.po" >:: fun ctxt -> let tests = make_tests ctxt in copy_merge_compare (concat tests.test_dir "utf8-ja.po") ); ] (********************************************) (* Test for running ocaml-gettext program *) (* (spot also problem with runtime behavior *) (* of ocaml-gettext library) *) (********************************************) let run_ocaml_gettext = "Running ocaml-gettext" >::: [ ( "ocaml-gettext with LC_ALL and LANG unset" >:: fun ctxt -> let tests = make_tests ctxt in assert_command ~ctxt tests.ocaml_gettext [ "--help" ]) ] (******************) (* Try to compile *) (******************) let compile_ocaml = "Compile OCaml code" >::: List.map (fun (bn, exp_return_code, exp_err) -> bn >:: fun ctxt -> let tests = make_tests ctxt in let opt_options = let major, minor = Scanf.sscanf Sys.ocaml_version "%d.%d.%d" (fun x y _ -> (x, y)) in if (major, minor) >= (4, 3) then ["-color"; "never"] else [] in let out = Buffer.create 13 in let capture_out strm = Stream.iter (Buffer.add_char out) strm in let match_exp_err = Str.regexp (".*"^(Str.quote exp_err)^".*") in assert_command ~exit_code:(Unix.WEXITED exp_return_code) ~use_stderr:true ~foutput:capture_out ~ctxt "ocamlc" (opt_options @ [ "-c"; "-I"; make_filename [Filename.parent_dir_name; "src"; "lib"; "gettext"; "base"; ".gettextBase.objs"; "byte"]; "-I"; tests.test_dir; Filename.concat tests.test_dir "TestGettext.ml"; Filename.concat tests.test_dir bn; ]); FileUtil.rm (List.map (FilePath.replace_extension bn) [ "cmo"; "cmi" ]); FileUtil.rm (List.map (FilePath.add_extension "TestGettext") [ "cmo"; "cmi" ]); assert_bool (Printf.sprintf "error output:\nwant to contain: %S\ngot:\n%s" exp_err (Buffer.contents out)) (Str.string_match match_exp_err (Buffer.contents out) 0)) [ ("unsound_warning.ml", 0, ""); ("valid_format.ml", 0, ""); ("invalid_format1.ml", 2, "line 4, characters 28-29:"); ("invalid_format2.ml", 2, "line 4, characters 28-29:"); ("invalid_format3.ml", 2, "line 4, characters 27-28:"); ("invalid_format4.ml", 2, "line 4, characters 27-28:"); ("invalid_format5.ml", 2, "line 4, characters 36-52:"); ] (*********************) (* Main test routine *) (*********************) let () = run_test_tt_main ("Test ocaml-gettext" >::: [ format_test; split_plural_test; po_test; extract_test; install_test; po_process_test; merge_test; run_ocaml_gettext; compile_ocaml; ]) ocaml-gettext-0.4.2/test/testdata/000077500000000000000000000000001367051331200170635ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/testdata/TestGettext.ml000066400000000000000000000002111367051331200216730ustar00rootroot00000000000000include Gettext.Library (struct let textdomain = "ocaml-gettext" let codeset = None let dir = None let dependencies = [] end) ocaml-gettext-0.4.2/test/testdata/escape-char.ml000066400000000000000000000001721367051331200215700ustar00rootroot00000000000000let _ = [ s_ "hello world!\n"; s_ "goodbye world!\n"; s_ "goodby world 2!"; s_ "and then\tbye-bye"; ] ocaml-gettext-0.4.2/test/testdata/fr_FR/000077500000000000000000000000001367051331200200615ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/000077500000000000000000000000001367051331200216465ustar00rootroot00000000000000ocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/test1.mo000066400000000000000000000005031367051331200232410ustar00rootroot00000000000000<\\]*sW1@%s is replaced by %s.'Your command, please?', asked the waiter.heyContent-Type: text/plain; charset=ISO-8859-1 Plural-Forms: nplurals=2; plural=(n > 1); %2$s remplace %1$s.Votre commande, s'il vous plait, dit le garon.hocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/test10.mo000066400000000000000000000005031367051331200233210ustar00rootroot00000000000000<\\]*sW1@%s is replaced by %s.'Your command, please?', asked the waiter.heyContent-Type: text/plain; charset=ISO-8859-1 Plural-Forms: nplurals=2; plural=(n > 1); %2$s remplace %1$s.Votre commande, s'il vous plait, dit le garon.hocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/test11.mo000066400000000000000000000005271367051331200233300ustar00rootroot00000000000000<\pq*W1"T%s is replaced by %s.'Your command, please?', asked the waiter.heyContent-Type: text/plain; charset=ISO-8859-1 Plural-Forms: nplurals=2; plural=(n > 1); %2$s remplace %1$s.Votre commande, s'il vous plait, dit le garon.hocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/test2.mo000066400000000000000000000005751367051331200232530ustar00rootroot00000000000000Dllm*W#41Hz%d coffeemore %d coffee%s is replaced by %s.'Your command, please?', asked the waiter.heyContent-Type: text/plain; charset=ISO-8859-1 Plural-Forms: nplurals=2; plural=(n > 1); %d caf%d cafs%2$s remplace %1$s.Votre commande, s'il vous plait, dit le garon.hocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/test3.mo000066400000000000000000000002051367051331200232420ustar00rootroot00000000000000$,,W-Content-Type: text/plain; charset=ISO-8859-1 Plural-Forms: nplurals=2; plural=(n > 1); ocaml-gettext-0.4.2/test/testdata/fr_FR/LC_MESSAGES/test4.mo000066400000000000000000000051021367051331200232440ustar00rootroot00000000000000llm?=?/?o??F/U/#!'? a!__MMHMMK?^AA MN  K A GettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralGettextCompat.gettextGettextCompat.ngettext singularGettextCompat.ngettext pluralTestGettext.Library.f_TestGettext.Library.fn_ singularTestGettext.Library.fn_ pluralTestGettext.Library.sn_ singularTestGettext.Library.sn_ pluralTestGettext.Program.f_TestGettext.Program.fn_ singularTestGettext.Program.fn_ pluralTestGettext.Program.sn_ singularTestGettext.Program.sn_ pluralTestGettext.f_TestGettext.fn_ singularTestGettext.fn_ pluralTestGettext.sn_ singularTestGettext.sn_ pluralf_fgettextfn_ singularfn_ pluralfngettext singularfngettext pluralgettextngettext singularngettext pluralsn_ singularsn_ pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Fonction de compatibil fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )Fonction de compatibilit gettextFonction de compatibilit ngettext ( singulier )Fonction de compatibilit ngettext ( pluriel )Fonction de librairie f_Fonction de librairie fn_ ( singulier )Fonction de librairie fn_ ( pluriel )Fonction de librairie sn_ ( singulier )Fonction de librairie sn_ ( pluriel )Fonction de programme f_Fonction de programme fn_ ( singulier )Fonction de programme fn_ ( pluriel )Fonction de programme sn_ ( singulier )Fonction de programme sn_ ( pluriel )Fonction alias f_Fonction alias f_ ( singulier )Fonction alias f_ ( pluriel )Fonction alias sn_ ( singulier )Fonction alias sn_ ( pluriel )Fonction simple f_Fonction simple fgettextFonction simple fn_ ( singulier )Fonction simple fn_ ( pluriel )Fonction simple fngettext ( singulier )Fonction simple fngettext ( pluriel )Fonction simple gettextFonction simple ngettext ( singulier )Fonction simple ngettext ( pluriel )Fonction simple sn_ ( singulier )Fonction simple sn_ ( pluriel )ocaml-gettext-0.4.2/test/testdata/invalid_format1.ml000066400000000000000000000000741367051331200224750ustar00rootroot00000000000000open TestGettext open Printf let () = eprintf (f_ "%ld") 2 ocaml-gettext-0.4.2/test/testdata/invalid_format2.ml000066400000000000000000000000741367051331200224760ustar00rootroot00000000000000open TestGettext open Printf let () = eprintf (f_ "%Ld") 2 ocaml-gettext-0.4.2/test/testdata/invalid_format3.ml000066400000000000000000000000731367051331200224760ustar00rootroot00000000000000open TestGettext open Printf let () = eprintf (f_ "%s") 2 ocaml-gettext-0.4.2/test/testdata/invalid_format4.ml000066400000000000000000000000731367051331200224770ustar00rootroot00000000000000open TestGettext open Printf let () = eprintf (f_ "%b") 2 ocaml-gettext-0.4.2/test/testdata/invalid_format5.ml000066400000000000000000000001301367051331200224720ustar00rootroot00000000000000open TestGettext open Printf let () = eprintf (fn_ "%d category" "%Ld categories" 1) 1 ocaml-gettext-0.4.2/test/testdata/multiline-comment.po000066400000000000000000000010221367051331200230600ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: oji 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2005-05-27 02:37+0200\n" "PO-Revision-Date: 2005-05-27 02:39+0200\n" "Last-Translator: French \n" "Language-Team: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;" #: ../dlg_test.ml:83 ../dlg_config.ml:126 ../dlg_browser.ml:76 #. ../dlg_editor.ml:70 msgid "vocabulary" msgstr "vocabulaire" ocaml-gettext-0.4.2/test/testdata/test1.po000066400000000000000000000005331367051331200204640ustar00rootroot00000000000000msgid "" msgstr "" "Content-Type: text/plain; charset=ISO-8859-1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "'Your command, please?', asked the waiter." msgstr "Votre commande, s'il vous plait, dit le garon." # Reverse the arguments. #, c-format msgid "%s is replaced by %s." msgstr "%2$s remplace %1$s." msgid "hey" msgstr "h" ocaml-gettext-0.4.2/test/testdata/test10.mo000066400000000000000000000013231367051331200205370ustar00rootroot000000000000004LLM?d"NaqGettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=INTEGER; plural=EXPRESSION; Fonction de compatibilit fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )ocaml-gettext-0.4.2/test/testdata/test11.po000066400000000000000000000744521367051331200205600ustar00rootroot00000000000000# translation of virt-top.tip.ja.po to Japanese # Kiyoto Hashida , 2008. msgid "" msgstr "" "Project-Id-Version: virt-top.tip.ja\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-03-28 17:30+0000\n" "PO-Revision-Date: 2008-10-21 08:20+1000\n" "Last-Translator: Kiyoto Hashida \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: KBabel 1.11.4\n" #: ../virt-top/virt_top.ml:1490 msgid "# .virt-toprc virt-top configuration file\\n" msgstr "# .virt-toprc virt-top 設定ファイル\\n" #: ../virt-top/virt_top.ml:1508 msgid "# Enable CSV output to the named file\\n" msgstr "# 指定ファイルへの CSV 出力を有効にする\\n" #: ../virt-top/virt_top.ml:1511 msgid "# To protect this file from being overwritten, uncomment next line\\n" msgstr "# このファイルが上書きされるのを防止するには、次の行をアンコメントします\\n" #: ../virt-top/virt_top.ml:1505 msgid "# To send debug and error messages to a file, uncomment next line\\n" msgstr "# デバグとエラーのメッセージをファイルに送信するには、次の行をアンコメントします\\n" #: ../virt-top/virt_top.ml:1491 msgid "# generated on %s by %s\\n" msgstr "# %s によって %s 上で生成\\n" #: ../virt-top/virt_top.ml:63 msgid "%CPU" msgstr "%CPU" #: ../virt-top/virt_top.ml:64 msgid "%MEM" msgstr "%MEM" #: ../virt-top/virt_top.ml:1144 msgid "" "%d domains, %d active, %d running, %d sleeping, %d paused, %d inactive D:%d " "O:%d X:%d" msgstr "" "%d domains, %d active, %d running, %d sleeping, %d paused, %d inactive D:%d " "O:%d X:%d" #: ../mlvirsh/mlvirsh.ml:716 msgid "%s: command not found" msgstr "%s: コマンドが見つかりません" #: ../virt-top/virt_top.ml:105 msgid "%s: display should be %s" msgstr "%s: 表示は %s となるべきです" #: ../virt-top/virt_top.ml:82 msgid "%s: sort order should be: %s" msgstr "%s: 分類順は次のようになるべきです: %s" #: ../virt-df/virt_df.ml:362 ../virt-top/virt_top.ml:202 msgid "%s: unknown parameter" msgstr "%s: 不明なパラメータ" #: ../virt-top/virt_top.ml:233 msgid "%s:%d: configuration item ``%s'' ignored\\n%!" msgstr "%s:%d: 設定項目 ``%s'' 無視されました\\n%!" #: ../virt-df/virt_df.ml:514 msgid "(device omitted)" msgstr "(デバイス欠落)" #: ../virt-top/virt_top.ml:145 msgid "-d: cannot set a negative delay" msgstr "-d: ネガティブな遅延は設定できません" #: ../virt-df/virt_df.ml:498 msgid "1K-blocks" msgstr "1K-ブロック" #: ../virt-ctrl/vc_mainwindow.ml:97 msgid "About ..." msgstr "情報 ..." #: ../mlvirsh/mlvirsh.ml:399 msgid "Attach device to domain." msgstr "ドメインにデバイスを添付" #: ../virt-df/virt_df.ml:499 ../virt-df/virt_df.ml:498 msgid "Available" msgstr "利用可能" #: ../virt-top/virt_top.ml:167 msgid "Batch mode" msgstr "バッチモード" #: ../virt-top/virt_top.ml:70 msgid "Block read reqs" msgstr "読み込み要求を阻止する" #: ../virt-top/virt_top.ml:71 msgid "Block write reqs" msgstr "書き込み要求を阻止する" #: ../virt-ctrl/vc_connections.ml:408 msgid "CPU" msgstr "CPU" #: ../mlvirsh/mlvirsh.ml:365 msgid "CPU affinity" msgstr "CPU アフィニティ" #: ../virt-top/virt_top.ml:1151 msgid "CPU: %2.1f%% Mem: %Ld MB (%Ld MB by guests)" msgstr "CPU: %2.1f%% Mem: %Ld MB (ゲストによる %Ld MB)" #: ../virt-ctrl/vc_connection_dlg.ml:182 msgid "Cancel" msgstr "取消し" #: ../virt-top/virt_top.ml:1319 msgid "Change delay from %.1f to: " msgstr "遅延を %.1f から次へ変更する: " #: ../mlvirsh/mlvirsh.ml:409 msgid "Close an existing hypervisor connection." msgstr "既存のハイパーバイザー接続を閉じる" #: ../virt-ctrl/vc_mainwindow.ml:118 msgid "Connect ..." msgstr "接続 ..." #: ../virt-ctrl/vc_mainwindow.ml:160 msgid "Connect to ..." msgstr "次へ接続 ..." #: ../virt-df/virt_df.ml:348 ../virt-df/virt_df.ml:346 #: ../virt-top/virt_top.ml:171 ../virt-top/virt_top.ml:169 msgid "Connect to URI (default: Xen)" msgstr "URI (デフォルト : Xen)へ接続" #: ../virt-top/virt_top.ml:1558 msgid "Connect: %s; Hostname: %s" msgstr "接続 : %s; ホスト名 : %s" #: ../mlvirsh/mlvirsh.ml:476 msgid "Core dump a domain to a file for analysis." msgstr "解析の為にドメインをファイルにコアダンプする。" #: ../mlvirsh/mlvirsh.ml:422 msgid "Create a domain from an XML file." msgstr "XML ファイルからドメインを作成する。" #: ../mlvirsh/mlvirsh.ml:534 msgid "Create a network from an XML file." msgstr "XML ファイルからネットワークを作成する" #: ../virt-top/virt_top.ml:1596 msgid "DISPLAY MODES" msgstr "表示モード" #: ../mlvirsh/mlvirsh.ml:426 msgid "Define (but don't start) a domain from an XML file." msgstr "XML ファイルからドメインを(起動せずに)定義する" #: ../mlvirsh/mlvirsh.ml:538 msgid "Define (but don't start) a network from an XML file." msgstr "XML ファイルからネットワークを(起動せずに)定義する" #: ../virt-top/virt_top.ml:1326 msgid "Delay must be > 0" msgstr "遅延はゼロよりも大きい値でなければなりません" #: ../virt-top/virt_top.ml:181 msgid "Delay time interval (seconds)" msgstr "遅延時間間隔(秒)" #: ../virt-top/virt_top.ml:1552 msgid "Delay: %.1f secs; Batch: %s; Secure: %s; Sort: %s" msgstr "遅延: %.1f 秒; バッチ: %s; セキュア: %s; 分類: %s" #: ../mlvirsh/mlvirsh.ml:433 msgid "Destroy a domain." msgstr "ドメインを破壊する" #: ../mlvirsh/mlvirsh.ml:541 msgid "Destroy a network." msgstr "ネットワークを破壊する" #: ../mlvirsh/mlvirsh.ml:430 msgid "Detach device from domain." msgstr "デバイスをドメインから分離する" #: ../virt-ctrl/vc_mainwindow.ml:123 msgid "Details" msgstr "詳細" #: ../virt-top/virt_top.ml:175 msgid "Disable CPU stats in CSV" msgstr "CSV 内の CPU 統計を無効にする" #: ../virt-top/virt_top.ml:177 msgid "Disable block device stats in CSV" msgstr "CSV 内のブロックデバイス統計を無効にする" #: ../virt-top/virt_top.ml:179 msgid "Disable net stats in CSV" msgstr "CSV 内のネット統計を無効にする" #: ../mlvirsh/mlvirsh.ml:493 msgid "Display free memory for machine, NUMA cell or range of cells" msgstr "マシン、NUMA セル、あるいはセルの範囲用の空きメモリーを表示する" #: ../mlvirsh/mlvirsh.ml:437 msgid "Display the block device statistics for a domain." msgstr "ドメインのブロックデバイス統計を表示する" #: ../mlvirsh/mlvirsh.ml:444 msgid "Display the network interface statistics for a domain." msgstr "ドメインのネットワークインターフェイス統計を表示する" #: ../virt-df/virt_df.ml:358 msgid "Display version and exit" msgstr "バージョンを表示して終了する" #: ../virt-top/virt_top.ml:191 msgid "Do not read init file" msgstr "init ファイルを読み込まない" #: ../virt-top/virt_top.ml:66 msgid "Domain ID" msgstr "ドメイン ID" #: ../virt-top/virt_top.ml:67 msgid "Domain name" msgstr "ドメイン名" #: ../virt-top/virt_top.ml:1610 msgid "Domains display" msgstr "ドメイン表示" #: ../virt-ctrl/vc_mainwindow.ml:61 ../virt-top/virt_top_main.ml:47 #: ../virt-top/virt_top.ml:1528 msgid "Error" msgstr "エラー" #: ../virt-top/virt_top.ml:185 msgid "Exit at given time" msgstr "任意の時点で終了" #: ../virt-ctrl/vc_mainwindow.ml:79 msgid "File" msgstr "ファイル" #: ../virt-df/virt_df.ml:502 msgid "Filesystem" msgstr "ファイルシステム" #: ../mlvirsh/mlvirsh.ml:606 msgid "Get the current scheduler parameters for a domain." msgstr "ドメインの現在のスケジューラパラメータを取得する" #: ../mlvirsh/mlvirsh.ml:623 msgid "Get the scheduler type." msgstr "スケジューラタイプを取得する" #: ../mlvirsh/mlvirsh.ml:635 msgid "Gracefully shutdown a domain." msgstr "優しくドメインをシャットダウンする" #: ../virt-ctrl/vc_mainwindow.ml:96 ../virt-ctrl/vc_mainwindow.ml:80 #: ../virt-top/virt_top.ml:1580 msgid "Help" msgstr "ヘルプ" #: ../virt-top/virt_top.ml:187 msgid "Historical CPU delay" msgstr "歴史的 CPU の遅延" #: ../mlvirsh/mlvirsh.ml:35 msgid "Hypervisor connection URI" msgstr "ハイパバイザー接続 URI" #: ../virt-ctrl/vc_connections.ml:405 msgid "ID" msgstr "ID" #: ../virt-df/virt_df.ml:500 msgid "IFree" msgstr "IFree" #: ../virt-df/virt_df.ml:500 msgid "IUse" msgstr "IUse" #: ../virt-df/virt_df.ml:500 msgid "Inodes" msgstr "Inodes" #: ../virt-df/virt_df_lvm2.ml:33 msgid "LVM2 not supported yet" msgstr "LVM2 はまだサポートされていません" #: ../virt-df/virt_df_ext2.ml:82 msgid "Linux ext2/3" msgstr "Linux ext2/3" #: ../virt-df/virt_df_linux_swap.ml:33 msgid "Linux swap" msgstr "Linux swap" #: ../mlvirsh/mlvirsh.ml:557 msgid "List the active networks." msgstr "アクティブなネットワークを一覧表示する" #: ../mlvirsh/mlvirsh.ml:565 msgid "List the defined but inactive networks." msgstr "定義すみでアクティブでないネットワークを一覧表示する" #: ../mlvirsh/mlvirsh.ml:516 msgid "List the defined but not running domains." msgstr "定義済で実行していないドメインを一覧表示する" #: ../mlvirsh/mlvirsh.ml:508 msgid "List the running domains." msgstr "実行中のドメインを一覧表示する" #: ../virt-ctrl/vc_mainwindow.ml:158 msgid "Local QEMU/KVM" msgstr "ローカル QEMU/KVM" #: ../virt-ctrl/vc_mainwindow.ml:157 msgid "Local Xen" msgstr "ローカル Xen" #: ../virt-ctrl/vc_connection_dlg.ml:93 msgid "Local network" msgstr "ローカルネットワーク" #: ../virt-top/virt_top.ml:173 msgid "Log statistics to CSV file" msgstr "CSV ファイルへのログ統計" #: ../virt-top/virt_top.ml:1563 msgid "MAIN KEYS" msgstr "主要キー" #: ../virt-ctrl/vc_connections.ml:409 msgid "Memory" msgstr "メモリー" #: ../virt-top/virt_top.ml:1617 msgid "More help in virt-top(1) man page. Press any key to return." msgstr "virt-top(1) man ページには他のヘルプがあります。どれかのキーを押すと戻ります" #: ../virt-df/virt_df.ml:382 ../virt-top/virt_top.ml:258 msgid "" "NB: If you want to monitor a local Xen hypervisor, you usually need to be " "root" msgstr "" "NB: ローカル Xen ハイパバイザーをモニターしたい場合は、通常 root になる必要が " "あります" #: ../virt-ctrl/vc_connections.ml:406 msgid "Name" msgstr "名前" #: ../virt-top/virt_top.ml:68 msgid "Net RX bytes" msgstr "ネット RX バイト" #: ../virt-top/virt_top.ml:69 msgid "Net TX bytes" msgstr "ネット TX バイト" #: ../virt-top/virt_top.ml:1332 msgid "Not a valid number" msgstr "有効な数ではありません" #: ../virt-top/virt_top.ml:193 msgid "Number of iterations to run" msgstr "繰り返し実行する回数" #: ../virt-ctrl/vc_connection_dlg.ml:170 ../virt-ctrl/vc_connection_dlg.ml:137 msgid "Open" msgstr "開く" #: ../mlvirsh/mlvirsh.ml:418 msgid "Open a new hypervisor connection." msgstr "新規ハイパバイザー接続を開く" #: ../virt-ctrl/vc_mainwindow.ml:86 msgid "Open connection ..." msgstr "接続を開く ..." #: ../virt-ctrl/vc_connection_dlg.ml:40 msgid "Open connection to hypervisor" msgstr "ハイパバイザーへの接続を開く" #: ../virt-ctrl/vc_mainwindow.ml:130 msgid "Pause" msgstr "一時停止" #: ../mlvirsh/mlvirsh.ml:670 ../mlvirsh/mlvirsh.ml:666 msgid "Pin domain VCPU to a list of physical CPUs." msgstr "ドメイン VCPU を物理 CPU の一覧に固定する" #: ../mlvirsh/mlvirsh.ml:706 msgid "Print list of commands or full description of one command." msgstr "コマンドの一覧、又は1つのコマンドの完全な説明を表示" #: ../mlvirsh/mlvirsh.ml:584 msgid "Print node information." msgstr "ノード情報を表示" #: ../virt-df/virt_df.ml:352 ../virt-df/virt_df.ml:350 msgid "Print sizes in human-readable format" msgstr "可読形式でサイズを表示" #: ../mlvirsh/mlvirsh.ml:440 msgid "Print the ID of a domain." msgstr "ドメインの ID を表示" #: ../mlvirsh/mlvirsh.ml:464 msgid "Print the OS type of a domain." msgstr "ドメインの OS タイプを表示" #: ../mlvirsh/mlvirsh.ml:472 msgid "Print the UUID of a domain." msgstr "ドメインの UUID を表示" #: ../mlvirsh/mlvirsh.ml:581 msgid "Print the UUID of a network." msgstr "ネットワークの UUID を表示" #: ../mlvirsh/mlvirsh.ml:480 msgid "Print the XML description of a domain." msgstr "ドメインの XML 記述を表示" #: ../mlvirsh/mlvirsh.ml:545 msgid "Print the XML description of a network." msgstr "ネットワークの XML 記述を表示" #: ../mlvirsh/mlvirsh.ml:530 msgid "Print the bridge name of a network." msgstr "ネットワークのブリッジ名を表示" #: ../mlvirsh/mlvirsh.ml:653 msgid "Print the canonical URI." msgstr "正規の URI を表示" #: ../mlvirsh/mlvirsh.ml:448 msgid "Print the domain info." msgstr "ドメイン情報を表示" #: ../mlvirsh/mlvirsh.ml:468 msgid "Print the domain state." msgstr "ドメインの状態を表示" #: ../mlvirsh/mlvirsh.ml:646 msgid "Print the driver name" msgstr "ドライバー名を表示" #: ../mlvirsh/mlvirsh.ml:677 msgid "Print the driver version" msgstr "ドライバーのバージョンを表示" #: ../mlvirsh/mlvirsh.ml:500 msgid "Print the hostname." msgstr "ホスト名を表示" #: ../mlvirsh/mlvirsh.ml:522 msgid "Print the max VCPUs available." msgstr "使用可能な最大 VCPU を表示" #: ../mlvirsh/mlvirsh.ml:456 msgid "Print the max VCPUs of a domain." msgstr "ドメインの最大 VCPU を表示" #: ../mlvirsh/mlvirsh.ml:452 msgid "Print the max memory (in kilobytes) of a domain." msgstr "ドメインの最大メモリーを(キロバイトで)表示" #: ../mlvirsh/mlvirsh.ml:460 msgid "Print the name of a domain." msgstr "ドメインの名前を表示" #: ../mlvirsh/mlvirsh.ml:569 msgid "Print the name of a network." msgstr "ネットワークの名前を表示" #: ../mlvirsh/mlvirsh.ml:497 msgid "Print whether a domain autostarts at boot." msgstr "起動時にドメインが自動開始するかどうか表示" #: ../mlvirsh/mlvirsh.ml:549 msgid "Print whether a network autostarts at boot." msgstr "起動時にネットワークが自動開始するかどうか表示" #: ../virt-ctrl/vc_connection_dlg.ml:83 msgid "QEMU or KVM" msgstr "QEMU 又は KVM" #: ../virt-ctrl/vc_mainwindow.ml:89 ../virt-top/virt_top.ml:1578 msgid "Quit" msgstr "終了" #: ../mlvirsh/mlvirsh.ml:519 msgid "Quit the interactive terminal." msgstr "対話式の端末で終了" #: ../mlvirsh/mlvirsh.ml:36 msgid "Read-only connection" msgstr "読み込み専用接続" #: ../mlvirsh/mlvirsh.ml:587 msgid "Reboot a domain." msgstr "ドメインを再起動" #: ../virt-ctrl/vc_connection_dlg.ml:134 msgid "Refresh" msgstr "リフレッシュ" #: ../mlvirsh/mlvirsh.ml:592 msgid "Restore a domain from the named file." msgstr "指定ファイルからドメインを復元" #: ../virt-ctrl/vc_mainwindow.ml:133 msgid "Resume" msgstr "復帰" #: ../mlvirsh/mlvirsh.ml:595 msgid "Resume a domain." msgstr "ドメインを復帰" #: ../mlvirsh/mlvirsh.ml:406 msgid "Returns capabilities of hypervisor/driver." msgstr "ハイパバイザーの戻り機能" #: ../virt-top/virt_top.ml:199 msgid "Run from a script (no user interface)" msgstr "スクリプトから実行(ユーザーインターフェイスなし)" #: ../virt-top/virt_top.ml:1584 msgid "SORTING" msgstr "分類" #: ../mlvirsh/mlvirsh.ml:599 msgid "Save a domain to a file." msgstr "ファイルにドメインを保存" #: ../virt-top/virt_top.ml:197 msgid "Secure (\\\"kiosk\\\") mode" msgstr "セキュア (\\\"kiosk\\\") モード" #: ../virt-top/virt_top.ml:1593 msgid "Select sort field" msgstr "分類フィールドを選択" #: ../virt-top/virt_top.ml:183 msgid "Send debug messages to file" msgstr "デバッグメッセージをファイルに送信" #: ../virt-top/virt_top.ml:189 msgid "Set name of init file" msgstr "init ファイルの名前を設定する" #: ../virt-top/virt_top.ml:195 msgid "Set sort order (%s)" msgstr "分類順 (%s) を設定する" #: ../virt-top/virt_top.ml:1340 msgid "Set sort order for main display" msgstr "ドメイン表示の分類順を設定する" #: ../mlvirsh/mlvirsh.ml:631 msgid "Set the maximum memory used by the domain (in kilobytes)." msgstr "ドメインにより使用される最大メモリー(キロバイト)を設定する" #: ../mlvirsh/mlvirsh.ml:627 msgid "Set the memory used by the domain (in kilobytes)." msgstr "ドメインにより使用されるメモリー(キロバイト)を設定する" #: ../mlvirsh/mlvirsh.ml:674 msgid "Set the number of virtual CPUs assigned to a domain." msgstr "ドメインに割り当てる CPU の数を設定する" #: ../mlvirsh/mlvirsh.ml:618 msgid "Set the scheduler parameters for a domain." msgstr "ドメイン用のスケジューラパラメータを設定する" #: ../virt-top/virt_top.ml:1579 msgid "Set update interval" msgstr "更新の間隔を設定する" #: ../mlvirsh/mlvirsh.ml:403 msgid "Set whether a domain autostarts at boot." msgstr "起動時にドメインが自動開始するかどうか設定する" #: ../mlvirsh/mlvirsh.ml:526 msgid "Set whether a network autostarts at boot." msgstr "起動時にネットワークが自動開始するかどうか設定する" #: ../virt-df/virt_df.ml:344 ../virt-df/virt_df.ml:342 msgid "Show all domains (default: only active domains)" msgstr "全てのドメインを表示(デフォルト: アクティブドメインのみ)" #: ../virt-df/virt_df.ml:356 ../virt-df/virt_df.ml:354 msgid "Show inodes instead of blocks" msgstr "ブロックではなくアイノードを表示" #: ../virt-ctrl/vc_mainwindow.ml:137 msgid "Shutdown" msgstr "シャットダウン" #: ../virt-df/virt_df.ml:499 msgid "Size" msgstr "サイズ" #: ../virt-top/virt_top.ml:1589 msgid "Sort by %CPU" msgstr "%CPU で分類" #: ../virt-top/virt_top.ml:1590 msgid "Sort by %MEM" msgstr "%MEM で分類" #: ../virt-top/virt_top.ml:1592 msgid "Sort by ID" msgstr "ID で分類" #: ../virt-top/virt_top.ml:1591 msgid "Sort by TIME" msgstr "時間で分類" #: ../virt-ctrl/vc_mainwindow.ml:127 msgid "Start" msgstr "開始" #: ../mlvirsh/mlvirsh.ml:639 msgid "Start a previously defined inactive domain." msgstr "以前に停止中と定義したドメインを開始" #: ../mlvirsh/mlvirsh.ml:573 msgid "Start a previously defined inactive network." msgstr "以前に停止中と定義したネットワークを開始" #: ../virt-top/virt_top.ml:165 msgid "Start by displaying block devices" msgstr "ブロックデバイスの表示で開始" #: ../virt-top/virt_top.ml:163 msgid "Start by displaying network interfaces" msgstr "ネットワークインターフェイスの表示で開始" #: ../virt-top/virt_top.ml:161 msgid "Start by displaying pCPUs (default: tasks)" msgstr "pCPU の表示で開始(デフォルト: タスク)" #: ../virt-ctrl/vc_connections.ml:407 msgid "Status" msgstr "ステータス" #: ../mlvirsh/mlvirsh.ml:643 msgid "Suspend a domain." msgstr "ドメインをサスペンド" #: ../mlvirsh/mlvirsh.ml:40 msgid "" "Synopsis:\n" " %s [options] [command]\n" "\n" "List of all commands:\n" " %s help\n" "\n" "Full description of a single command:\n" " %s help command\n" "\n" "Options:" msgstr "" "シノプシス:\n" " %s [options] [command]\n" "\n" "全コマンドの一覧:\n" " %s help\n" "\n" "単独コマンドの完全説明:\n" " %s help command\n" "\n" "オプション群:" #: ../virt-top/virt_top.ml:65 msgid "TIME (CPU time)" msgstr "時間(CPU 時間)" #: ../virt-ctrl/vc_connection_dlg.ml:62 msgid "This machine" msgstr "このマシン" #: ../virt-top/virt_top.ml:1613 msgid "Toggle block devices" msgstr "ブロックデバイスの切り替え" #: ../virt-top/virt_top.ml:1612 msgid "Toggle network interfaces" msgstr "ネットワークインターフェイスの切り替え" #: ../virt-top/virt_top.ml:1611 msgid "Toggle physical CPUs" msgstr "物理 CPU の切り替え" #: ../virt-df/virt_df.ml:502 msgid "Type" msgstr "タイプ" #: ../virt-top/virt_top.ml:1341 msgid "Type key or use up and down cursor keys." msgstr "キーをタイプするか、又は上下カーソルキーを使用" #: ../virt-ctrl/vc_connection_dlg.ml:160 msgid "URI connection" msgstr "URI 接続" #: ../mlvirsh/mlvirsh.ml:650 msgid "Undefine an inactive domain." msgstr "停止中のドメインを定義解除" #: ../mlvirsh/mlvirsh.ml:577 msgid "Undefine an inactive network." msgstr "停止中のネットワークを定義解除" #: ../virt-top/virt_top.ml:1622 msgid "Unknown command - try 'h' for help" msgstr "不明なコマンド - 'h' を使用してヘルプ参照 " #: ../virt-top/virt_top.ml:1577 msgid "Update display" msgstr "表示を更新" #: ../mlvirsh/mlvirsh.ml:690 msgid "Use '%s help command' for help on a command." msgstr "'%s help コマンドを使用してコマンドのヘルプを参照" #: ../virt-df/virt_df.ml:499 ../virt-df/virt_df.ml:498 msgid "Used" msgstr "使用中" #: ../virt-ctrl/vc_mainwindow.ml:23 msgid "Virtual Control" msgstr "仮想制御" #: ../virt-ctrl/vc_mainwindow.ml:53 msgid "Virtualisation error" msgstr "仮想化エラー" #: ../virt-ctrl/vc_mainwindow.ml:39 msgid "" "Virtualization control tool (virt-ctrl) by\n" "Richard W.M. Jones (rjones@redhat.com).\n" "\n" "Copyright %s 2007-2008 Red Hat Inc.\n" "\n" "Libvirt version: %s\n" "\n" "Gtk toolkit version: %s" msgstr "" "仮想化制御ツール (virt-ctrl) 製作者\n" "Richard W.M. Jones (rjones@redhat.com).\n" "\n" "Copyright %s 2007-2008 Red Hat Inc.\n" "\n" "Libvirt バージョン: %s\n" "\n" "Gtk toolkit バージョン: %s" #: ../virt-top/virt_top.ml:1523 msgid "Wrote settings to %s" msgstr "%s への設定を書き込み" #: ../virt-ctrl/vc_connection_dlg.ml:76 msgid "Xen hypervisor" msgstr "Xen ハイパバイザー" #: ../mlvirsh/mlvirsh.ml:364 msgid "\\tCPU time: %Ld ns\\n" msgstr "\\tCPU 時間: %Ld ns\\n" #: ../mlvirsh/mlvirsh.ml:362 msgid "\\tcurrent state: %s\\n" msgstr "\\tcurrent 状態: %s\\n" #: ../mlvirsh/mlvirsh.ml:361 msgid "\\ton physical CPU: %d\\n" msgstr "\\ton 物理 CPU: %d\\n" #: ../mlvirsh/mlvirsh.ml:298 ../mlvirsh/mlvirsh.ml:289 #: ../virt-ctrl/vc_helpers.ml:54 msgid "blocked" msgstr "阻止" #: ../mlvirsh/mlvirsh.ml:330 msgid "cores: %d\\n" msgstr "コア: %d\\n" #: ../mlvirsh/mlvirsh.ml:342 msgid "cpu_time: %Ld ns\\n" msgstr "cpu_time: %Ld ns\\n" #: ../mlvirsh/mlvirsh.ml:326 msgid "cpus: %d\\n" msgstr "cpus: %d\\n" #: ../mlvirsh/mlvirsh.ml:293 ../virt-ctrl/vc_helpers.ml:58 msgid "crashed" msgstr "クラッシュ" #: ../virt-df/virt_df.ml:236 msgid "detection of unpartitioned devices not yet supported" msgstr "未パーティションの検出はまだサポートがありません" #: ../mlvirsh/mlvirsh.ml:242 msgid "domain %s: not found. Additional info: %s" msgstr "ドメイン%s: 見つかりません。追加情報: %s" #: ../virt-df/virt_df_ext2.ml:39 msgid "error reading ext2/ext3 magic" msgstr "ext2/ext3 magic の読み込みでエラー" #: ../virt-df/virt_df.ml:182 msgid "error reading extended partition" msgstr "拡張パーティションの読み込みでエラー" #: ../virt-df/virt_df.ml:149 msgid "error reading partition table" msgstr "パーティションテーブルの読み込みでエラー" #: ../virt-ctrl/vc_dbus.ml:239 msgid "error set after getting System bus" msgstr "システムバスの取得後にエラー設定" #: ../mlvirsh/mlvirsh.ml:379 msgid "errors: %Ld\\n" msgstr "エラー: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:258 msgid "expected field value pairs, but got an odd number of arguments" msgstr "予期したフィールド値のペアですが、奇数の引数を受理しました" #: ../mlvirsh/mlvirsh.ml:610 msgid "expecting domain followed by field value pairs" msgstr "ドメインの後にフィールド値のペアを予期" #: ../mlvirsh/mlvirsh.ml:220 msgid "flag should be '%s'" msgstr "フラグは '%s' であるべきです" #: ../virt-df/virt_df.ml:419 ../virt-top/virt_top_xml.ml:46 msgid "get_xml_desc didn't return " msgstr "get_xml_desc は を返しませんでした" #: ../virt-df/virt_df.ml:427 msgid "get_xml_desc returned no node in XML" msgstr "get_xml_desc は XML で ノードを返しませんでした" #: ../virt-df/virt_df.ml:430 msgid "get_xml_desc returned strange node" msgstr "get_xml_desc は不思議な ノードを返しました" #: ../mlvirsh/mlvirsh.ml:700 msgid "help: %s: command not found" msgstr "ヘルプ: %s: コマンドが見つかりません" #: ../mlvirsh/mlvirsh.ml:188 ../mlvirsh/mlvirsh.ml:182 #: ../mlvirsh/mlvirsh.ml:177 ../mlvirsh/mlvirsh.ml:172 #: ../mlvirsh/mlvirsh.ml:168 ../mlvirsh/mlvirsh.ml:164 #: ../mlvirsh/mlvirsh.ml:160 msgid "incorrect number of arguments for function" msgstr "機能するには引数の数量が違います" #: ../mlvirsh/mlvirsh.ml:339 msgid "max_mem: %Ld K\\n" msgstr "max_mem: %Ld K\\n" #: ../mlvirsh/mlvirsh.ml:340 ../mlvirsh/mlvirsh.ml:325 msgid "memory: %Ld K\\n" msgstr "メモリー: %Ld K\\n" #: ../mlvirsh/mlvirsh.ml:327 msgid "mhz: %d\\n" msgstr "mhz: %d\\n" #: ../mlvirsh/mlvirsh.ml:727 msgid "mlvirsh" msgstr "mlvirsh" #: ../mlvirsh/mlvirsh.ml:725 msgid "mlvirsh(no connection)" msgstr "mlvirsh (無接続)" #: ../mlvirsh/mlvirsh.ml:726 msgid "mlvirsh(ro)" msgstr "mlvirsh(ro)" #: ../mlvirsh/mlvirsh.ml:324 msgid "model: %s\\n" msgstr "モデル: %s\\n " #: ../mlvirsh/mlvirsh.ml:253 msgid "network %s: not found. Additional info: %s" msgstr "ネットワーク %s: 見つかりません。追加情報: %s" #: ../mlvirsh/mlvirsh.ml:328 msgid "nodes: %d\\n" msgstr "ノード: %d\\n" #: ../mlvirsh/mlvirsh.ml:202 ../mlvirsh/mlvirsh.ml:197 msgid "not connected to the hypervisor" msgstr "ハイパバイザーに接続されていません" #: ../mlvirsh/mlvirsh.ml:341 msgid "nr_virt_cpu: %d\\n" msgstr "nr_virt_cpu: %d\\n" #: ../mlvirsh/mlvirsh.ml:296 msgid "offline" msgstr "オフライン" #: ../virt-df/virt_df_ext2.ml:42 msgid "partition marked EXT2/3 but no valid filesystem" msgstr "パーティションは EXT2/3 になっていますが、有効なファイルシステムではありません" #: ../mlvirsh/mlvirsh.ml:290 ../virt-ctrl/vc_helpers.ml:55 msgid "paused" msgstr "一時停止" #: ../virt-df/virt_df.ml:188 msgid "probe_extended_partition: internal error" msgstr "probe_extended_partition: 内部エラー" #: ../mlvirsh/mlvirsh.ml:376 msgid "read bytes: %Ld\\n" msgstr "バイトの読み込み: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:375 msgid "read requests: %Ld\\n" msgstr "要求の読み込み: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:297 ../mlvirsh/mlvirsh.ml:288 #: ../virt-ctrl/vc_helpers.ml:53 msgid "running" msgstr "実行中" #: ../mlvirsh/mlvirsh.ml:384 msgid "rx bytes: %Ld\\n" msgstr "rx バイト: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:387 msgid "rx dropped: %Ld\\n" msgstr "rx 却下: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:386 msgid "rx errs: %Ld\\n" msgstr "rx エラー: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:385 msgid "rx packets: %Ld\\n" msgstr "rx パケット: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:226 msgid "setting should be '%s' or '%s'" msgstr "設定は '%s'か '%s' になるべきです" #: ../mlvirsh/mlvirsh.ml:291 ../virt-ctrl/vc_helpers.ml:56 msgid "shutdown" msgstr "シャットダウン" #: ../mlvirsh/mlvirsh.ml:292 ../virt-ctrl/vc_helpers.ml:57 msgid "shutoff" msgstr "シャットオフ" #: ../mlvirsh/mlvirsh.ml:329 msgid "sockets: %d\\n" msgstr "ソケット: %d\\n" #: ../mlvirsh/mlvirsh.ml:338 msgid "state: %s\\n" msgstr "状態: %s\\n" #: ../mlvirsh/mlvirsh.ml:331 msgid "threads: %d\\n" msgstr "スレッド: %d\\n" #: ../mlvirsh/mlvirsh.ml:198 msgid "tried to do read-write operation on read-only hypervisor connection" msgstr "読み込み専用のハイパバイザー接続で読み込みと書き込みを試行しました" #: ../mlvirsh/mlvirsh.ml:388 msgid "tx bytes: %Ld\\n" msgstr "tx バイト: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:391 msgid "tx dropped: %Ld\\n" msgstr "tx 却下: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:390 msgid "tx errs: %Ld\\n" msgstr "tx エラー: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:389 msgid "tx packets: %Ld\\n" msgstr "tx パケット: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:287 ../virt-ctrl/vc_helpers.ml:52 msgid "unknown" msgstr "不明" #: ../virt-df/virt_df.ml:246 msgid "unsupported partition type %02x" msgstr "サポートされないパーティションタイプ %02x" #: ../virt-df/virt_df.ml:363 msgid "" "virt-df : like 'df', shows disk space used in guests\n" "\n" "SUMMARY\n" " virt-df [-options]\n" "\n" "OPTIONS" msgstr "" "virt-df : 'df' の様に, ゲスト内で使用されているディスク量を示します\n" "\n" "要約\n" " virt-df [-options]\n" "\n" "オプション" #: ../virt-top/virt_top.ml:1543 msgid "virt-top %s (libvirt %d.%d.%d) by Red Hat" msgstr "virt-top %s (libvirt %d.%d.%d) Red Hat 作" #: ../virt-top/virt_top.ml:203 msgid "" "virt-top : a 'top'-like utility for virtualization\n" "\n" "SUMMARY\n" " virt-top [-options]\n" "\n" "OPTIONS" msgstr "" "virt-top : 'top'-のようなユーティリティで仮想化用です\n" "\n" "要約\n" " virt-top [-options]\n" "\n" "オプション" #: ../virt-top/virt_top.ml:40 msgid "virt-top was compiled without support for CSV files" msgstr "virt-top は CSV ファイル用のサポートなしでコンパイルされています" #: ../virt-top/virt_top.ml:51 msgid "virt-top was compiled without support for dates and times" msgstr "virt-top は日付と時刻用のサポートなしでコンパイルされています" #: ../mlvirsh/mlvirsh.ml:360 msgid "virtual CPU: %d\\n" msgstr "仮想 CPU: %d\\n" #: ../virt-ctrl/vc_dbus.ml:219 msgid "warning: ignored unknown message %s from %s\\n%!" msgstr "警告: %s からの不明メッセージ %s を無視しました\\n%!" #: ../virt-ctrl/vc_dbus.ml:124 msgid "warning: unexpected message contents of Found signal" msgstr "警告: 予期しないメッセージが Found 信号を含んでいます" #: ../virt-ctrl/vc_dbus.ml:188 msgid "warning: unexpected message contents of ItemNew signal" msgstr "警告: 予期しないメッセージが ItemNew 信号を含んでいます" #: ../virt-ctrl/vc_dbus.ml:140 msgid "warning: unexpected message contents of ItemRemove signal" msgstr "警告: 予期しないメッセージが ItemRemove 信号を含んでいます" #: ../mlvirsh/mlvirsh.ml:378 msgid "write bytes: %Ld\\n" msgstr "バイトの書き込み: %Ld\\n" #: ../mlvirsh/mlvirsh.ml:377 msgid "write requests: %Ld\\n" msgstr "要求の書き込み: %Ld\\n" ocaml-gettext-0.4.2/test/testdata/test12.po000066400000000000000000000002611367051331200205440ustar00rootroot00000000000000msgid "" msgstr "" "Content-Type: text/plain; charset=ISO-8859-1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "'Your command, please?', asked the waiter." msgstr "" ocaml-gettext-0.4.2/test/testdata/test2.po000066400000000000000000000006651367051331200204730ustar00rootroot00000000000000msgid "" msgstr "" "Content-Type: text/plain; charset=ISO-8859-1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "'Your command, please?', asked the waiter." msgstr "Votre commande, s'il vous plait, dit le garon." # Reverse the arguments. #, c-format msgid "%s is replaced by %s." msgstr "%2$s remplace %1$s." msgid "hey" msgstr "h" msgid "%d coffee" msgid_plural "more %d coffee" msgstr[0] "%d caf" msgstr[1] "%d cafs" ocaml-gettext-0.4.2/test/testdata/test3.po000066400000000000000000000007171367051331200204720ustar00rootroot00000000000000msgid "" msgstr "" "Content-Type: text/plain; charset=ISO-8859-1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" domain "fr" msgid "'Your command, please?', asked the waiter." msgstr "Votre commande, s'il vous plait, dit le garon." # Reverse the arguments. #, c-format msgid "%s is replaced by %s." msgstr "%2$s remplace %1$s." msgid "hey" msgstr "h" domain "us" msgid "%d coffee" msgid_plural "more %d coffee" msgstr[0] "%d caf" msgstr[1] "%d cafs" ocaml-gettext-0.4.2/test/testdata/test4.ml000066400000000000000000000107001367051331200204560ustar00rootroot00000000000000(**************************************************************************) (* ocaml-gettext: a library to translate messages *) (* *) (* Copyright (C) 2003-2008 Sylvain Le Gall *) (* *) (* This library is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Lesser General Public *) (* License as published by the Free Software Foundation; either *) (* version 2.1 of the License, or (at your option) any later version; *) (* with the OCaml static compilation exception. *) (* *) (* This library 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 *) (* Lesser General Public License for more details. *) (* *) (* You should have received a copy of the GNU Lesser General Public *) (* License along with this library; if not, write to the Free Software *) (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *) (* USA *) (**************************************************************************) let t' = () let _ = s_ "s_" let _ = f_ "f_" let _ = sn_ "sn_ singular" "sn_ plural" 0 let _ = fn_ "fn_ singular" "fn_ plural" 0 let _ = gettext t' "gettext" let _ = fgettext t' "fgettext" let _ = dgettext t' "mydomain" "dgettext" let _ = fdgettext t' "mydomain" "fdgettext" let _ = dcgettext t' "mydomain" "dcgettext" LC_ALL let _ = fdcgettext t' "mydomain" "fdcgettext" LC_ALL let _ = ngettext t' "ngettext singular" "ngettext plural" 0 let _ = fngettext t' "fngettext singular" "fngettext plural" 0 let _ = dngettext t' "mydomain" "dngettext singular" "dngettext plural " 0 let _ = fdngettext t' "mydomain" "fdngettext singular" "fdngettext plural" 0 let _ = dcngettext t' "mydomain" "dcngettext singular" "dcngettext plural" 0 LC_ALL let _ = fdcngettext t' "mydomain" "fdcngettext singular" "fdcngettext plural" 0 LC_ALL let _ = TestGettext.s_ "TestGettext.s_" let _ = TestGettext.f_ "TestGettext.f_" let _ = TestGettext.sn_ "TestGettext.sn_ singular" "TestGettext.sn_ plural" 0 let _ = TestGettext.fn_ "TestGettext.fn_ singular" "TestGettext.fn_ plural" 0 let _ = GettextCompat.gettext t' "GettextCompat.gettext" let _ = GettextCompat.fgettext t' "GettextCompat.fgettext" let _ = GettextCompat.dgettext t' "mydomain" "GettextCompat.dgettext" let _ = GettextCompat.fdgettext t' "mydomain" "GettextCompat.fdgettext" let _ = GettextCompat.dcgettext t' "mydomain" "GettextCompat.dcgettext" LC_ALL let _ = GettextCompat.fdcgettext t' "mydomain" "GettextCompat.fdcgettext" LC_ALL let _ = GettextCompat.ngettext t' "GettextCompat.ngettext singular" "GettextCompat.ngettext plural" 0 let _ = GettextCompat.fngettext t' "GettextCompat.fngettext singular" "GettextCompat.fngettext plural" 0 let _ = GettextCompat.dngettext t' "mydomain" "GettextCompat.dngettext singular" "GettextCompat.dngettext plural " 0 let _ = GettextCompat.fdngettext t' "mydomain" "GettextCompat.fdngettext singular" "GettextCompat.fdngettext plural" 0 let _ = GettextCompat.dcngettext t' "mydomain" "GettextCompat.dcngettext singular" "GettextCompat.dcngettext plural" 0 LC_ALL let _ = GettextCompat.fdcngettext t' "mydomain" "GettextCompat.fdcngettext singular" "GettextCompat.fdcngettext plural" 0 LC_ALL let _ = TestGettext.Library.s_ "TestGettext.Library.s_" let _ = TestGettext.Library.f_ "TestGettext.Library.f_" let _ = TestGettext.Library.sn_ "TestGettext.Library.sn_ singular" "TestGettext.Library.sn_ plural" 0 let _ = TestGettext.Library.fn_ "TestGettext.Library.fn_ singular" "TestGettext.Library.fn_ plural" 0 let _ = TestGettext.Program.s_ "TestGettext.Program.s_" let _ = TestGettext.Program.f_ "TestGettext.Program.f_" let _ = TestGettext.Program.sn_ "TestGettext.Program.sn_ singular" "TestGettext.Program.sn_ plural" 0 let _ = TestGettext.Gettext.Program.fn_ "TestGettext.Program.fn_ singular" "TestGettext.Program.fn_ plural" 0 ocaml-gettext-0.4.2/test/testdata/test4.po000066400000000000000000000134411367051331200204710ustar00rootroot00000000000000#, fuzzy msgid "" msgstr "" "Project-Id-Version: ocaml-gettext 0.2.0\n" "Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org\n" "POT-Creation-Date: 2005-02-08 23:35+0200\n" "PO-Revision-Date: 2005-02-08 23:35+0200\n" "Last-Translator: Sylvain Le Gall \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n" #: test4.ml:89 msgid "GettextCompat.fgettext" msgstr "Fonction de compatibilit fgettext" #: test4.ml:107 msgid "GettextCompat.fngettext singular" msgid_plural "GettextCompat.fngettext plural" msgstr[0] "Fonction de compatibilit fngettext ( singulier )" msgstr[1] "Fonction de compatibilit fngettext ( pluriel )" #: test4.ml:86 msgid "GettextCompat.gettext" msgstr "Fonction de compatibilit gettext" #: test4.ml:104 msgid "GettextCompat.ngettext singular" msgid_plural "GettextCompat.ngettext plural" msgstr[0] "Fonction de compatibilit ngettext ( singulier )" msgstr[1] "Fonction de compatibilit ngettext ( pluriel )" #: test4.ml:125 msgid "TestGettext.Library.f_" msgstr "Fonction de librairie f_" #: test4.ml:131 msgid "TestGettext.Library.fn_ singular" msgid_plural "TestGettext.Library.fn_ plural" msgstr[0] "Fonction de librairie fn ( singulier )" msgstr[1] "Fonction de librairie fn ( pluriel )" #: test4.ml:122 msgid "TestGettext.Library.s_" msgstr "Fonction de librairie s_" #: test4.ml:128 msgid "TestGettext.Library.sn_ singular" msgid_plural "TestGettext.Library.sn_ plural" msgstr[0] "Fonction de librairie sn_ ( singulier )" msgstr[1] "Fonction de librairie sn_ ( pluriel )" #: test4.ml:137 msgid "TestGettext.Program.f_" msgstr "Fonction de programme f_" #: test4.ml:143 msgid "TestGettext.Program.fn_ singular" msgid_plural "TestGettext.Program.fn_ plural" msgstr[0] "Fonction de programme ( singulier )" msgstr[1] "Fonction de programme ( pluriel )" #: test4.ml:134 msgid "TestGettext.Program.s_" msgstr "Fonction de programm s_" #: test4.ml:140 msgid "TestGettext.Program.sn_ singular" msgid_plural "TestGettext.Program.sn_ plural" msgstr[0] "Fonction de programme sn_ ( singulier )" msgstr[1] "Fonction de programme sn_ ( pluriel )" #: test4.ml:77 msgid "TestGettext.f_" msgstr "Fonction aliase f_" #: test4.ml:83 msgid "TestGettext.fn_ singular" msgid_plural "TestGettext.fn_ plural" msgstr[0] "Fonction aliase fn_ ( singulier )" msgstr[1] "Fonction aliase fn_ ( pluriel )" #: test4.ml:74 msgid "TestGettext.s_" msgstr "Fonction simple aliase s_" #: test4.ml:80 msgid "TestGettext.sn_ singular" msgid_plural "TestGettext.sn_ plural" msgstr[0] "Fonction aliase sn_ ( singulier )" msgstr[1] "Fonction aliase sn_ ( pluriel )" #: test4.ml:29 msgid "f_" msgstr "Fonction simple f_" #: test4.ml:41 msgid "fgettext" msgstr "Fonction simple fgettext" #: test4.ml:35 msgid "fn_ singular" msgid_plural "fn_ plural" msgstr[0] "Fonction simple fn_ ( singulier )" msgstr[1] "Fonction simple fn_ ( pluriel )" #: test4.ml:59 msgid "fngettext singular" msgid_plural "fngettext plural" msgstr[0] "Fonction simple fngettext ( singulier )" msgstr[1] "Fonction simple fngettext ( pluriel )" #: test4.ml:38 msgid "gettext" msgstr "Fonction simple gettext" #: test4.ml:56 msgid "ngettext singular" msgid_plural "ngettext plural" msgstr[0] "Fonction ngettext ( singulier)" msgstr[1] "Fonction ngettext ( pluriel )" #: test4.ml:26 msgid "s_" msgstr "Fonction simple s_" #: test4.ml:32 msgid "sn_ singular" msgid_plural "sn_ plural" msgstr[0] "Fonction simple sn_ ( singulier )" msgstr[1] "Fonction simple sn_ ( pluriel )" domain "mydomain" #: test4.ml:98 msgid "GettextCompat.dcgettext" msgstr "Fonction de compatibilit dcgettext" #: test4.ml:116 msgid "GettextCompat.dcngettext singular" msgid_plural "GettextCompat.dcngettext plural" msgstr[0] "Fonction de compatibilit dcngettext ( singulier )" msgstr[1] "Fonction de compatibilit dcngettext ( pluriel )" #: test4.ml:92 msgid "GettextCompat.dgettext" msgstr "Fonction de compatibilit dgettext" #: test4.ml:110 msgid "GettextCompat.dngettext singular" msgid_plural "GettextCompat.dngettext plural " msgstr[0] "Fonction de compatibilit dngettext ( singulier )" msgstr[1] "Fonction de compatibilit dngettext ( pluriel )" #: test4.ml:101 msgid "GettextCompat.fdcgettext" msgstr "Fonction de compatibilit fdcgettext" #: test4.ml:119 msgid "GettextCompat.fdcngettext singular" msgid_plural "GettextCompat.fdcngettext plural" msgstr[0] "Fonction de compatibilit fdcngettext ( singulier )" msgstr[1] "Fonction de compatibilit fdcngettext ( pluriel )" #: test4.ml:95 msgid "GettextCompat.fdgettext" msgstr "Fonction de compatibilit fdgettext" #: test4.ml:113 msgid "GettextCompat.fdngettext singular" msgid_plural "GettextCompat.fdngettext plural" msgstr[0] "Fonction de compatibilit fdngettext ( singulier )" msgstr[1] "Fonction de compatibilit fdngettext ( pluriel )" #: test4.ml:50 msgid "dcgettext" msgstr "Fonction simple dcgettext" #: test4.ml:68 msgid "dcngettext singular" msgid_plural "dcngettext plural" msgstr[0] "Fonction simple dcngettext ( singulier )" msgstr[1] "Fonction simple dcngettext ( pluriel )" #: test4.ml:44 msgid "dgettext" msgstr "Fonction simple dcgettext" #: test4.ml:62 msgid "dngettext singular" msgid_plural "dngettext plural " msgstr[0] "Fonction simple dngettext ( singulier )" msgstr[1] "Fonction simple dngettext ( pluriel )" #: test4.ml:53 msgid "fdcgettext" msgstr "Fonction simple fdcgettext" #: test4.ml:71 msgid "fdcngettext singular" msgid_plural "fdcngettext plural" msgstr[0] "Fonction simple fdcngettext ( singulier )" msgstr[1] "Fonction simple fdcngettext ( pluriel )" #: test4.ml:47 msgid "fdgettext" msgstr "Fonction simple dcgettext" #: test4.ml:65 msgid "fdngettext singular" msgid_plural "fdngettext plural" msgstr[0] "Fonction simple dcgettext" msgstr[1] "Fonction simple dcgettext" ocaml-gettext-0.4.2/test/testdata/test5.mo000066400000000000000000000051021367051331200204620ustar00rootroot00000000000000llm?=?/?o??F/U/#!'? a!__MMHMMK?^AA MN  K A GettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralGettextCompat.gettextGettextCompat.ngettext singularGettextCompat.ngettext pluralTestGettext.Library.f_TestGettext.Library.fn_ singularTestGettext.Library.fn_ pluralTestGettext.Library.sn_ singularTestGettext.Library.sn_ pluralTestGettext.Program.f_TestGettext.Program.fn_ singularTestGettext.Program.fn_ pluralTestGettext.Program.sn_ singularTestGettext.Program.sn_ pluralTestGettext.f_TestGettext.fn_ singularTestGettext.fn_ pluralTestGettext.sn_ singularTestGettext.sn_ pluralf_fgettextfn_ singularfn_ pluralfngettext singularfngettext pluralgettextngettext singularngettext pluralsn_ singularsn_ pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Fonction de compatibil fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )Fonction de compatibilit gettextFonction de compatibilit ngettext ( singulier )Fonction de compatibilit ngettext ( pluriel )Fonction de librairie f_Fonction de librairie fn_ ( singulier )Fonction de librairie fn_ ( pluriel )Fonction de librairie sn_ ( singulier )Fonction de librairie sn_ ( pluriel )Fonction de programme f_Fonction de programme fn_ ( singulier )Fonction de programme fn_ ( pluriel )Fonction de programme sn_ ( singulier )Fonction de programme sn_ ( pluriel )Fonction alias f_Fonction alias f_ ( singulier )Fonction alias f_ ( pluriel )Fonction alias sn_ ( singulier )Fonction alias sn_ ( pluriel )Fonction simple f_Fonction simple fgettextFonction simple fn_ ( singulier )Fonction simple fn_ ( pluriel )Fonction simple fngettext ( singulier )Fonction simple fngettext ( pluriel )Fonction simple gettextFonction simple ngettext ( singulier )Fonction simple ngettext ( pluriel )Fonction simple sn_ ( singulier )Fonction simple sn_ ( pluriel )ocaml-gettext-0.4.2/test/testdata/test6.mo000066400000000000000000000051021367051331200204630ustar00rootroot00000000000000llm?=?/?o??F/U/#!'? a!__MMHMMK?^AA MN  K A GettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralGettextCompat.gettextGettextCompat.ngettext singularGettextCompat.ngettext pluralTestGettext.Library.f_TestGettext.Library.fn_ singularTestGettext.Library.fn_ pluralTestGettext.Library.sn_ singularTestGettext.Library.sn_ pluralTestGettext.Program.f_TestGettext.Program.fn_ singularTestGettext.Program.fn_ pluralTestGettext.Program.sn_ singularTestGettext.Program.sn_ pluralTestGettext.f_TestGettext.fn_ singularTestGettext.fn_ pluralTestGettext.sn_ singularTestGettext.sn_ pluralf_fgettextfn_ singularfn_ pluralfngettext singularfngettext pluralgettextngettext singularngettext pluralsn_ singularsn_ pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Fonction de compatibil fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )Fonction de compatibilit gettextFonction de compatibilit ngettext ( singulier )Fonction de compatibilit ngettext ( pluriel )Fonction de librairie f_Fonction de librairie fn_ ( singulier )Fonction de librairie fn_ ( pluriel )Fonction de librairie sn_ ( singulier )Fonction de librairie sn_ ( pluriel )Fonction de programme f_Fonction de programme fn_ ( singulier )Fonction de programme fn_ ( pluriel )Fonction de programme sn_ ( singulier )Fonction de programme sn_ ( pluriel )Fonction alias f_Fonction alias f_ ( singulier )Fonction alias f_ ( pluriel )Fonction alias sn_ ( singulier )Fonction alias sn_ ( pluriel )Fonction simple f_Fonction simple fgettextFonction simple fn_ ( singulier )Fonction simple fn_ ( pluriel )Fonction simple fngettext ( singulier )Fonction simple fngettext ( pluriel )Fonction simple gettextFonction simple ngettext ( singulier )Fonction simple ngettext ( pluriel )Fonction simple sn_ ( singulier )Fonction simple sn_ ( pluriel )ocaml-gettext-0.4.2/test/testdata/test7.mo000066400000000000000000000051021367051331200204640ustar00rootroot00000000000000llm?=?/?o??F/U/#!'? a!__MMHMMK?^AA MN  K A GettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralGettextCompat.gettextGettextCompat.ngettext singularGettextCompat.ngettext pluralTestGettext.Library.f_TestGettext.Library.fn_ singularTestGettext.Library.fn_ pluralTestGettext.Library.sn_ singularTestGettext.Library.sn_ pluralTestGettext.Program.f_TestGettext.Program.fn_ singularTestGettext.Program.fn_ pluralTestGettext.Program.sn_ singularTestGettext.Program.sn_ pluralTestGettext.f_TestGettext.fn_ singularTestGettext.fn_ pluralTestGettext.sn_ singularTestGettext.sn_ pluralf_fgettextfn_ singularfn_ pluralfngettext singularfngettext pluralgettextngettext singularngettext pluralsn_ singularsn_ pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Fonction de compatibil fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )Fonction de compatibilit gettextFonction de compatibilit ngettext ( singulier )Fonction de compatibilit ngettext ( pluriel )Fonction de librairie f_Fonction de librairie fn_ ( singulier )Fonction de librairie fn_ ( pluriel )Fonction de librairie sn_ ( singulier )Fonction de librairie sn_ ( pluriel )Fonction de programme f_Fonction de programme fn_ ( singulier )Fonction de programme fn_ ( pluriel )Fonction de programme sn_ ( singulier )Fonction de programme sn_ ( pluriel )Fonction alias f_Fonction alias f_ ( singulier )Fonction alias f_ ( pluriel )Fonction alias sn_ ( singulier )Fonction alias sn_ ( pluriel )Fonction simple f_Fonction simple fgettextFonction simple fn_ ( singulier )Fonction simple fn_ ( pluriel )Fonction simple fngettext ( singulier )Fonction simple fngettext ( pluriel )Fonction simple gettextFonction simple ngettext ( singulier )Fonction simple ngettext ( pluriel )Fonction simple sn_ ( singulier )Fonction simple sn_ ( pluriel )ocaml-gettext-0.4.2/test/testdata/test8.mo000066400000000000000000000051021367051331200204650ustar00rootroot00000000000000ll?=?/?o??F/U/#!'? a!__MMHMMK?^AA MN  K A GettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralGettextCompat.gettextGettextCompat.ngettext singularGettextCompat.ngettext pluralTestGettext.Library.f_TestGettext.Library.fn_ singularTestGettext.Library.fn_ pluralTestGettext.Library.sn_ singularTestGettext.Library.sn_ pluralTestGettext.Program.f_TestGettext.Program.fn_ singularTestGettext.Program.fn_ pluralTestGettext.Program.sn_ singularTestGettext.Program.sn_ pluralTestGettext.f_TestGettext.fn_ singularTestGettext.fn_ pluralTestGettext.sn_ singularTestGettext.sn_ pluralf_fgettextfn_ singularfn_ pluralfngettext singularfngettext pluralgettextngettext singularngettext pluralsn_ singularsn_ pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Fonction de compatibil fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )Fonction de compatibilit gettextFonction de compatibilit ngettext ( singulier )Fonction de compatibilit ngettext ( pluriel )Fonction de librairie f_Fonction de librairie fn_ ( singulier )Fonction de librairie fn_ ( pluriel )Fonction de librairie sn_ ( singulier )Fonction de librairie sn_ ( pluriel )Fonction de programme f_Fonction de programme fn_ ( singulier )Fonction de programme fn_ ( pluriel )Fonction de programme sn_ ( singulier )Fonction de programme sn_ ( pluriel )Fonction alias f_Fonction alias f_ ( singulier )Fonction alias f_ ( pluriel )Fonction alias sn_ ( singulier )Fonction alias sn_ ( pluriel )Fonction simple f_Fonction simple fgettextFonction simple fn_ ( singulier )Fonction simple fn_ ( pluriel )Fonction simple fngettext ( singulier )Fonction simple fngettext ( pluriel )Fonction simple gettextFonction simple ngettext ( singulier )Fonction simple ngettext ( pluriel )Fonction simple sn_ ( singulier )Fonction simple sn_ ( pluriel )ocaml-gettext-0.4.2/test/testdata/test9.mo000066400000000000000000000051021367051331200204660ustar00rootroot00000000000000llm?=?/?o??F/U/#!' a!__MMHMMK?^AA MN  K A GettextCompat.fgettextGettextCompat.fngettext singularGettextCompat.fngettext pluralGettextCompat.gettextGettextCompat.ngettext singularGettextCompat.ngettext pluralTestGettext.Library.f_TestGettext.Library.fn_ singularTestGettext.Library.fn_ pluralTestGettext.Library.sn_ singularTestGettext.Library.sn_ pluralTestGettext.Program.f_TestGettext.Program.fn_ singularTestGettext.Program.fn_ pluralTestGettext.Program.sn_ singularTestGettext.Program.sn_ pluralTestGettext.f_TestGettext.fn_ singularTestGettext.fn_ pluralTestGettext.sn_ singularTestGettext.sn_ pluralf_fgettextfn_ singularfn_ pluralfngettext singularfngettext pluralgettextngettext singularngettext pluralsn_ singularsn_ pluralProject-Id-Version: ocaml-gettext 0.2.0 Report-Msgid-Bugs-To: submit@bugs.gallu.homelinux.org POT-Creation-Date: 2005-02-08 23:35+0200 PO-Revision-Date: 2005-02-08 23:35+0200 Last-Translator: Sylvain Le Gall Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Fonction de compatibil fgettextFonction de compatibilit fngettext ( singulier )Fonction de compatibilit fngettext ( pluriel )Fonction de compatibilit gettextFonction de compatibilit ngettext ( singulier )Fonction de compatibilit ngettext ( pluriel )Fonction de librairie f_Fonction de librairie fn_ ( singulier )Fonction de librairie fn_ ( pluriel )Fonction de librairie sn_ ( singulier )Fonction de librairie sn_ ( pluriel )Fonction de programme f_Fonction de programme fn_ ( singulier )Fonction de programme fn_ ( pluriel )Fonction de programme sn_ ( singulier )Fonction de programme sn_ ( pluriel )Fonction alias f_Fonction alias f_ ( singulier )Fonction alias f_ ( pluriel )Fonction alias sn_ ( singulier )Fonction alias sn_ ( pluriel )Fonction simple f_Fonction simple fgettextFonction simple fn_ ( singulier )Fonction simple fn_ ( pluriel )Fonction simple fngettext ( singulier )Fonction simple fngettext ( pluriel )Fonction simple gettextFonction simple ngettext ( singulier )Fonction simple ngettext ( pluriel )Fonction simple sn_ ( singulier )Fonction simple sn_ ( pluriel )ocaml-gettext-0.4.2/test/testdata/unsound_warning.ml000066400000000000000000000001051367051331200226310ustar00rootroot00000000000000open TestGettext let () = Printf.eprintf (f_ "%s\n") "abce"; () ocaml-gettext-0.4.2/test/testdata/utf8-fr.po000066400000000000000000000174751367051331200207340ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: oji 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2005-05-27 02:37+0200\n" "PO-Revision-Date: 2005-05-27 02:39+0200\n" "Last-Translator: French \n" "Language-Team: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;" #: ../dlg_browser.ml:93 msgid " - browse kanji - " msgstr " - parcourir les kanji - " #: ../dlg_config.ml:11 msgid " - configuration" msgstr "- configuration" #: ../dlg_editor.ml:84 msgid " - edit kanji - " msgstr " - édition de kanji" #: ../dlg_stacks.ml:18 msgid " - stacks manager" msgstr " - gestionnaire de tas" #: ../dlg_test.ml:170 msgid " - statistics" msgstr " - statistiques" #: ../dlg_test.ml:103 msgid " - test - " msgstr " - révision- " #: ../dlg_editor.ml:34 msgid " book: " msgstr "livre:" #: ../dlg_editor.ml:42 msgid " keyword: " msgstr "mot clef:" #: ../dlg_editor.ml:31 msgid " lang: " msgstr "langue:" #: ../dlg_editor.ml:46 msgid " nicknames: " msgstr "sésames:" #: ../dlg_editor.ml:50 msgid " number (-1 if not in this book): " msgstr "numéro (-1 si il n'est pas dans le livre)" #: ../dlg_test.ml:164 msgid " bad answers were:" msgstr "les mauvaises réponses étaient" #: ../dlg_search.ml:32 msgid " because " msgstr " car " #: ../dlg_stacks.ml:35 msgid " in book" msgstr " dans le livre " #: ../dlg_editor.ml:101 ../dlg_editor.ml:161 msgid " kana " msgstr " kana " #: ../dlg_editor.ml:103 ../dlg_editor.ml:163 msgid " translation " msgstr " signification " #: ../dlg_voclists.ml:41 msgid " vocabulary files" msgstr " fichiers de vocabulaire" #: ../dlg_editor.ml:36 msgid "(just write it instead of selecting in the lists)" msgstr "(écrivez le au lieu de le sélectionner)" #: ../dlg_search.ml:72 ../dlg_search.ml:81 ../dlg_search.ml:90 msgid ") in lang " msgstr ") en langue " #: ../dlg_config.ml:287 msgid " select font for big kanji" msgstr " chosissez la police pour le gros kanji" #: ../dlg_editor.ml:63 msgid "ON readings " msgstr "lectures ON" #: ../dlg_browser.ml:73 ../dlg_config.ml:68 ../dlg_test.ml:80 msgid "ON readings" msgstr "lectures ON" #: ../dlg_stacks.ml:186 msgid "already known" msgstr "déja connus" #: ../dlg_stacks.ml:26 msgid "buffer zone" msgstr "zone tampon" #: ../main.ml:39 msgid "configuration" msgstr "configuration" #: ../main.ml:47 msgid "data" msgstr "données" #: ../dlg_stacks.ml:240 msgid "erroneous" msgstr "érronés" #: ../dlg_editor.ml:39 msgid "flashcard's datas" msgstr "données de la fiche" #: ../dlg_stacks.ml:29 msgid "import from number " msgstr "importer depuis le numéro " #: ../dlg_editor.ml:25 msgid "kanji: " msgstr "kanji: " #: ../dlg_browser.ml:45 ../dlg_test.ml:52 msgid "keywords in all langs" msgstr "mots clefs dans toutes les langues" #: ../dlg_editor.ml:56 msgid "kun readings " msgstr "lectures kun" #: ../dlg_browser.ml:70 ../dlg_config.ml:97 ../dlg_test.ml:77 msgid "kun readings" msgstr "lectures kun" #: ../dlg_config.ml:27 msgid "main data" msgstr "données principales" #: ../dlg_browser.ml:57 ../dlg_test.ml:64 msgid "nicknames in all langs" msgstr "sésames dans toutes les langues" #: ../dlg_browser.ml:33 ../dlg_test.ml:40 msgid "numbers in all books" msgstr "numéros dans tous les livres" #: ../dlg_browser.ml:80 ../dlg_test.ml:87 msgid "personal notes on this kanji" msgstr "notes personnelles sur ce kanji" #: ../dlg_config.ml:18 msgid "question type" msgstr "type de question" #: ../dlg_editor.ml:22 msgid "select flashcard" msgstr "choisissez une fiche" #: ../dlg_stacks.ml:22 msgid "stacks " msgstr "tas " #: ../dlg_stacks.ml:57 msgid "sub stacks" msgstr "sous tas" #: ../dlg_editor.ml:70 ../dlg_browser.ml:76 ../dlg_config.ml:126 #. ../dlg_test.ml:83 msgid "vocabulary" msgstr "vocabulaire" #: ../main.ml:28 msgid "work" msgstr "révision" #: ../dlg_test.ml:90 msgid "See" msgstr "Voir" #: ../main.ml:36 msgid "add a day to kanji stacks" msgstr "avancer d'un jour les tas de kanji" #: ../dlg_voclists.ml:15 msgid "add all files you want, click on close when you are done" msgstr "ajoutez les fichiers voulus, cliquez sur fermer une fois terminé" #: ../dlg_voclists.ml:44 msgid "add and remove files" msgstr "ajouter et supprimer des fichiers" #: ../dlg_config.ml:160 ../dlg_config.ml:215 msgid "automagically detected in data file" msgstr "détecté automagiquement dans le fichier de données" #: ../dlg_config.ml:160 msgid "book to use" msgstr "livre à utiliser" #: ../main.ml:49 msgid "browse all kanji flashcards" msgstr "parcourir les fiches de kanji" #: ../dlg_config.ml:18 msgid "define what will be displayed" msgstr "définissez ce qui sera affiché" #: ../main.ml:52 msgid "edit the kanji flashcards" msgstr "éditer les fiches de kanji" #: ../dlg_config.ml:82 ../dlg_config.ml:111 ../dlg_config.ml:140 msgid "kana" msgstr "kana" #: ../dlg_config.ml:37 ../dlg_config.ml:78 ../dlg_config.ml:107 #. ../dlg_config.ml:136 msgid "kanji" msgstr "kanji" #: ../dlg_editor.ml:99 ../dlg_editor.ml:159 msgid "kanji " msgstr "kanji" #: ../dlg_test.ml:102 msgid "kanji " msgstr "kanji " #: ../dlg_voclists.ml:21 msgid "kanjiscope file" msgstr "fichier kanjiscope" #: ../dlg_config.ml:45 msgid "keyword" msgstr "mot-clef" #: ../dlg_search.ml:59 msgid "keyword in lang " msgstr "mot-clef en langue" #: ../dlg_search.ml:67 msgid "kun reading = " msgstr "lecture kun = " #: ../dlg_config.ml:215 msgid "lang to use" msgstr "langue à utiliser" #: ../dlg_voclists.ml:12 msgid "load a vocabulary list" msgstr "charger une liste de vocabulaire" #: ../main.ml:55 msgid "manage vocabulary files" msgstr "gérer les fichiers de vocabulaire" #: ../main.ml:41 msgid "manage your kanji stacks" msgstr "gérer les tas de kanji" #: ../dlg_voclists.ml:20 msgid "native CSV file" msgstr "fichier CSV natif" #: ../dlg_search.ml:63 msgid "nickname in lang " msgstr "sésame en langue" #: ../dlg_config.ml:49 msgid "nicknames" msgstr "sésames" #: ../dlg_config.ml:172 msgid "no book" msgstr "pas de livre" #: ../dlg_config.ml:228 msgid "no lang" msgstr "pas de langue" #: ../dlg_config.ml:53 msgid "notes" msgstr "notes" #: ../dlg_config.ml:41 msgid "number" msgstr "numéro" #: ../dlg_search.ml:47 msgid "number in book " msgstr "numéro dans le livre" #: ../dlg_search.ml:90 msgid "on reading " msgstr "lecture on" #: ../dlg_search.ml:85 msgid "on reading = " msgstr "lecture on = " #: ../dlg_config.ml:160 msgid "only used to show numbers" msgstr "utilisé seulement pour l'affichage des numéros" #: ../dlg_search.ml:16 msgid "search a kanji" msgstr "rechercher un kanji" #: ../dlg_stacks.ml:54 msgid "stack " msgstr "tas " #: ../main.ml:33 msgid "stubborn work on kanji (1-0)" msgstr "travail têtu sur les kanji (1-0)" #: ../dlg_stacks.ml:83 msgid "sub stack " msgstr "sous tas " #: ../dlg_test.ml:158 msgid "success:" msgstr "réussite:" #: ../dlg_test.ml:158 msgid "test finished!" msgstr "révisions terminées!" #: ../dlg_stacks.ml:32 msgid "to" msgstr "jusqu'au" #: ../dlg_config.ml:86 ../dlg_config.ml:115 ../dlg_config.ml:144 msgid "translation" msgstr "traduction" #: ../dlg_search.ml:81 msgid "vocabulary " msgstr "vocabulaire " #: ../dlg_search.ml:76 msgid "vocabulary = " msgstr "vocabulaire = " #: ../main.ml:30 msgid "work today's kanji" msgstr "réviser les kanji du jour" #: ../dlg_editor.ml:36 msgid "you can add a lang, a book, or even a kanji" msgstr "vous pouvez ajouter un livre, une langue ou même un kanji" #: ../dlg_search.ml:93 msgid "your notes = " msgstr "vos notes = " ocaml-gettext-0.4.2/test/testdata/utf8-ja.po000066400000000000000000000222471367051331200207100ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: virt-p2v--devel\n" "Report-Msgid-Bugs-To: rjones@redhat.com\n" "POT-Creation-Date: 2008-03-22 15:53+0000\n" "PO-Revision-Date: 2008-03-23 20:29+0000\n" "Last-Translator: Naoko - \n" "Language-Team: Japanese\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: ../virt-p2v.ml:1876 msgid " (about %.0f minutes remaining)" msgstr "残り 約%.0f分" #: ../virt-p2v.ml:1879 msgid " (about %.0f seconds remaining)" msgstr "残り 約%.0f秒" #: ../virt-p2v.ml:1902 msgid "%s has finished" msgstr "%s修了" #: ../virt-p2v.ml:813 msgid "%s starting up ...\\n%!" msgstr "%s起動中 ...\\n%!" #: ../virt-p2v.ml:1424 msgid "(leave MAC blank for random)" msgstr "" #: ../virt-p2v.ml:1391 msgid "Architecture:" msgstr "アーキテクチャ" #: ../virt-p2v.ml:1120 msgid "Automatic from:" msgstr "" #: ../virt-p2v.ml:1356 msgid "Block devices" msgstr "ブロックデバイス" #: ../virt-p2v.ml:1418 msgid "CPUs:" msgstr "" #: ../virt-p2v.ml:428 msgid "Command failed:\\n\\n%s" msgstr "コマンド失敗:\\n\\n%2" #: ../virt-p2v.ml:1090 msgid "Configure network" msgstr "ネットワークを設定" #: ../virt-p2v.ml:1382 msgid "Configure target system" msgstr "目標システムを設定" #: ../virt-p2v.ml:825 msgid "Detecting hard drives (this may take some time) ..." msgstr "ハードドライブ検出(要時間)" #: ../virt-p2v.ml:571 msgid "" "Disk snapshot failed: unable to read the size in sectors of block device %s" msgstr "スナップショット失敗:%sのブロックデバイスのセクターのサイズ読み込み不可能" #: ../virt-p2v.ml:1136 msgid "Don't configure the network" msgstr "ネットワークを設定しないで下さい" #: ../virt-p2v.ml:323 msgid "Error" msgstr "エラー" #: ../virt-p2v.ml:295 msgid "F12 for next screen | [ALT] [F2] root / no password for shell" msgstr "" #: ../virt-p2v.ml:1021 msgid "Finished detecting hard drives." msgstr "ハードドライブ検出修了" #: ../virt-p2v.ml:1147 msgid "Gateway" msgstr "ゲートウエー" #: ../virt-p2v.ml:1384 msgid "Hypervisor:" msgstr "ハイパーバイザー" #: ../virt-p2v.ml:1143 msgid "IP" msgstr "" #: ../virt-p2v.ml:1141 msgid "Interface" msgstr "インタフェース" #: ../virt-p2v.ml:212 msgid "Linux /boot" msgstr "" #: ../virt-p2v.ml:208 msgid "Linux swap" msgstr "" #: ../virt-p2v.ml:1421 msgid "MAC addr:" msgstr "" #: ../virt-p2v.ml:1415 msgid "Memory (MB):" msgstr "メモリー (MB)" #: ../virt-p2v.ml:213 msgid "Mountable non-root" msgstr "" #: ../virt-p2v.ml:1149 msgid "Nameserver" msgstr "ネーム•サーバー" #: ../virt-p2v.ml:1145 msgid "Netmask" msgstr "ネットマスク" #: ../virt-p2v.ml:1089 msgid "Network" msgstr "" #: ../virt-p2v.ml:1237 msgid "" "Network configuration.\\n\\nPlease configure the network from this shell.\\n" "\\nWhen you have finished, exit the shell with ^D or exit.\\n" msgstr "" #: ../virt-p2v.ml:853 msgid "" "No non-removable block devices (hard disks, etc.) could be found on this " "machine." msgstr "" #: ../virt-p2v.ml:1557 msgid "Note" msgstr "" #: ../virt-p2v.ml:1599 msgid "Performing LVM snapshots ...\\n" msgstr "" #: ../virt-p2v.ml:1076 msgid "Physical to Virtual (P2V)" msgstr "" #: ../virt-p2v.ml:1133 msgid "QEMU user network" msgstr "QEMU ユーザーネットワーク" #: ../virt-p2v.ml:1287 msgid "Remote directory" msgstr "" #: ../virt-p2v.ml:1283 msgid "Remote host" msgstr "リモートホスト" #: ../virt-p2v.ml:1552 msgid "" "Remote hypervisor claims not to support fully virtualized %s guests.\\n" "\\nContinuing anyway.\\n\\n%!" msgstr "" #: ../virt-p2v.ml:1558 msgid "" "Remote hypervisor supports multiple types of fully virtualized %s guests.\\n" "\\nPlease help further development of libvirt and virt-p2v by sending the " "file /tmp/virt-p2v.log back to the developers. See the main virt-p2v " "website for contact details." msgstr "" #: ../virt-p2v.ml:1285 msgid "Remote port" msgstr "" #: ../virt-p2v.ml:1373 msgid "Root filesystem" msgstr "ルート ファイルシステム" #: ../virt-p2v.ml:1281 ../virt-p2v.ml:1280 msgid "SSH configuration" msgstr "SSH 設定" #: ../virt-p2v.ml:1338 msgid "SSH configuration failed" msgstr "SSH設定失敗" #: ../virt-p2v.ml:1289 msgid "SSH username" msgstr "SSHユーザーネーム" #: ../virt-p2v.ml:1358 msgid "Select block devices to send" msgstr "送信用のブロックデバイスを選択" #: ../virt-p2v.ml:1374 msgid "Select root filesystem" msgstr "" #: ../virt-p2v.ml:1123 msgid "Start a shell" msgstr "" #: ../virt-p2v.ml:1139 msgid "Static configuration:" msgstr "静的設定" #: ../virt-p2v.ml:1381 msgid "Target system" msgstr "" #: ../virt-p2v.ml:1302 msgid "Test SSH connection" msgstr "SSHコネクションをテスト" #: ../virt-p2v.ml:676 msgid "Testing SSH connection by listing files in remote directory ...\\n" msgstr "" #: ../virt-p2v.ml:1081 ../virt-p2v.ml:1080 msgid "Transfer type" msgstr "" #: ../virt-p2v.ml:1505 msgid "Try to fetch remote hypervisor capabilities ...\\n" msgstr "遠隔ハイパーバイザー機能をフェッチする" #: ../virt-p2v.ml:1266 msgid "Trying QEMU network configuration.\\n" msgstr "" #: ../virt-p2v.ml:1250 msgid "Trying network auto-configuration from root filesystem ...\\n" msgstr "" #: ../virt-p2v.ml:1241 msgid "Trying static network configuration.\\n" msgstr "" #: ../virt-p2v.ml:214 msgid "Unknown partition type" msgstr "不明のパーティションタイプ" #: ../virt-p2v.ml:1298 msgid "Use SSH compression (not good for LANs)" msgstr "" #: ../virt-p2v.ml:1427 msgid "Use remote libvirtd" msgstr "" #: ../virt-p2v.ml:1077 msgid "Virtual to Virtual (V2V)" msgstr "" #: ../virt-p2v.ml:1551 msgid "Warning" msgstr "警告" #: ../virt-p2v.ml:1068 msgid "" "Welcome to %s, a live CD for migrating a physical machine to a virtualized " "host.\\n\\nTo continue press the Return key.\\n\\nTo get a shell you can use " "[ALT] [F2] and log in as root with no password.\\n\\nExtra information is " "logged in /tmp/virt-p2v.log but this file disappears when the machine " "reboots." msgstr "" #: ../virt-p2v.ml:211 msgid "Windows root" msgstr "" #: ../virt-p2v.ml:821 msgid "You should only run this script from the live CD or a USB key." msgstr "ライブCDもしくはUSBキーからこのスクリプトを実行すべきです" #: ../virt-p2v.ml:1801 msgid "" "\\\n" "\\n\\n" msgstr "" "\\\n" "\\n\\n" #: ../virt-p2v.ml:1256 ../virt-p2v.ml:1244 msgid "" "\\nAuto-configuration failed. Starting a shell.\\n\\nPlease configure the " "network from this shell.\\n\\nWhen you have finished, exit the shell with ^D " "or exit.\\n" msgstr "" #: ../virt-p2v.ml:1840 msgid "\\nSending /dev/%s (%.3f GB) to remote machine\\n\\n%!" msgstr "" #: ../virt-p2v.ml:1903 msgid "" "\\nThe physical to virtual migration is complete.\\n\\nPlease verify the " "disk image(s) and configuration file on the remote host, and then start up " "the virtual machine by doing:\\n\\ncd %s\\nvirsh define %s\\n\\nWhen you " "press [OK] this machine will reboot." msgstr "" "\\nThe physical to virtual migration is complete.\\n\\nPlease verify the " "disk image(s) and configuration file on the remote host, and then start up " "the virtual machine by doing:\\n\\ncd %s\\nvirsh define %s\\n\\nWhen you " "OKを押して再起動する。" #: ../virt-p2v.ml:1819 msgid "\\nWriting configuration file ...\\n" msgstr "" #: ../virt-p2v.ml:683 msgid "" "\\n\\nDid SSH work?\\nHint: If not sure, there is a shell on console [ALT] " "[F2]\\n" msgstr "" #: ../virt-p2v.ml:599 msgid "" "\\n\\nDid automatic network configuration work?\\nHint: If not sure, there " "is a shell on console [ALT] [F2]" msgstr "" #: ../virt-p2v.ml:322 msgid "" "\\n\\nIf you want to report this error, there is a shell on [ALT] [F2], log " "in as root with no password.\\n\\nPlease provide the contents of /tmp/virt-" "p2v.log and output of the 'dmesg' command." msgstr "" #: ../virt-p2v.ml:286 msgid "open_centered_window: not in newt mode" msgstr "" #: ../virt-p2v.ml:447 msgid "shget: command killed by signal %d" msgstr "" #: ../virt-p2v.ml:449 msgid "shget: command stopped by signal %d" msgstr "" #: ../virt-p2v.ml:661 msgid "ssh: exited with error code %d" msgstr "" #: ../virt-p2v.ml:662 msgid "ssh: killed by signal %d" msgstr "" #: ../virt-p2v.ml:663 msgid "ssh: stopped by signal %d" msgstr "" #: ../virt-p2v.ml:528 msgid "unexpected output: " msgstr "" #: ../virt-p2v.ml:1915 msgid "usage: virt-p2v [--test] [ttyname]\\n%!" msgstr "" ocaml-gettext-0.4.2/test/testdata/valid_format.ml000066400000000000000000000003301367051331200220600ustar00rootroot00000000000000open TestGettext let e = Printf.eprintf let () = e (f_ "%ld") 1l; e (f_ "%d") 1; e (f_ "%s") "abcd"; e (f_ "%a") (fun chn e -> Printf.fprintf chn "%s" e) "ancd"; e (fn_ "%d category" "%d categories" 1) 1