mirror of
https://github.com/openharmony/third_party_gettext.git
synced 2026-07-01 10:25:03 -04:00
xgettext: Add Ruby support.
* gettext-tools/src/x-ruby.h: New file. * gettext-tools/src/x-ruby.c: New file. * gettext-tools/src/xgettext.h (verbose): New declaration. * gettext-tools/src/xgettext.c: Include x-ruby.h. (verbose): New declaration. (flag_table_ruby): New variable. (long_options): Add '--verbose'. (main): Update for Ruby. Handle '-v'/'--verbose' option. (usage): Document the '-L Ruby' and '-v' options. (xgettext_record_flag, language_to_extractor, extension_to_language): Update for Ruby. * gettext-tools/src/Makefile.am (noinst_HEADERS): Add x-ruby.h. (xgettext_SOURCES): Add x-ruby.c. * gettext-tools/src/FILES: Mention x-ruby.h, x-ruby.c. * gettext-tools/tests/xgettext-ruby-1: New file. * gettext-tools/tests/format-ruby-1: New file. * gettext-tools/tests/format-ruby-2: New file. * gettext-tools/tests/Makefile.am (TESTS): Add them. * gettext-tools/doc/gettext.texi (Ruby): New section. * gettext-tools/doc/xgettext.texi: Document the '-L Ruby' and '-v' options. * HACKING: Document the recommended Ruby packages. * NEWS: Mention the Ruby support.
This commit is contained in:
@@ -142,6 +142,13 @@ are skipped. To this effect, you need to install also:
|
||||
+ Homepage: http://www.php.net/
|
||||
+ Ubuntu package: php
|
||||
|
||||
* Ruby
|
||||
+ Homepage: https://www.ruby-lang.org/en/
|
||||
+ Ubuntu package: ruby
|
||||
* The ruby-gettext package
|
||||
+ Homepage: https://ruby-gettext.github.io/
|
||||
+ Ubuntu package: ruby-gettext
|
||||
|
||||
* lua
|
||||
+ Homepage: https://www.lua.org/
|
||||
+ Ubuntu package: lua5.2 or lua5.1
|
||||
|
||||
@@ -10,6 +10,10 @@ Version 0.21 - April 2020
|
||||
o xgettext now recognizes text blocks as string literals.
|
||||
- JavaScript:
|
||||
xgettext parses JSX expressions more reliably.
|
||||
- Ruby:
|
||||
o xgettext now supports Ruby.
|
||||
o 'msgfmt -c' now verifies the syntax of translations of Ruby format
|
||||
strings.
|
||||
|
||||
* Runtime behaviour:
|
||||
- On native Windows platforms, the directory that contains the message
|
||||
|
||||
@@ -79,7 +79,7 @@ This file provides documentation for GNU @code{gettext} utilities.
|
||||
It also serves as a reference for the free Translation Project.
|
||||
|
||||
@copying
|
||||
Copyright (C) 1995-1998, 2001-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1998, 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This manual is free documentation. It is dually licensed under the
|
||||
GNU FDL and the GNU GPL. This means that you can redistribute this
|
||||
@@ -114,7 +114,7 @@ A copy of the license is included in @ref{GNU GPL}.
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
@c @insertcopying
|
||||
Copyright (C) 1995-1998, 2001-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1998, 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This manual is free documentation. It is dually licensed under the
|
||||
GNU FDL and the GNU GPL. This means that you can redistribute this
|
||||
@@ -436,6 +436,7 @@ Individual Programming Languages
|
||||
* Tcl:: Tcl - Tk's scripting language
|
||||
* Perl:: Perl
|
||||
* PHP:: PHP Hypertext Preprocessor
|
||||
* Ruby:: Ruby
|
||||
* Pike:: Pike
|
||||
* GCC-source:: GNU Compiler Collection sources
|
||||
* Lua:: Lua
|
||||
@@ -9548,6 +9549,7 @@ that language, and to combine the resulting files using @code{msgcat}.
|
||||
* Tcl:: Tcl - Tk's scripting language
|
||||
* Perl:: Perl
|
||||
* PHP:: PHP Hypertext Preprocessor
|
||||
* Ruby:: Ruby
|
||||
* Pike:: Pike
|
||||
* GCC-source:: GNU Compiler Collection sources
|
||||
* Lua:: Lua
|
||||
@@ -12045,6 +12047,62 @@ On platforms without gettext, the functions are not available.
|
||||
|
||||
An example is available in the @file{examples} directory: @code{hello-php}.
|
||||
|
||||
@node Ruby
|
||||
@subsection Ruby
|
||||
@cindex Ruby
|
||||
|
||||
@table @asis
|
||||
@item RPMs
|
||||
ruby, ruby-gettext
|
||||
|
||||
@item Ubuntu packages
|
||||
ruby, ruby-gettext
|
||||
|
||||
@item File extension
|
||||
@code{rb}
|
||||
|
||||
@item String syntax
|
||||
@code{"abc"}, @code{'abc'}, @code{%q/abc/} etc.,
|
||||
@code{%q(abc)}, @code{%q[abc]}, @code{%q@{abc@}}
|
||||
|
||||
@item gettext shorthand
|
||||
@code{_("abc")}
|
||||
|
||||
@item gettext/ngettext functions
|
||||
@code{gettext}, @code{ngettext}
|
||||
|
||||
@item textdomain
|
||||
---
|
||||
|
||||
@item bindtextdomain
|
||||
@code{bindtextdomain} function
|
||||
|
||||
@item setlocale
|
||||
---
|
||||
|
||||
@item Prerequisite
|
||||
@code{require 'gettext'}
|
||||
@code{include GetText}
|
||||
|
||||
@item Use or emulate GNU gettext
|
||||
emulate
|
||||
|
||||
@item Extractor
|
||||
@code{xgettext}
|
||||
|
||||
@item Formatting with positions
|
||||
@code{sprintf("%2$d %1$d", x, y)}
|
||||
@*@code{"%@{new@} replaces %@{old@}" % @{:old => oldvalue, :new => newvalue@}}
|
||||
|
||||
@item Portability
|
||||
fully portable
|
||||
|
||||
@item po-mode marking
|
||||
---
|
||||
@end table
|
||||
|
||||
@c An example is available in the @file{examples} directory: @code{hello-ruby}.
|
||||
|
||||
@node Pike
|
||||
@subsection Pike
|
||||
@cindex Pike
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This file is part of the GNU gettext manual.
|
||||
@c Copyright (C) 1995-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||
@c See the file gettext.texi for copying conditions.
|
||||
|
||||
@pindex xgettext
|
||||
@@ -76,9 +76,9 @@ Specifies the language of the input files. The supported languages
|
||||
are @code{C}, @code{C++}, @code{ObjectiveC}, @code{PO}, @code{Shell},
|
||||
@code{Python}, @code{Lisp}, @code{EmacsLisp}, @code{librep}, @code{Scheme},
|
||||
@code{Smalltalk}, @code{Java}, @code{JavaProperties}, @code{C#}, @code{awk},
|
||||
@code{YCP}, @code{Tcl}, @code{Perl}, @code{PHP}, @code{GCC-source},
|
||||
@code{NXStringTable}, @code{RST}, @code{RSJ}, @code{Glade}, @code{Lua},
|
||||
@code{JavaScript}, @code{Vala}, @code{GSettings}, @code{Desktop}.
|
||||
@code{YCP}, @code{Tcl}, @code{Perl}, @code{PHP}, @code{Ruby},
|
||||
@code{GCC-source}, @code{NXStringTable}, @code{RST}, @code{RSJ}, @code{Glade},
|
||||
@code{Lua}, @code{JavaScript}, @code{Vala}, @code{GSettings}, @code{Desktop}.
|
||||
|
||||
@item -C
|
||||
@itemx --c++
|
||||
@@ -642,4 +642,10 @@ Display this help and exit.
|
||||
@opindex --version@r{, @code{xgettext} option}
|
||||
Output version information and exit.
|
||||
|
||||
@item -v
|
||||
@itemx --verbose
|
||||
@opindex -v@r{, @code{xgettext} option}
|
||||
@opindex --verbose@r{, @code{xgettext} option}
|
||||
Increase verbosity level.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -362,6 +362,9 @@ msgl-check.c
|
||||
| x-php.h
|
||||
| x-php.c
|
||||
| String extractor for PHP.
|
||||
| x-ruby.h
|
||||
| x-ruby.c
|
||||
| String extractor for Ruby.
|
||||
| x-rst.h
|
||||
| x-rst.c
|
||||
| String extractor from .rst files, for Object Pascal.
|
||||
|
||||
@@ -59,7 +59,7 @@ rc-str-list.h xg-pos.h xg-encoding.h xg-mixed-string.h xg-arglist-context.h \
|
||||
xg-arglist-callshape.h xg-arglist-parser.h xg-message.h \
|
||||
x-c.h x-po.h x-sh.h x-python.h x-lisp.h x-elisp.h x-librep.h \
|
||||
x-scheme.h x-smalltalk.h x-java.h x-properties.h x-csharp.h x-awk.h x-ycp.h \
|
||||
x-tcl.h x-perl.h x-php.h x-stringtable.h x-rst.h x-glade.h x-lua.h \
|
||||
x-tcl.h x-perl.h x-php.h x-ruby.h x-stringtable.h x-rst.h x-glade.h x-lua.h \
|
||||
x-javascript.h x-vala.h x-gsettings.h x-desktop.h x-appdata.h
|
||||
|
||||
EXTRA_DIST += FILES project-id
|
||||
@@ -206,6 +206,7 @@ xgettext_SOURCES += \
|
||||
x-tcl.c \
|
||||
x-perl.c \
|
||||
x-php.c \
|
||||
x-ruby.c \
|
||||
x-rst.c \
|
||||
x-lua.c \
|
||||
x-javascript.c \
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/* xgettext Ruby backend.
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2020.
|
||||
|
||||
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 3 of the License, 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, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "x-ruby.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "message.h"
|
||||
#include "sh-quote.h"
|
||||
#include "spawn-pipe.h"
|
||||
#include "wait-process.h"
|
||||
#include "xvasprintf.h"
|
||||
#include "x-po.h"
|
||||
#include "xgettext.h"
|
||||
#include "xg-message.h"
|
||||
#include "c-strstr.h"
|
||||
#include "read-catalog-abstract.h"
|
||||
#include "error.h"
|
||||
#include "gettext.h"
|
||||
|
||||
/* A convenience macro. I don't like writing gettext() every time. */
|
||||
#define _(str) gettext (str)
|
||||
|
||||
/* The Ruby syntax is defined in
|
||||
https://ruby-doc.org/core-2.7.1/doc/syntax_rdoc.html
|
||||
https://ruby-doc.org/core-2.7.1/doc/syntax/comments_rdoc.html
|
||||
https://ruby-doc.org/core-2.7.1/doc/syntax/literals_rdoc.html
|
||||
We don't parse Ruby directly, but instead rely on the 'rxgettext' program
|
||||
from https://github.com/ruby-gettext/gettext . */
|
||||
|
||||
|
||||
/* ====================== Keyword set customization. ====================== */
|
||||
|
||||
/* This function currently has no effect. */
|
||||
void
|
||||
x_ruby_extract_all (void)
|
||||
{
|
||||
}
|
||||
|
||||
/* This function currently has no effect. */
|
||||
void
|
||||
x_ruby_keyword (const char *keyword)
|
||||
{
|
||||
}
|
||||
|
||||
/* This function currently has no effect. */
|
||||
void
|
||||
init_flag_table_ruby (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* ========================= Extracting strings. ========================== */
|
||||
|
||||
void
|
||||
extract_ruby (const char *real_filename, const char *logical_filename,
|
||||
flag_context_list_table_ty *flag_table,
|
||||
msgdomain_list_ty *mdlp)
|
||||
{
|
||||
const char *progname = "rxgettext";
|
||||
char *dummy_filename;
|
||||
msgdomain_list_ty *mdlp2;
|
||||
int pass;
|
||||
|
||||
dummy_filename = xasprintf (_("(output from '%s')"), progname);
|
||||
|
||||
/* Invoke rgettext twice:
|
||||
1. to get the messages, without ruby-format flags.
|
||||
2. to get the 'xgettext:' comments that guide us while adding
|
||||
[no-]ruby-format flags. */
|
||||
mdlp2 = msgdomain_list_alloc (true);
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
{
|
||||
char *argv[4];
|
||||
unsigned int i;
|
||||
pid_t child;
|
||||
int fd[1];
|
||||
FILE *fp;
|
||||
int exitstatus;
|
||||
|
||||
/* Prepare arguments. */
|
||||
argv[0] = (char *) progname;
|
||||
i = 1;
|
||||
|
||||
if (pass > 0)
|
||||
argv[i++] = (char *) "--add-comments=xgettext:";
|
||||
else
|
||||
{
|
||||
if (add_all_comments)
|
||||
argv[i++] = (char *) "--add-comments";
|
||||
else if (comment_tag != NULL)
|
||||
argv[i++] = xasprintf ("--add-comments=%s", comment_tag);
|
||||
}
|
||||
|
||||
argv[i++] = (char *) real_filename;
|
||||
|
||||
argv[i] = NULL;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
char *command = shell_quote_argv (argv);
|
||||
error (0, 0, "%s", command);
|
||||
free (command);
|
||||
}
|
||||
|
||||
child = create_pipe_in (progname, progname, argv,
|
||||
DEV_NULL, false, true, true, fd);
|
||||
|
||||
fp = fdopen (fd[0], "r");
|
||||
if (fp == NULL)
|
||||
error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
|
||||
/* Read the resulting PO file. */
|
||||
extract_po (fp, dummy_filename, dummy_filename, flag_table,
|
||||
pass == 0 ? mdlp : mdlp2);
|
||||
|
||||
fclose (fp);
|
||||
|
||||
/* Remove zombie process from process list, and retrieve exit status. */
|
||||
exitstatus =
|
||||
wait_subprocess (child, progname, false, false, true, true, NULL);
|
||||
if (exitstatus != 0)
|
||||
error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"),
|
||||
progname, exitstatus);
|
||||
}
|
||||
|
||||
/* Add [no-]ruby-format flags and process 'xgettext:' comments.
|
||||
This processing is similar to the one done in remember_a_message(). */
|
||||
if (mdlp->nitems == 1 && mdlp2->nitems == 1)
|
||||
{
|
||||
message_list_ty *mlp = mdlp->item[0]->messages;
|
||||
message_list_ty *mlp2 = mdlp2->item[0]->messages;
|
||||
size_t j;
|
||||
|
||||
for (j = 0; j < mlp->nitems; j++)
|
||||
{
|
||||
message_ty *mp = mlp->item[j];
|
||||
|
||||
if (!is_header (mp))
|
||||
{
|
||||
/* Find 'xgettext:' comments and apply them to mp. */
|
||||
message_ty *mp2 =
|
||||
message_list_search (mlp2, mp->msgctxt, mp->msgid);
|
||||
|
||||
if (mp2 != NULL && mp2->comment_dot != NULL)
|
||||
{
|
||||
string_list_ty *mp2_comment_dot = mp2->comment_dot;
|
||||
size_t k;
|
||||
|
||||
for (k = 0; k < mp2_comment_dot->nitems; k++)
|
||||
{
|
||||
const char *s = mp2_comment_dot->item[k];
|
||||
|
||||
/* To reduce the possibility of unwanted matches we do a
|
||||
two step match: the line must contain 'xgettext:' and
|
||||
one of the possible format description strings. */
|
||||
const char *t = c_strstr (s, "xgettext:");
|
||||
if (t != NULL)
|
||||
{
|
||||
bool tmp_fuzzy;
|
||||
enum is_format tmp_format[NFORMATS];
|
||||
struct argument_range tmp_range;
|
||||
enum is_wrap tmp_wrap;
|
||||
enum is_syntax_check tmp_syntax_check[NSYNTAXCHECKS];
|
||||
bool interesting;
|
||||
size_t i;
|
||||
|
||||
t += strlen ("xgettext:");
|
||||
|
||||
po_parse_comment_special (t, &tmp_fuzzy, tmp_format,
|
||||
&tmp_range, &tmp_wrap,
|
||||
tmp_syntax_check);
|
||||
|
||||
interesting = false;
|
||||
for (i = 0; i < NFORMATS; i++)
|
||||
if (tmp_format[i] != undecided)
|
||||
{
|
||||
mp->is_format[i] = tmp_format[i];
|
||||
interesting = true;
|
||||
}
|
||||
if (has_range_p (tmp_range))
|
||||
{
|
||||
intersect_range (mp, &tmp_range);
|
||||
interesting = true;
|
||||
}
|
||||
if (tmp_wrap != undecided)
|
||||
{
|
||||
mp->do_wrap = tmp_wrap;
|
||||
interesting = true;
|
||||
}
|
||||
for (i = 0; i < NSYNTAXCHECKS; i++)
|
||||
if (tmp_syntax_check[i] != undecided)
|
||||
{
|
||||
mp->do_syntax_check[i] = tmp_syntax_check[i];
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
/* If the "xgettext:" marker was followed by an
|
||||
interesting keyword, and we updated our
|
||||
is_format/do_wrap variables, eliminate the comment
|
||||
from the #. comments. */
|
||||
if (interesting)
|
||||
if (mp->comment_dot != NULL)
|
||||
{
|
||||
const char *removed =
|
||||
string_list_remove (mp->comment_dot, s);
|
||||
|
||||
if (removed != NULL)
|
||||
free ((char *) removed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now evaluate the consequences of the 'xgettext:' comments, */
|
||||
decide_is_format (mp);
|
||||
decide_do_wrap (mp);
|
||||
decide_syntax_check (mp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msgdomain_list_free (mdlp2);
|
||||
|
||||
free (dummy_filename);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/* xgettext Ruby backend.
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2020.
|
||||
|
||||
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 3 of the License, 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, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "message.h"
|
||||
#include "xg-arglist-context.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define EXTENSIONS_RUBY \
|
||||
{ "rb", "Ruby" }, \
|
||||
|
||||
#define SCANNERS_RUBY \
|
||||
{ "Ruby", NULL, extract_ruby, \
|
||||
&flag_table_ruby, &formatstring_ruby, NULL }, \
|
||||
|
||||
extern void extract_ruby (const char *real_filename,
|
||||
const char *logical_filename,
|
||||
flag_context_list_table_ty *flag_table,
|
||||
msgdomain_list_ty *mdlp);
|
||||
|
||||
extern void x_ruby_keyword (const char *keyword);
|
||||
extern void x_ruby_extract_all (void);
|
||||
|
||||
extern void init_flag_table_ruby (void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -106,6 +106,7 @@
|
||||
#include "x-tcl.h"
|
||||
#include "x-perl.h"
|
||||
#include "x-php.h"
|
||||
#include "x-ruby.h"
|
||||
#include "x-stringtable.h"
|
||||
#include "x-rst.h"
|
||||
#include "x-glade.h"
|
||||
@@ -166,6 +167,9 @@ static catalog_output_format_ty output_syntax = &output_format_po;
|
||||
/* If nonzero omit header with information about this run. */
|
||||
int xgettext_omit_header;
|
||||
|
||||
/* Be more verbose. */
|
||||
int verbose = 0;
|
||||
|
||||
/* Table of flag_context_list_ty tables. */
|
||||
static flag_context_list_table_ty flag_table_c;
|
||||
static flag_context_list_table_ty flag_table_cxx_qt;
|
||||
@@ -186,6 +190,7 @@ static flag_context_list_table_ty flag_table_ycp;
|
||||
static flag_context_list_table_ty flag_table_tcl;
|
||||
static flag_context_list_table_ty flag_table_perl;
|
||||
static flag_context_list_table_ty flag_table_php;
|
||||
static flag_context_list_table_ty flag_table_ruby;
|
||||
static flag_context_list_table_ty flag_table_lua;
|
||||
static flag_context_list_table_ty flag_table_javascript;
|
||||
static flag_context_list_table_ty flag_table_vala;
|
||||
@@ -210,7 +215,7 @@ static locating_rule_list_ty *its_locating_rules;
|
||||
" <its:translateRule selector=\"/*\" translate=\"no\"/>" \
|
||||
"</its:rules>"
|
||||
|
||||
/* If nonzero add comments used by itstool. */
|
||||
/* If nonzero add comments used by itstool. */
|
||||
static bool add_itstool_comments = false;
|
||||
|
||||
/* Long options. */
|
||||
@@ -263,6 +268,7 @@ static const struct option long_options[] =
|
||||
{ "stringtable-output", no_argument, NULL, CHAR_MAX + 7 },
|
||||
{ "style", required_argument, NULL, CHAR_MAX + 15 },
|
||||
{ "trigraphs", no_argument, NULL, 'T' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "width", required_argument, NULL, 'w' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
@@ -373,12 +379,13 @@ main (int argc, char *argv[])
|
||||
init_flag_table_tcl ();
|
||||
init_flag_table_perl ();
|
||||
init_flag_table_php ();
|
||||
init_flag_table_ruby ();
|
||||
init_flag_table_lua ();
|
||||
init_flag_table_javascript ();
|
||||
init_flag_table_vala ();
|
||||
|
||||
while ((optchar = getopt_long (argc, argv,
|
||||
"ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTVw:W:x:",
|
||||
"ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTvVw:W:x:",
|
||||
long_options, NULL)) != EOF)
|
||||
switch (optchar)
|
||||
{
|
||||
@@ -399,6 +406,7 @@ main (int argc, char *argv[])
|
||||
x_tcl_extract_all ();
|
||||
x_perl_extract_all ();
|
||||
x_php_extract_all ();
|
||||
x_ruby_extract_all ();
|
||||
x_lua_extract_all ();
|
||||
x_javascript_extract_all ();
|
||||
x_vala_extract_all ();
|
||||
@@ -478,6 +486,7 @@ main (int argc, char *argv[])
|
||||
x_tcl_keyword (optarg);
|
||||
x_perl_keyword (optarg);
|
||||
x_php_keyword (optarg);
|
||||
x_ruby_keyword (optarg);
|
||||
x_lua_keyword (optarg);
|
||||
x_javascript_keyword (optarg);
|
||||
x_vala_keyword (optarg);
|
||||
@@ -541,6 +550,10 @@ main (int argc, char *argv[])
|
||||
x_c_trigraphs ();
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
do_version = true;
|
||||
break;
|
||||
@@ -1073,8 +1086,8 @@ Choice of input file language:\n"));
|
||||
(C, C++, ObjectiveC, PO, Shell, Python, Lisp,\n\
|
||||
EmacsLisp, librep, Scheme, Smalltalk, Java,\n\
|
||||
JavaProperties, C#, awk, YCP, Tcl, Perl, PHP,\n\
|
||||
GCC-source, NXStringTable, RST, RSJ, Glade,\n\
|
||||
Lua, JavaScript, Vala, Desktop)\n"));
|
||||
Ruby, GCC-source, NXStringTable, RST, RSJ,\n\
|
||||
Glade, Lua, JavaScript, Vala, Desktop)\n"));
|
||||
printf (_("\
|
||||
-C, --c++ shorthand for --language=C++\n"));
|
||||
printf (_("\
|
||||
@@ -1218,6 +1231,8 @@ Informative output:\n"));
|
||||
-h, --help display this help and exit\n"));
|
||||
printf (_("\
|
||||
-V, --version output version information and exit\n"));
|
||||
printf (_("\
|
||||
-v, --verbose increase verbosity level\n"));
|
||||
printf ("\n");
|
||||
/* TRANSLATORS: The first placeholder is the web address of the Savannah
|
||||
project of this package. The second placeholder is the bug-reporting
|
||||
@@ -1555,6 +1570,11 @@ xgettext_record_flag (const char *optionstring)
|
||||
name_start, name_end,
|
||||
argnum, value, pass);
|
||||
break;
|
||||
case format_ruby:
|
||||
flag_context_list_table_insert (&flag_table_ruby, 0,
|
||||
name_start, name_end,
|
||||
argnum, value, pass);
|
||||
break;
|
||||
case format_gcc_internal:
|
||||
flag_context_list_table_insert (&flag_table_gcc_internal, 0,
|
||||
name_start, name_end,
|
||||
@@ -2126,6 +2146,7 @@ language_to_extractor (const char *name)
|
||||
SCANNERS_TCL
|
||||
SCANNERS_PERL
|
||||
SCANNERS_PHP
|
||||
SCANNERS_RUBY
|
||||
SCANNERS_STRINGTABLE
|
||||
SCANNERS_RST
|
||||
SCANNERS_GLADE
|
||||
@@ -2217,6 +2238,7 @@ extension_to_language (const char *extension)
|
||||
EXTENSIONS_TCL
|
||||
EXTENSIONS_PERL
|
||||
EXTENSIONS_PHP
|
||||
EXTENSIONS_RUBY
|
||||
EXTENSIONS_STRINGTABLE
|
||||
EXTENSIONS_RST
|
||||
EXTENSIONS_GLADE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* xgettext common functions.
|
||||
Copyright (C) 2001-2003, 2005-2006, 2008-2009, 2011, 2013-2014, 2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001-2003, 2005-2006, 2008-2009, 2011, 2013-2014, 2018, 2020 Free Software Foundation, Inc.
|
||||
Written by Peter Miller <millerp@canb.auug.org.au>
|
||||
and Bruno Haible <haible@clisp.cons.org>, 2001.
|
||||
|
||||
@@ -50,6 +50,9 @@ extern const char *msgstr_suffix;
|
||||
If false, keep the header entry present in the input. */
|
||||
extern int xgettext_omit_header;
|
||||
|
||||
/* Be more verbose. */
|
||||
extern int verbose;
|
||||
|
||||
extern enum is_syntax_check default_syntax_check[NSYNTAXCHECKS];
|
||||
|
||||
/* Language dependent format string parser.
|
||||
|
||||
@@ -108,6 +108,7 @@ TESTS = gettext-1 gettext-2 \
|
||||
xgettext-rst-1 xgettext-rst-2 \
|
||||
xgettext-python-1 xgettext-python-2 xgettext-python-3 \
|
||||
xgettext-python-4 \
|
||||
xgettext-ruby-1 \
|
||||
xgettext-scheme-1 xgettext-scheme-2 xgettext-scheme-3 \
|
||||
xgettext-scheme-4 \
|
||||
xgettext-sh-1 xgettext-sh-2 xgettext-sh-3 xgettext-sh-4 xgettext-sh-5 \
|
||||
@@ -146,6 +147,7 @@ TESTS = gettext-1 gettext-2 \
|
||||
format-perl-mixed-1 format-perl-mixed-2 \
|
||||
format-qt-1 format-qt-2 \
|
||||
format-qt-plural-1 format-qt-plural-2 \
|
||||
format-ruby-1 format-ruby-2 \
|
||||
format-scheme-1 format-scheme-2 \
|
||||
format-sh-1 format-sh-2 \
|
||||
format-tcl-1 format-tcl-2 \
|
||||
|
||||
Executable
+304
@@ -0,0 +1,304 @@
|
||||
#! /bin/sh
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ . ../src
|
||||
|
||||
# Test recognition of Ruby format strings.
|
||||
|
||||
(rxgettext --version) >/dev/null 2>/dev/null \
|
||||
|| { echo "Skipping test: rxgettext not found"; Exit 77; }
|
||||
|
||||
cat <<\EOF > f-r-1.data
|
||||
# Valid: no argument
|
||||
"abc%%"
|
||||
# Valid: one string argument (unnumbered)
|
||||
"abc%s"
|
||||
# Valid: one string argument (numbered)
|
||||
"abc%1$s"
|
||||
# Valid: one string argument (named)
|
||||
"abc%<foo>s"
|
||||
# Valid: one string argument (named)
|
||||
"abc%{foo}"
|
||||
# Valid: one escaped string argument (unnumbered)
|
||||
"abc%p"
|
||||
# Valid: one escaped string argument (numbered)
|
||||
"abc%1$p"
|
||||
# Valid: one escaped string argument (named)
|
||||
"abc%<foo>p"
|
||||
# Valid: one character argument (unnumbered)
|
||||
"abc%c"
|
||||
# Valid: one character argument (numbered)
|
||||
"abc%1$c"
|
||||
# Valid: one character argument (named)
|
||||
"abc%<foo>c"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%d"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$d"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>d"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%i"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$i"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>i"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%u"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$u"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>u"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%o"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$o"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>o"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%x"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$x"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>x"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%X"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$X"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>X"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%b"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$b"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>b"
|
||||
# Valid: one integer argument (unnumbered)
|
||||
"abc%B"
|
||||
# Valid: one integer argument (numbered)
|
||||
"abc%1$B"
|
||||
# Valid: one integer argument (named)
|
||||
"abc%<foo>B"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%f"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$f"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>f"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%g"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$g"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>g"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%G"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$G"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>G"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%e"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$e"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>e"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%E"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$E"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>E"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%a"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$a"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>a"
|
||||
# Valid: one floating-point argument (unnumbered)
|
||||
"abc%A"
|
||||
# Valid: one floating-point argument (numbered)
|
||||
"abc%1$A"
|
||||
# Valid: one floating-point argument (named)
|
||||
"abc%<foo>A"
|
||||
# Valid: one argument with flags (unnumbered)
|
||||
"abc%0#g"
|
||||
# Valid: one argument with flags (numbered)
|
||||
"abc%1$0#g"
|
||||
# Valid: one argument with flags (numbered)
|
||||
"abc%0#1$g"
|
||||
# Valid: one argument with flags (named)
|
||||
"abc%<foo>0#g"
|
||||
# Valid: one argument with flags (named)
|
||||
"abc%0#<foo>g"
|
||||
# Valid: one argument with width (unnumbered)
|
||||
"abc%2g"
|
||||
# Valid: one argument with width (numbered)
|
||||
"abc%1$2g"
|
||||
# Valid: one argument with width (named)
|
||||
"abc%<foo>2g"
|
||||
# Valid: one argument with width (named)
|
||||
"abc%2<foo>g"
|
||||
# Valid: one argument with width (unnumbered)
|
||||
"abc%*g"
|
||||
# Valid: one argument with width (numbered)
|
||||
"abc%2$*1$g"
|
||||
# Valid: one argument with precision (unnumbered)
|
||||
"abc%.4g"
|
||||
# Valid: one argument with precision (numbered)
|
||||
"abc%1$.4g"
|
||||
# Valid: one argument with precision (named)
|
||||
"abc%<foo>.4g"
|
||||
# Valid: one argument with precision (named)
|
||||
"abc%.4<foo>g"
|
||||
# Valid: one argument with precision (unnumbered)
|
||||
"abc%.*g"
|
||||
# Valid: one argument with precision (numbered)
|
||||
"abc%2$.*1$g"
|
||||
# Valid: one argument with width and precision (unnumbered)
|
||||
"abc%14.4g"
|
||||
# Valid: one argument with width and precision (numbered)
|
||||
"abc%1$14.4g"
|
||||
# Valid: one argument with width and precision (named)
|
||||
"abc%<foo>14.4g"
|
||||
# Valid: one argument with width and precision (named)
|
||||
"abc%14<foo>.4g"
|
||||
# Valid: one argument with width and precision (named)
|
||||
"abc%14.4<foo>g"
|
||||
# Valid: one argument with width and precision (unnumbered)
|
||||
"abc%14.*g"
|
||||
# Valid: one argument with width and precision (numbered)
|
||||
"abc%2$14.*1$g"
|
||||
# Valid: one argument with width and precision (unnumbered)
|
||||
"abc%*.4g"
|
||||
# Valid: one argument with width and precision (numbered)
|
||||
"abc%2$*1$.4g"
|
||||
# Valid: one argument with width and precision (unnumbered)
|
||||
"abc%*.*g"
|
||||
# Valid: one argument with width and precision (numbered)
|
||||
"abc%3$*1$.*2$g"
|
||||
# Invalid: unterminated directive
|
||||
"abc%"
|
||||
# Invalid: unterminated name
|
||||
"abc%<value"
|
||||
# Invalid: unterminated name
|
||||
"abc%{value"
|
||||
# Invalid: unterminated directive
|
||||
"abc%<value>"
|
||||
# Invalid: unknown format specifier (unnumbered)
|
||||
"abc%y"
|
||||
# Invalid: mixing unnumbered and numbered in the same directive
|
||||
"abc%2$*g"
|
||||
# Invalid: mixing unnumbered and numbered in the same directive
|
||||
"abc%*1$g"
|
||||
# Invalid: mixing unnumbered and numbered in the same directive
|
||||
"abc%2$.*g"
|
||||
# Invalid: mixing unnumbered and numbered in the same directive
|
||||
"abc%.*1$g"
|
||||
# Invalid: mixing unnumbered and numbered in different directives
|
||||
"abc%d%2$g"
|
||||
# Invalid: mixing unnumbered and numbered in different directives
|
||||
"abc%1$d%g"
|
||||
# Invalid: mixing unnumbered and named in the same directive
|
||||
"abc%*<foo>g"
|
||||
# Invalid: mixing unnumbered and named in the same directive
|
||||
"abc%.*<foo>g"
|
||||
# Invalid: mixing unnumbered and named in different directives
|
||||
"abc%d%<foo>g"
|
||||
# Invalid: mixing unnumbered and named in different directives
|
||||
"abc%<foo>d%g"
|
||||
# Invalid: mixing numbered and named in the same directive
|
||||
"abc%*1$<foo>g"
|
||||
# Invalid: mixing numbered and named in the same directive
|
||||
"abc%.*1$<foo>g"
|
||||
# Invalid: mixing numbered and named in different directives
|
||||
"abc%2$d%<foo>g"
|
||||
# Invalid: mixing numbered and named in different directives
|
||||
"abc%<foo>d%2$g"
|
||||
# Invalid: flags after width (unnumbered)
|
||||
"abc%*0g"
|
||||
# Invalid: flags after width (numbered)
|
||||
"abc%2$*1$0g"
|
||||
# Invalid: flags after precision (unnumbered)
|
||||
"abc%.*0g"
|
||||
# Invalid: flags after precision (numbered)
|
||||
"abc%2$.*1$0g"
|
||||
# Invalid: width after precision (unnumbered)
|
||||
"abc%.*14g"
|
||||
# Invalid: width after precision (unnumbered)
|
||||
"abc%.4*g"
|
||||
# Invalid: width after precision (unnumbered)
|
||||
"abc%.**g"
|
||||
# Invalid: width after precision (numbered)
|
||||
"abc%2$.*1$14g"
|
||||
# Invalid: width after precision (numbered)
|
||||
"abc%2$.4*1$g"
|
||||
# Invalid: width after precision (numbered)
|
||||
"abc%3$.*1$*2$g"
|
||||
# Invalid: twice width (unnumbered)
|
||||
"abc%2*g"
|
||||
# Invalid: twice width (unnumbered)
|
||||
"abc%*2g"
|
||||
# Invalid: twice width (numbered)
|
||||
"abc%2$2*1$g"
|
||||
# Invalid: twice width (numbered)
|
||||
"abc%2$*1$2g"
|
||||
# Invalid: twice precision (unnumbered)
|
||||
"abc%.4.2g"
|
||||
# Invalid: twice precision (numbered)
|
||||
"abc%1$.4.2g"
|
||||
# Valid: three arguments
|
||||
"abc%d%u%u"
|
||||
# Valid: an unused argument
|
||||
"abc%2$d%3$u"
|
||||
# Valid: a named argument
|
||||
"abc%<value>d"
|
||||
# Valid: a named argument
|
||||
"abc%{value}"
|
||||
# Valid: an empty name
|
||||
"abc%<>d"
|
||||
# Valid: an empty name
|
||||
"abc%{}"
|
||||
# Valid: ignored named argument
|
||||
"abc%<dummy>%"
|
||||
# Valid: three arguments, two with equal names
|
||||
"abc%<addr>4x,%<char>c,%<addr>u"
|
||||
# Invalid: argument with conflicting types
|
||||
"abc%<addr>4x,%<char>c,%<addr>s"
|
||||
# Valid: no conflict
|
||||
"abc%<addr>s,%{addr}"
|
||||
EOF
|
||||
|
||||
: ${XGETTEXT=xgettext}
|
||||
n=0
|
||||
while read comment; do
|
||||
read string
|
||||
n=`expr $n + 1`
|
||||
cat <<EOF > f-r-1-$n.in
|
||||
gettext(${string});
|
||||
EOF
|
||||
${XGETTEXT} -L Ruby -o f-r-1-$n.po f-r-1-$n.in || Exit 1
|
||||
test -f f-r-1-$n.po || Exit 1
|
||||
fail=
|
||||
if echo "$comment" | grep 'Valid:' > /dev/null; then
|
||||
if grep ruby-format f-r-1-$n.po > /dev/null; then
|
||||
:
|
||||
else
|
||||
fail=yes
|
||||
fi
|
||||
else
|
||||
if grep ruby-format f-r-1-$n.po > /dev/null; then
|
||||
fail=yes
|
||||
else
|
||||
:
|
||||
fi
|
||||
fi
|
||||
if test -n "$fail"; then
|
||||
echo "Format string recognition error:" 1>&2
|
||||
cat f-r-1-$n.in 1>&2
|
||||
echo "Got:" 1>&2
|
||||
cat f-r-1-$n.po 1>&2
|
||||
Exit 1
|
||||
fi
|
||||
rm -f f-r-1-$n.in f-r-1-$n.po
|
||||
done < f-r-1.data
|
||||
|
||||
Exit 0
|
||||
Executable
+361
@@ -0,0 +1,361 @@
|
||||
#! /bin/sh
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ . ../src
|
||||
|
||||
# Test checking of Ruby format strings.
|
||||
|
||||
cat <<\EOF > f-r-2.data
|
||||
# Valid: %% doesn't count
|
||||
msgid "abc%%def"
|
||||
msgstr "xyz"
|
||||
# Invalid: invalid msgstr
|
||||
msgid "abc%%def"
|
||||
msgstr "xyz%"
|
||||
# Valid: same arguments, with different widths (argument list)
|
||||
msgid "abc%2sdef"
|
||||
msgstr "xyz%3s"
|
||||
# Valid: same arguments, with different widths (argument list)
|
||||
msgid "abc%2sdef"
|
||||
msgstr "xyz%1$3s"
|
||||
# Valid: same arguments, with different widths (named)
|
||||
msgid "abc%<foo>2sdef"
|
||||
msgstr "xyz%<foo>3s"
|
||||
# Valid: same arguments, with different widths (named)
|
||||
msgid "abc%<date>5s%<time>4s"
|
||||
msgstr "xyz%<date>4s%<time>5s"
|
||||
# Invalid: too few arguments (argument list)
|
||||
msgid "abc%sdef%u"
|
||||
msgstr "xyz%s"
|
||||
# Invalid: too few arguments (named)
|
||||
msgid "abc%<foo>sdef%<bar>u"
|
||||
msgstr "xyz%<foo>s"
|
||||
# Invalid: too many arguments (argument list)
|
||||
msgid "abc%udef"
|
||||
msgstr "xyz%uvw%c"
|
||||
# Invalid: too many arguments (named)
|
||||
msgid "abc%<foo>udef"
|
||||
msgstr "xyz%<foo>uvw%<bar>c"
|
||||
# Valid: permutation (argument list)
|
||||
msgid "abc%3$d%1$c%2$sdef"
|
||||
msgstr "xyz%2$s%1$c%3$d"
|
||||
# Valid: permutation (named)
|
||||
msgid "abc%<3>d%<1>c%<2>sdef"
|
||||
msgstr "xyz%<2>s%<1>c%<3>d"
|
||||
# Invalid: missing argument (named)
|
||||
msgid "abc%<2>sdef%<1>u"
|
||||
msgstr "xyz%<1>u"
|
||||
# Invalid: missing argument (named)
|
||||
msgid "abc%<1>sdef%<2>u"
|
||||
msgstr "xyz%<2>u"
|
||||
# Invalid: added argument (named)
|
||||
msgid "abc%<foo>udef"
|
||||
msgstr "xyz%<foo>uvw%<char>c"
|
||||
# Invalid: added argument (named)
|
||||
msgid "abc%<foo>udef"
|
||||
msgstr "xyz%<zoo>cvw%<foo>u"
|
||||
# Invalid: unnamed vs. named arguments
|
||||
msgid "abc%sdef"
|
||||
msgstr "xyz%<value>s"
|
||||
# Invalid: named vs. unnamed arguments
|
||||
msgid "abc%{value}def"
|
||||
msgstr "xyz%s"
|
||||
# Valid: unnumbered vs. numbered arguments
|
||||
msgid "abc%sdef%d"
|
||||
msgstr "xyz%2$duvw%1$s"
|
||||
# Valid: numbered vs. unnumbered arguments
|
||||
msgid "abc%1$sdef%2$d"
|
||||
msgstr "xyz%suvw%d"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%i"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%u"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%o"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%x"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%X"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%b"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%d"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%u"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%o"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%x"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%X"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%b"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%u"
|
||||
msgstr "xyz%o"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%u"
|
||||
msgstr "xyz%x"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%u"
|
||||
msgstr "xyz%X"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%u"
|
||||
msgstr "xyz%b"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%u"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%o"
|
||||
msgstr "xyz%x"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%o"
|
||||
msgstr "xyz%X"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%o"
|
||||
msgstr "xyz%b"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%o"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%x"
|
||||
msgstr "xyz%X"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%x"
|
||||
msgstr "xyz%b"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%x"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%X"
|
||||
msgstr "xyz%b"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%X"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%b"
|
||||
msgstr "xyz%B"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%f"
|
||||
msgstr "xyz%g"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%f"
|
||||
msgstr "xyz%G"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%f"
|
||||
msgstr "xyz%e"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%f"
|
||||
msgstr "xyz%E"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%f"
|
||||
msgstr "xyz%a"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%f"
|
||||
msgstr "xyz%A"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%g"
|
||||
msgstr "xyz%G"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%g"
|
||||
msgstr "xyz%e"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%g"
|
||||
msgstr "xyz%E"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%g"
|
||||
msgstr "xyz%a"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%g"
|
||||
msgstr "xyz%A"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%G"
|
||||
msgstr "xyz%e"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%G"
|
||||
msgstr "xyz%E"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%G"
|
||||
msgstr "xyz%a"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%G"
|
||||
msgstr "xyz%A"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%e"
|
||||
msgstr "xyz%E"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%e"
|
||||
msgstr "xyz%a"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%e"
|
||||
msgstr "xyz%A"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%E"
|
||||
msgstr "xyz%a"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%E"
|
||||
msgstr "xyz%A"
|
||||
# Valid: type compatibility (argument list)
|
||||
msgid "abc%a"
|
||||
msgstr "xyz%A"
|
||||
# Valid: type compatibility (named)
|
||||
msgid "abc%<foo>d"
|
||||
msgstr "xyz%<foo>x"
|
||||
# Valid: type compatibility (named)
|
||||
msgid "abc%<foo>s"
|
||||
msgstr "xyz%{foo}"
|
||||
# Valid: type compatibility (named)
|
||||
msgid "abc%{foo}"
|
||||
msgstr "xyz%<foo>s"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%c"
|
||||
msgstr "xyz%s"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%c"
|
||||
msgstr "xyz%.0s"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%c"
|
||||
msgstr "xyz%p"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%c"
|
||||
msgstr "xyz%i"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%c"
|
||||
msgstr "xyz%e"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%s"
|
||||
msgstr "xyz%p"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%s"
|
||||
msgstr "xyz%i"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%.0s"
|
||||
msgstr "xyz%i"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%s"
|
||||
msgstr "xyz%e"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%.0s"
|
||||
msgstr "xyz%e"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%p"
|
||||
msgstr "xyz%i"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%p"
|
||||
msgstr "xyz%e"
|
||||
# Invalid: type incompatibility (argument list)
|
||||
msgid "abc%i"
|
||||
msgstr "xyz%e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%<foo>s"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%{foo}"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%<foo>.0s"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%.0{foo}"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%<foo>p"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%<foo>i"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>c"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>s"
|
||||
msgstr "xyz%<foo>p"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%{foo}"
|
||||
msgstr "xyz%<foo>p"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>s"
|
||||
msgstr "xyz%<foo>i"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%{foo}"
|
||||
msgstr "xyz%<foo>i"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>.0s"
|
||||
msgstr "xyz%<foo>i"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%.0{foo}"
|
||||
msgstr "xyz%<foo>i"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>s"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%{foo}"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>.0s"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%.0{foo}"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>p"
|
||||
msgstr "xyz%<foo>i"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>p"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility (named)
|
||||
msgid "abc%<foo>i"
|
||||
msgstr "xyz%<foo>e"
|
||||
# Invalid: type incompatibility for width (argument list)
|
||||
msgid "abc%g%*g"
|
||||
msgstr "xyz%*g%g"
|
||||
EOF
|
||||
|
||||
: ${MSGFMT=msgfmt}
|
||||
n=0
|
||||
while read comment; do
|
||||
read msgid_line
|
||||
read msgstr_line
|
||||
n=`expr $n + 1`
|
||||
cat <<EOF > f-r-2-$n.po
|
||||
#, ruby-format
|
||||
${msgid_line}
|
||||
${msgstr_line}
|
||||
EOF
|
||||
fail=
|
||||
if echo "$comment" | grep 'Valid:' > /dev/null; then
|
||||
if ${MSGFMT} --check-format -o f-r-2-$n.mo f-r-2-$n.po; then
|
||||
:
|
||||
else
|
||||
fail=yes
|
||||
fi
|
||||
else
|
||||
${MSGFMT} --check-format -o f-r-2-$n.mo f-r-2-$n.po 2> /dev/null
|
||||
if test $? = 1; then
|
||||
:
|
||||
else
|
||||
fail=yes
|
||||
fi
|
||||
fi
|
||||
if test -n "$fail"; then
|
||||
echo "Format string checking error:" 1>&2
|
||||
cat f-r-2-$n.po 1>&2
|
||||
Exit 1
|
||||
fi
|
||||
rm -f f-r-2-$n.po f-r-2-$n.mo
|
||||
done < f-r-2.data
|
||||
|
||||
Exit 0
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ . ../src
|
||||
|
||||
# Test of Ruby support.
|
||||
|
||||
(rxgettext --version) >/dev/null 2>/dev/null \
|
||||
|| { echo "Skipping test: rxgettext not found"; Exit 77; }
|
||||
|
||||
cat <<\EOF > xg-ru-1.rb
|
||||
_("abc")
|
||||
# Some comment.
|
||||
_("abc%%def")
|
||||
_("abc%{foo}def")
|
||||
# xgettext: no-ruby-format
|
||||
_("abc%{bar}def")
|
||||
_("some %d people")
|
||||
EOF
|
||||
|
||||
: ${XGETTEXT=xgettext}
|
||||
${XGETTEXT} --add-comments --no-location -o xg-ru-1.tmp xg-ru-1.rb 2>xg-ru-1.err
|
||||
test $? = 0 || { cat xg-ru-1.err; Exit 1; }
|
||||
func_filter_POT_Creation_Date xg-ru-1.tmp xg-ru-1.pot
|
||||
|
||||
cat <<\EOF > xg-ru-1.ok
|
||||
# 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 <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "abc"
|
||||
msgstr ""
|
||||
|
||||
#. Some comment.
|
||||
#, ruby-format
|
||||
msgid "abc%%def"
|
||||
msgstr ""
|
||||
|
||||
#, ruby-format
|
||||
msgid "abc%{foo}def"
|
||||
msgstr ""
|
||||
|
||||
#, no-ruby-format
|
||||
msgid "abc%{bar}def"
|
||||
msgstr ""
|
||||
|
||||
#, ruby-format
|
||||
msgid "some %d people"
|
||||
msgstr ""
|
||||
EOF
|
||||
|
||||
: ${DIFF=diff}
|
||||
${DIFF} xg-ru-1.ok xg-ru-1.pot
|
||||
result=$?
|
||||
|
||||
exit $result
|
||||
Reference in New Issue
Block a user