Support for JavaScript.

This commit is contained in:
Andreas Stricker 2010-02-23 14:14:09 +01:00 committed by Daiki Ueno
parent 97c6a77933
commit fe8db3b5b4
27 changed files with 2854 additions and 19 deletions

View File

@ -1,3 +1,8 @@
2013-04-17 Andreas Stricker <astricker@futurelab.ch>
Support for JavaScript.
* woe32dll/gettextsrc-exports.c: Export formatstring_javascript.
2013-04-15 Daiki Ueno <ueno@gnu.org>
* woe32dll/gettextsrc-exports.c: Export formatstring_lua.

View File

@ -1,3 +1,12 @@
2013-04-17 Andreas Stricker <astricker@futurelab.ch>
Support for JavaScript.
* gettext.texi (PO Files): Mention javascript-format.
(javascript-format): New subsection.
(JavaScript): New subsection.
* xgettext.texi: Document JavaScript source language. Document
that it is applicable to --flag.
2013-04-11 Ľubomír Remák <lubomirr@lubomirr.eu>
Support for Lua.

View File

@ -410,6 +410,7 @@ The Translator's View
* kde-format:: KDE Format Strings
* boost-format:: Boost Format Strings
* lua-format:: Lua Format Strings
* javascript-format:: JavaScript Format Strings
Individual Programming Languages
@ -435,6 +436,7 @@ Individual Programming Languages
* Pike:: Pike
* GCC-source:: GNU Compiler Collection sources
* Lua:: Lua
* JavaScript:: JavaScript
sh - Shell Script
@ -1631,6 +1633,12 @@ Likewise for Boost, see @ref{boost-format}.
@kwindex no-lua-format@r{ flag}
Likewise for Lua, see @ref{lua-format}.
@item javascript-format
@kwindex javascript-format@r{ flag}
@itemx no-javascript-format
@kwindex no-javascript-format@r{ flag}
Likewise for JavaScript, see @ref{javascript-format}.
@end table
@kwindex msgctxt
@ -8974,6 +8982,7 @@ strings.
* kde-format:: KDE Format Strings
* boost-format:: Boost Format Strings
* lua-format:: Lua Format Strings
* javascript-format:: JavaScript Format Strings
@end menu
@node c-format, objc-format, Translators for other Languages, Translators for other Languages
@ -9230,12 +9239,27 @@ such as @samp{%1$+5d}, or may be surrounded by vertical bars, such as
@samp{%|1$+5d|} or @samp{%|1$+5|}, or consists of just an argument number
between percent signs, such as @samp{%1%}.
@node lua-format, , boost-format, Translators for other Languages
@node lua-format, javascript-format, boost-format, Translators for other Languages
@subsection Lua Format Strings
Lua format strings are described in the Lua reference manual, section @w{String Manipulation},
@uref{http://www.lua.org/manual/5.1/manual.html#pdf-string.format}.
@node javascript-format, , lua-format, Translators for other Languages
@subsection JavaScript Format Strings
Although JavaScript specification itself does not define any format
strings, many JavaScript implementations provide printf-like
functions. @code{xgettext} understands a set of common format strings
used in popular JavaScript implementations including Gjs, Seed, and
Node.JS. In such a format string, a directive starts with @samp{%}
and is finished by a specifier: @samp{%} denotes a literal percent
sign, @samp{c} denotes a character, @samp{s} denotes a string,
@samp{b}, @samp{d}, @samp{o}, @samp{x}, @samp{X} denote an integer,
@samp{f} denotes floating-point number, @samp{j} denotes a JSON
object.
@node Maintainers for other Languages, List of Programming Languages, Translators for other Languages, Programming Languages
@section The Maintainer's View
@ -9340,6 +9364,7 @@ that language, and to combine the resulting files using @code{msgcat}.
* Pike:: Pike
* GCC-source:: GNU Compiler Collection sources
* Lua:: Lua
* JavaScript:: JavaScript
@end menu
@node C, sh, List of Programming Languages, List of Programming Languages
@ -11800,7 +11825,7 @@ Uses autoconf macros
yes
@end table
@node Lua, , GCC-source, List of Programming Languages
@node Lua, JavaScript, GCC-source, List of Programming Languages
@subsection Lua
@table @asis
@ -11862,6 +11887,60 @@ On platforms without gettext, the functions are not available.
---
@end table
@node JavaScript
@subsection JavaScript
@table @asis
@item RPMs
js
@item File extension
@code{js}
@item String syntax
@itemize @bullet
@item @code{"abc"}
@item @code{'abc'}
@end itemize
@item gettext shorthand
@code{_("abc")}
@item gettext/ngettext functions
@code{gettext}, @code{dgettext}, @code{dcgettext}, @code{ngettext},
@code{dngettext}
@item textdomain
@code{textdomain} function
@item bindtextdomain
@code{bindtextdomain} function
@item setlocale
automatic
@item Prerequisite
---
@item Use or emulate GNU gettext
use, or emulate
@item Extractor
@code{xgettext}
@item Formatting with positions
---
@item Portability
On platforms without gettext, the functions are not available.
@item po-mode marking
---
@end table
@c This is the template for new languages.
@ignore

View File

@ -73,7 +73,7 @@ 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{Glade}, @code{Lua}.
@code{NXStringTable}, @code{RST}, @code{Glade}, @code{Lua}, @code{JavaScript}.
@item -C
@itemx --c++
@ -137,7 +137,7 @@ Extract all strings.
This option has an effect with most languages, namely C, C++, ObjectiveC,
Shell, Python, Lisp, EmacsLisp, librep, Java, C#, awk, Tcl, Perl, PHP,
GCC-source, Glade, Lua.
GCC-source, Glade, Lua, JavaScript.
@item -k[@var{keywordspec}]
@itemx --keyword[=@var{keywordspec}]
@ -180,7 +180,7 @@ escaped.
This option has an effect with most languages, namely C, C++, ObjectiveC,
Shell, Python, Lisp, EmacsLisp, librep, Java, C#, awk, Tcl, Perl, PHP,
GCC-source, Glade, Lua.
GCC-source, Glade, Lua, JavaScript.
The default keyword specifications, which are always looked for if not
explicitly disabled, are language dependent. They are:
@ -250,6 +250,11 @@ For Glade 1: @code{label}, @code{title}, @code{text}, @code{format},
For Lua: @code{_}, @code{gettext.gettext}, @code{gettext.dgettext:2},
@code{gettext.dcgettext:2}, @code{gettext.ngettext:1,2},
@code{gettext.dngettext:2,3}, @code{gettext.dcngettext:2,3}.
@item
For JavaScript: @code{_}, @code{gettext}, @code{dgettext:2},
@code{dcgettext:2}, @code{ngettext:1,2}, @code{dngettext:2,3},
@code{pgettext:1c,2}, @code{dpgettext:2c,3}.
@end itemize
To disable the default keyword specifications, the option @samp{-k} or
@ -302,7 +307,7 @@ lead to a crash at runtime.
@*
This option has an effect with most languages, namely C, C++, ObjectiveC,
Shell, Python, Lisp, EmacsLisp, librep, Scheme, Java, C#, awk, YCP, Tcl, Perl, PHP,
GCC-source, Lua.
GCC-source, Lua, JavaScript.
@item -T
@itemx --trigraphs

View File

@ -1,3 +1,8 @@
2013-04-17 Andreas Stricker <astricker@futurelab.ch>
Support for JavaScript.
* Makefile.am (libgettextpo_la_AUXSOURCES): Add format-javascript.c.
2013-04-11 Ľubomír Remák <lubomirr@lubomirr.eu>
* Makefile.am (libgettextpo_la_AUXSOURCES): Add format-lua.c.

View File

@ -70,6 +70,7 @@ libgettextpo_la_AUXSOURCES = \
../src/format-librep.c \
../src/format-scheme.c \
../src/format-java.c \
../src/format-javascript.c \
../src/format-csharp.c \
../src/format-awk.c \
../src/format-pascal.c \

View File

@ -1,3 +1,28 @@
2013-04-17 Andreas Stricker <astricker@futurelab.ch>
Support for JavaScript.
* message.h (format_type): New enum value 'format_javascript'.
(NFORMATS): Increment.
* message.c (format_language): Add format_javascript entry.
(format_language_pretty): Likewise.
* format.h (formatstring_javascript): New declaration.
* format-javascript.c: New file.
* format.c (formatstring_parsers): Add formatstring_javascript.
* x-javascript.h: New file.
* x-javascript.c: New file.
* xgettext.c: Include x-javascript.h.
(flag_table_javascript): New variable.
(main): Invoke init_flag_table_javascript, x_javascript_extract_all,
x_javascript_keyword.
(usage): Mention JavaScript source language.
(xgettext_record_flag): Handle format_javascript.
(language_to_extractor): Add JavaScript rule.
(extension_to_language): Add JavaScript rule.
* Makefile.am (noinst_HEADERS): Add x-javascript.h.
(FORMAT_SOURCE): Add format-javascript.c.
(xgettext_SOURCES): Add x-javascript.c.
* FILES: Update.
2013-04-16 Ľubomír Remák <lubomirr@lubomirr.eu>
Support for escape sequences added in Lua 5.2.

View File

@ -234,6 +234,7 @@ format-qt-plural.c Format string handling for Qt plural forms.
format-kde.c Format string handling for KDE.
format-boost.c Format string handling for Boost.
format-lua.c Format string handling for Lua.
format-javascript.c Format string handling for JavaScript.
format.c Table of the language dependent format string handlers.
plural-exp.c
@ -337,6 +338,9 @@ msgl-check.c
| x-lua.h
| x-lua.c
| String extractor for Lua.
| x-javascript.h
| x-javascript.c
| String extractor for JavaScript.
| xgettext.c
| Main source for the 'xgettext' program.
|

View File

@ -51,7 +51,8 @@ write-qt.h \
po-time.h plural-table.h lang-table.h format.h filters.h \
xgettext.h x-c.h x-po.h x-sh.h x-python.h x-lisp.h x-elisp.h x-librep.h \
x-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-stringtable.h x-rst.h x-glade.h x-lua.h \
x-javascript.h
EXTRA_DIST += FILES project-id ChangeLog.0
@ -136,7 +137,8 @@ FORMAT_SOURCE += \
format-qt-plural.c \
format-kde.c \
format-boost.c \
format-lua.c
format-lua.c \
format-javascript.c
# libgettextsrc contains all code that is needed by at least two programs.
libgettextsrc_la_SOURCES = \
@ -174,7 +176,7 @@ endif
xgettext_SOURCES += \
x-c.c x-po.c x-sh.c x-python.c x-lisp.c x-elisp.c x-librep.c x-scheme.c \
x-smalltalk.c x-java.c x-csharp.c x-awk.c x-ycp.c x-tcl.c x-perl.c x-php.c \
x-rst.c x-glade.c x-lua.c
x-rst.c x-glade.c x-lua.c x-javascript.c
if !WOE32DLL
msgattrib_SOURCES = msgattrib.c
else

View File

@ -0,0 +1,333 @@
/* JavaScript format strings.
Copyright (C) 2001-2004, 2006-2009, 2013 Free Software Foundation, Inc.
Written by Andreas Stricker <andy@knitter.ch>, 2010.
It's based on python format module from Bruno Haible.
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 <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "format.h"
#include "c-ctype.h"
#include "xalloc.h"
#include "xvasprintf.h"
#include "format-invalid.h"
#include "gettext.h"
#define _(str) gettext (str)
/* Although JavaScript specification itself does not define any format
strings, many implementations provide printf-like functions.
We provide a permissive parser which accepts commonly used format
strings, where:
A directive
- starts with '%',
- is optionally followed by any of the characters '0', '-', ' ',
or, each of which acts as a flag,
- is optionally followed by a width specification: a nonempty digit
sequence,
- is optionally followed by '.' and a precision specification: a nonempty
digit sequence,
- is finished by a specifier
- 's', that needs a string argument,
- 'b', 'd', 'u', 'o', 'x', 'X', that need an integer argument,
- 'f', that need a floating-point argument,
- 'c', that needs a character argument.
- 'j', that needs an argument of any type.
Additionally there is the directive '%%', which takes no argument. */
enum format_arg_type
{
FAT_NONE,
FAT_ANY,
FAT_CHARACTER,
FAT_STRING,
FAT_INTEGER,
FAT_FLOAT
};
struct spec
{
unsigned int directives;
unsigned int format_args_count;
unsigned int allocated;
enum format_arg_type *format_args;
};
/* Locale independent test for a decimal digit.
Argument can be 'char' or 'unsigned char'. (Whereas the argument of
<ctype.h> isdigit must be an 'unsigned char'.) */
#undef isdigit
#define isdigit(c) ((unsigned int) ((c) - '0') < 10)
static void *
format_parse (const char *format, bool translated, char *fdi,
char **invalid_reason)
{
const char *const format_start = format;
struct spec spec;
struct spec *result;
spec.directives = 0;
spec.format_args_count = 0;
spec.allocated = 0;
spec.format_args = NULL;
for (; *format != '\0';)
if (*format++ == '%')
{
/* A directive. */
enum format_arg_type type;
FDI_SET (format - 1, FMTDIR_START);
spec.directives++;
while (*format == '-' || *format == '+' || *format == ' '
|| *format == '0' || *format == 'I')
format++;
while (isdigit (*format))
format++;
if (*format == '.')
{
format++;
while (isdigit (*format))
format++;
}
switch (*format)
{
case '%':
type = FAT_NONE;
break;
case 'c':
type = FAT_CHARACTER;
break;
case 's':
type = FAT_STRING;
break;
case 'b': case 'd': case 'o': case 'x': case 'X':
type = FAT_INTEGER;
break;
case 'f':
type = FAT_FLOAT;
break;
case 'j':
type = FAT_ANY;
break;
default:
if (*format == '\0')
{
*invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
FDI_SET (format - 1, FMTDIR_ERROR);
}
else
{
*invalid_reason =
INVALID_CONVERSION_SPECIFIER (spec.directives, *format);
FDI_SET (format, FMTDIR_ERROR);
}
goto bad_format;
}
if (*format != '%')
{
if (spec.allocated == spec.format_args_count)
{
spec.allocated = 2 * spec.allocated + 1;
spec.format_args = (enum format_arg_type *) xrealloc (spec.format_args, spec.allocated * sizeof (enum format_arg_type));
}
spec.format_args[spec.format_args_count] = type;
spec.format_args_count++;
}
FDI_SET (format, FMTDIR_END);
format++;
}
result = XMALLOC (struct spec);
*result = spec;
return result;
bad_format:
if (spec.format_args != NULL)
free (spec.format_args);
return NULL;
}
static void
format_free (void *descr)
{
struct spec *spec = (struct spec *) descr;
if (spec->format_args != NULL)
free (spec->format_args);
free (spec);
}
static int
format_get_number_of_directives (void *descr)
{
struct spec *spec = (struct spec *) descr;
return spec->directives;
}
static bool
format_check (void *msgid_descr, void *msgstr_descr, bool equality,
formatstring_error_logger_t error_logger,
const char *pretty_msgid, const char *pretty_msgstr)
{
struct spec *spec1 = (struct spec *) msgid_descr;
struct spec *spec2 = (struct spec *) msgstr_descr;
bool err = false;
if (spec1->format_args_count + spec2->format_args_count > 0)
{
unsigned int i;
/* Check the argument types are the same. */
if (spec1->format_args_count != spec2->format_args_count)
{
if (error_logger)
error_logger (_("number of format specifications in '%s' and '%s' does not match"),
pretty_msgid, pretty_msgstr);
err = true;
}
else
for (i = 0; i < spec2->format_args_count; i++)
if (!(spec1->format_args[i] == spec2->format_args[i]
|| (!equality
&& (spec1->format_args[i] == FAT_ANY
|| spec2->format_args[i] == FAT_ANY))))
{
if (error_logger)
error_logger (_("format specifications in '%s' and '%s' for argument %u are not the same"),
pretty_msgid, pretty_msgstr, i + 1);
err = true;
}
}
return err;
}
struct formatstring_parser formatstring_javascript =
{
format_parse,
format_free,
format_get_number_of_directives,
NULL,
format_check
};
#ifdef TEST
/* Test program: Print the argument list specification returned by
format_parse for strings read from standard input. */
#include <stdio.h>
static void
format_print (void *descr)
{
struct spec *spec = (struct spec *) descr;
unsigned int i;
if (spec == NULL)
{
printf ("INVALID");
return;
}
printf ("(");
for (i = 0; i < spec->format_args_count; i++)
{
if (i > 0)
printf (" ");
switch (spec->format_args[i])
{
case FAT_ANY:
printf ("*");
break;
case FAT_CHARACTER:
printf ("c");
break;
case FAT_STRING:
printf ("s");
break;
case FAT_INTEGER:
printf ("i");
break;
case FAT_FLOAT:
printf ("f");
break;
default:
abort ();
}
}
printf (")");
}
int
main ()
{
for (;;)
{
char *line = NULL;
size_t line_size = 0;
int line_len;
char *invalid_reason;
void *descr;
line_len = getline (&line, &line_size, stdin);
if (line_len < 0)
break;
if (line_len > 0 && line[line_len - 1] == '\n')
line[--line_len] = '\0';
invalid_reason = NULL;
descr = format_parse (line, false, NULL, &invalid_reason);
format_print (descr);
printf ("\n");
if (descr == NULL)
printf ("%s\n", invalid_reason);
free (invalid_reason);
free (line);
}
return 0;
}
/*
* For Emacs M-x compile
* Local Variables:
* compile-command: "/bin/sh ../libtool --tag=CC --mode=link gcc -o a.out -static -O -g -Wall -I.. -I../gnulib-lib -I../intl -DHAVE_CONFIG_H -DTEST format-javascript.c ../gnulib-lib/libgettextlib.la"
* End:
*/
#endif /* TEST */

View File

@ -58,7 +58,8 @@ struct formatstring_parser *formatstring_parsers[NFORMATS] =
/* format_qt_plural */ &formatstring_qt_plural,
/* format_kde */ &formatstring_kde,
/* format_boost */ &formatstring_boost,
/* format_lua */ &formatstring_lua
/* format_lua */ &formatstring_lua,
/* format_javascript */ &formatstring_javascript
};
/* Check whether both formats strings contain compatible format

View File

@ -120,6 +120,7 @@ extern DLL_VARIABLE struct formatstring_parser formatstring_qt_plural;
extern DLL_VARIABLE struct formatstring_parser formatstring_kde;
extern DLL_VARIABLE struct formatstring_parser formatstring_boost;
extern DLL_VARIABLE struct formatstring_parser formatstring_lua;
extern DLL_VARIABLE struct formatstring_parser formatstring_javascript;
/* Table of all format string parsers. */
extern DLL_VARIABLE struct formatstring_parser *formatstring_parsers[NFORMATS];

View File

@ -58,7 +58,8 @@ const char *const format_language[NFORMATS] =
/* format_qt_plursl */ "qt-plural",
/* format_kde */ "kde",
/* format_boost */ "boost",
/* format_lua */ "lua"
/* format_lua */ "lua",
/* format_javascript */ "javascript"
};
const char *const format_language_pretty[NFORMATS] =
@ -87,7 +88,8 @@ const char *const format_language_pretty[NFORMATS] =
/* format_qt_plural */ "Qt plural",
/* format_kde */ "KDE",
/* format_boost */ "Boost",
/* format_lua */ "Lua"
/* format_lua */ "Lua",
/* format_javascript */ "JavaScript"
};

View File

@ -67,9 +67,10 @@ enum format_type
format_qt_plural,
format_kde,
format_boost,
format_lua
format_lua,
format_javascript
};
#define NFORMATS 25 /* Number of format_type enum values. */
#define NFORMATS 26 /* Number of format_type enum values. */
extern DLL_VARIABLE const char *const format_language[NFORMATS];
extern DLL_VARIABLE const char *const format_language_pretty[NFORMATS];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
/* xgettext Python backend.
Copyright (C) 2002-2003, 2006 Free Software Foundation, Inc.
This file was written by Andreas Stricker <andy@knitter.ch>, 2010.
It's based on x-python from Bruno Haible.
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 <http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include "message.h"
#include "xgettext.h"
#ifdef __cplusplus
extern "C" {
#endif
#define EXTENSIONS_JAVASCRIPT \
{ "js", "JavaScript" }, \
#define SCANNERS_JAVASCRIPT \
{ "JavaScript", extract_javascript, \
&flag_table_javascript, &formatstring_javascript, NULL }, \
/* Scan a Python file and add its translatable strings to mdlp. */
extern void extract_javascript (FILE *fp, const char *real_filename,
const char *logical_filename,
flag_context_list_table_ty *flag_table,
msgdomain_list_ty *mdlp);
extern void x_javascript_keyword (const char *keyword);
extern void x_javascript_extract_all (void);
extern void init_flag_table_javascript (void);
#ifdef __cplusplus
}
#endif

View File

@ -93,6 +93,7 @@
#include "x-rst.h"
#include "x-glade.h"
#include "x-lua.h"
#include "x-javascript.h"
/* If nonzero add all comments immediately preceding one of the keywords. */
@ -162,6 +163,7 @@ 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_lua;
static flag_context_list_table_ty flag_table_javascript;
/* If true, recognize Qt format strings. */
static bool recognize_format_qt;
@ -334,6 +336,7 @@ main (int argc, char *argv[])
init_flag_table_perl ();
init_flag_table_php ();
init_flag_table_lua ();
init_flag_table_javascript ();
while ((optchar = getopt_long (argc, argv,
"ac::Cd:D:eEf:Fhijk::l:L:m::M::no:p:sTVw:x:",
@ -359,6 +362,7 @@ main (int argc, char *argv[])
x_php_extract_all ();
x_glade_extract_all ();
x_lua_extract_all ();
x_javascript_extract_all ();
break;
case 'c':
@ -437,6 +441,7 @@ main (int argc, char *argv[])
x_php_keyword (optarg);
x_glade_keyword (optarg);
x_lua_keyword (optarg);
x_javascript_keyword (optarg);
if (optarg == NULL)
no_default_keywords = true;
else
@ -862,7 +867,7 @@ 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\
Lua, GCC-source, NXStringTable, RST, Glade)\n"));
Lua, JavaScript, GCC-source, NXStringTable, RST, Glade)\n"));
printf (_("\
-C, --c++ shorthand for --language=C++\n"));
printf (_("\
@ -895,21 +900,21 @@ Language specific options:\n"));
printf (_("\
(only languages C, C++, ObjectiveC, Shell,\n\
Python, Lisp, EmacsLisp, librep, Scheme, Java,\n\
C#, awk, Tcl, Perl, PHP, Lua, GCC-source, Glade)\n"));
C#, awk, Tcl, Perl, PHP, Lua, JavaScript, GCC-source, Glade)\n"));
printf (_("\
-kWORD, --keyword=WORD look for WORD as an additional keyword\n\
-k, --keyword do not to use default keywords\n"));
printf (_("\
(only languages C, C++, ObjectiveC, Shell,\n\
Python, Lisp, EmacsLisp, librep, Scheme, Java,\n\
C#, awk, Tcl, Perl, PHP, Lua, GCC-source, Glade)\n"));
C#, awk, Tcl, Perl, PHP, Lua, JavaScript, GCC-source, Glade)\n"));
printf (_("\
--flag=WORD:ARG:FLAG additional flag for strings inside the argument\n\
number ARG of keyword WORD\n"));
printf (_("\
(only languages C, C++, ObjectiveC, Shell,\n\
Python, Lisp, EmacsLisp, librep, Scheme, Java,\n\
C#, awk, YCP, Tcl, Perl, PHP, Lua, GCC-source)\n"));
C#, awk, YCP, Tcl, Perl, PHP, Lua, JavaScript, GCC-source)\n"));
printf (_("\
-T, --trigraphs understand ANSI C trigraphs for input\n"));
printf (_("\
@ -1778,6 +1783,11 @@ xgettext_record_flag (const char *optionstring)
name_start, name_end,
argnum, value, pass);
break;
case format_javascript:
flag_context_list_table_insert (&flag_table_javascript, 0,
name_start, name_end,
argnum, value, pass);
break;
default:
abort ();
}
@ -3196,6 +3206,7 @@ language_to_extractor (const char *name)
SCANNERS_RST
SCANNERS_GLADE
SCANNERS_LUA
SCANNERS_JAVASCRIPT
/* Here may follow more languages and their scanners: pike, etc...
Make sure new scanners honor the --exclude-file option. */
};
@ -3280,6 +3291,7 @@ extension_to_language (const char *extension)
EXTENSIONS_RST
EXTENSIONS_GLADE
EXTENSIONS_LUA
EXTENSIONS_JAVASCRIPT
/* Here may follow more file extensions... */
};

View File

@ -1,3 +1,15 @@
2013-04-17 Andreas Stricker <astricker@futurelab.ch>
Support for JavaScript.
* format-javascript-1: New file.
* format-javascript-2: New file.
* xgettext-javascript-1: New file.
* xgettext-javascript-2: New file.
* xgettext-javascript-3: New file.
* xgettext-javascript-4: New file.
* lang-javascript: New file.
* Makefile.am (TESTS): Add them.
2013-04-16 Ľubomír Remák <lubomirr@lubomirr.eu>
Support for escape sequences added in Lua 5.2.

View File

@ -101,6 +101,8 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
xgettext-tcl-1 xgettext-tcl-2 xgettext-tcl-3 \
xgettext-ycp-1 xgettext-ycp-2 xgettext-ycp-3 xgettext-ycp-4 \
xgettext-lua-1 xgettext-lua-2 \
xgettext-javascript-1 xgettext-javascript-2 xgettext-javascript-3 \
xgettext-javascript-4 \
format-awk-1 format-awk-2 \
format-boost-1 format-boost-2 \
format-c-1 format-c-2 format-c-3 format-c-4 format-c-5 \
@ -125,13 +127,14 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
format-tcl-1 format-tcl-2 \
format-ycp-1 format-ycp-2 \
format-lua-1 format-lua-2 \
format-javascript-1 format-javascript-2 \
plural-1 plural-2 \
gettextpo-1 \
lang-c lang-c++ lang-objc lang-sh lang-bash lang-python-1 \
lang-python-2 lang-clisp lang-elisp lang-librep lang-guile \
lang-smalltalk lang-java lang-csharp lang-gawk lang-pascal \
lang-ycp lang-tcl lang-perl-1 lang-perl-2 lang-php lang-po lang-rst \
lang-lua
lang-lua lang-javascript
EXTRA_DIST += $(TESTS) \
test.mo xg-c-1.ok.po mex-test2.ok \

View File

@ -0,0 +1,90 @@
#! /bin/sh
# Test recognition of JavaScript format strings.
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles f-js-1.data"
cat <<\EOF > f-js-1.data
# Valid: no argument
"abc%%"
# Valid: one character argument
"abc%c"
# Valid: one string argument
"abc%s"
# Valid: one integer argument
"abc%b"
# Valid: one integer argument
"abc%d"
# Valid: one integer argument
"abc%o"
# Valid: one integer argument
"abc%x"
# Valid: one integer argument
"abc%X"
# Valid: one floating-point argument
"abc%f"
# Valid: one object argument
"abc%j"
# Valid: one argument with flags
"abc%Id"
# Valid: one argument with width
"abc%2d"
# Valid: one argument with precision
"abc%.4f"
# Valid: one argument with width and precision
"abc%14.4f"
# Invalid: unterminated
"abc%"
# Invalid: unknown format specifier
"abc%y"
# Invalid: flags after width
"abc%1Ig"
# Invalid: twice precision
"abc%.4.2f"
# Valid: three arguments
"abc%d%j%j"
EOF
tmpfiles="$tmpfiles f-js-1.err"
: ${XGETTEXT=xgettext}
n=0
while read comment; do
read string
n=`expr $n + 1`
tmpfiles="$tmpfiles f-js-1-$n.in f-js-1-$n.po"
cat <<EOF > f-js-1-$n.in
gettext(${string});
EOF
# Hide xgettext's "The translator cannot reorder the arguments." warnings.
${XGETTEXT} -L JavaScript -o f-js-1-$n.po f-js-1-$n.in 2> f-js-1.err \
|| { cat f-js-1.err 1>&2; exit 1; }
test -f f-js-1-$n.po || exit 1
fail=
if echo "$comment" | grep 'Valid:' > /dev/null; then
if grep javascript-format f-js-1-$n.po > /dev/null; then
:
else
fail=yes
fi
else
if grep javascript-format f-js-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-js-1-$n.in 1>&2
echo "Got:" 1>&2
cat f-js-1-$n.po 1>&2
exit 1
fi
rm -f f-js-1-$n.in f-js-1-$n.po
done < f-js-1.data
rm -fr $tmpfiles
exit 0

View File

@ -0,0 +1,88 @@
#! /bin/sh
# Test checking of JavaScript format strings.
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles f-js-2.data"
cat <<\EOF > f-js-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
msgid "abc%2sdef"
msgstr "xyz%3s"
# Invalid: too few arguments
msgid "abc%sdef%u"
msgstr "xyz%s"
# Invalid: too many arguments
msgid "abc%udef"
msgstr "xyz%uvw%c"
# Valid: type compatibility
msgid "abc%o"
msgstr "xyz%d"
# Valid: type compatibility
msgid "abc%o"
msgstr "xyz%x"
# Valid: type compatibility
msgid "abc%o"
msgstr "xyz%X"
# Valid: type compatibility
msgid "abc%d"
msgstr "xyz%x"
# Valid: type compatibility
msgid "abc%d"
msgstr "xyz%X"
# Invalid: type incompatibility
msgid "abc%c"
msgstr "xyz%s"
# Invalid: type incompatibility
msgid "abc%c"
msgstr "xyz%d"
# Invalid: type incompatibility
msgid "abc%s"
msgstr "xyz%d"
EOF
: ${MSGFMT=msgfmt}
n=0
while read comment; do
read msgid_line
read msgstr_line
n=`expr $n + 1`
tmpfiles="$tmpfiles f-js-2-$n.po f-js-2-$n.mo"
cat <<EOF > f-js-2-$n.po
#, python-format
${msgid_line}
${msgstr_line}
EOF
fail=
if echo "$comment" | grep 'Valid:' > /dev/null; then
if ${MSGFMT} --check-format -o f-js-2-$n.mo f-js-2-$n.po; then
:
else
fail=yes
fi
else
${MSGFMT} --check-format -o f-js-2-$n.mo f-js-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-js-2-$n.po 1>&2
exit 1
fi
rm -f f-js-2-$n.po f-js-2-$n.mo
done < f-js-2.data
rm -fr $tmpfiles
exit 0

View File

@ -0,0 +1,132 @@
#! /bin/sh
# Test of gettext facilities in the JavaScript language.
# Assumes an fr_FR locale is installed.
# Assumes the following packages are installed: gjs.
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles prog.js"
cat <<\EOF > prog.js
const Format = imports.format;
const Gettext = imports.gettext;
String.prototype.format = Format.format;
const _ = Gettext.gettext;
Gettext.textdomain ("prog");
Gettext.bindtextdomain ("prog", ".");
print(_("'Your command, please?', asked the waiter."));
print(_("%s is replaced by %s.").format("FF", "EUR"));
EOF
tmpfiles="$tmpfiles prog.tmp prog.pot"
: ${XGETTEXT=xgettext}
${XGETTEXT} -o prog.tmp --omit-header --no-location prog.js
test $? = 0 || { rm -fr $tmpfiles; exit 1; }
LC_ALL=C tr -d '\r' < prog.tmp > prog.pot
test $? = 0 || { rm -fr $tmpfiles; exit 1; }
tmpfiles="$tmpfiles prog.ok"
cat <<EOF > prog.ok
msgid "'Your command, please?', asked the waiter."
msgstr ""
#, javascript-format
msgid "%s is replaced by %s."
msgstr ""
EOF
: ${DIFF=diff}
${DIFF} prog.ok prog.pot || exit 1
tmpfiles="$tmpfiles fr.po"
cat <<\EOF > fr.po
msgid ""
msgstr "Content-Type: text/plain; charset=ISO-8859-1\n"
msgid "'Your command, please?', asked the waiter."
msgstr "«Votre commande, s'il vous plait», dit le garçon."
# Reverse the arguments.
#, javascript-format
msgid "%s is replaced by %s."
msgstr "%s remplace %s."
EOF
tmpfiles="$tmpfiles fr.po.tmp fr.po.new"
: ${MSGMERGE=msgmerge}
${MSGMERGE} -q -o fr.po.tmp fr.po prog.pot
test $? = 0 || { rm -fr $tmpfiles; exit 1; }
LC_ALL=C tr -d '\r' < fr.po.tmp > fr.po.new
test $? = 0 || { rm -fr $tmpfiles; exit 1; }
: ${DIFF=diff}
${DIFF} fr.po fr.po.new || exit 1
tmpfiles="$tmpfiles fr"
test -d fr || mkdir fr
test -d fr/LC_MESSAGES || mkdir fr/LC_MESSAGES
: ${MSGFMT=msgfmt}
${MSGFMT} -o fr/LC_MESSAGES/prog.mo fr.po
# Test for presence of gjs.
(gjs -h) >/dev/null 2>/dev/null
test $? -le 1 \
|| { echo "Skipping test: gjs not found"; rm -fr $tmpfiles; exit 77; }
# Test which of the fr_FR locales are installed.
: ${LOCALE_FR=fr_FR}
: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
if test $LOCALE_FR != none; then
LC_ALL=$LOCALE_FR ./testlocale
case $? in
0) ;;
77) LOCALE_FR=none;;
*) exit 1;;
esac
fi
if test $LOCALE_FR_UTF8 != none; then
LC_ALL=$LOCALE_FR_UTF8 ./testlocale
case $? in
0) ;;
77) LOCALE_FR_UTF8=none;;
*) exit 1;;
esac
fi
if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none; then
if test -f /usr/bin/localedef; then
echo "Skipping test: no french locale is installed"
else
echo "Skipping test: no french locale is supported"
fi
rm -fr $tmpfiles; exit 77
fi
tmpfiles="$tmpfiles prog.ok prog.oku prog.out"
: ${DIFF=diff}
cat <<\EOF > prog.ok
«Votre commande, s'il vous plait», dit le garçon.
FF remplace EUR.
EOF
cat <<\EOF > prog.oku
«Votre commande, s'il vous plait», dit le garçon.
FF remplace EUR.
EOF
: ${LOCALE_FR=fr_FR}
: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
if test $LOCALE_FR != none; then
LANGUAGE= LC_ALL=$LOCALE_FR gjs prog.js > prog.out || exit 1
${DIFF} prog.ok prog.out || exit 1
fi
if test $LOCALE_FR_UTF8 != none; then
LANGUAGE= LC_ALL=$LOCALE_FR_UTF8 gjs prog.js > prog.out || exit 1
${DIFF} -u prog.oku prog.out || exit 1
fi
rm -fr $tmpfiles
exit 0

View File

@ -0,0 +1,64 @@
#!/bin/sh
# Test of JavaScript support.
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles xg-js-1.js"
cat <<\EOF > xg-js-1.js
var s1 = "Simple string, no gettext needed",
s2 = _("Extract this first string");
function foo(a) {
var s3 = "Prefix _(" + _("Extract this second string") + ") Postfix";
}
if (document.getElementsById("foo")[0].innerHTML == _("Extract this thirth string")) {
/* _("This is a comment and must not be extracted!") */
}
EOF
tmpfiles="$tmpfiles xg-js-1.err xg-js-1.tmp xg-js-1.pot"
: ${XGETTEXT=xgettext}
${XGETTEXT} --add-comments --no-location -o xg-js-1.tmp xg-js-1.js 2>xg-js-1.err
test $? = 0 || { cat xg-js-1.err; rm -fr $tmpfiles; exit 1; }
# Don't simplify this to "grep ... < xg-js-1.tmp", otherwise OpenBSD 4.0 grep
# only outputs "Binary file (standard input) matches".
cat xg-js-1.tmp | grep -v 'POT-Creation-Date' | LC_ALL=C tr -d '\r' > xg-js-1.pot
tmpfiles="$tmpfiles xg-js-1.ok"
cat <<\EOF > xg-js-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=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Extract this first string"
msgstr ""
msgid "Extract this second string"
msgstr ""
msgid "Extract this thirth string"
msgstr ""
EOF
: ${DIFF=diff}
${DIFF} xg-js-1.ok xg-js-1.pot
result=$?
rm -fr $tmpfiles
exit $result

View File

@ -0,0 +1,107 @@
#!/bin/sh
# Test of JavaScript support.
# Playing with regex and division operator
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles xg-js-2.js"
cat <<\EOF > xg-js-2.js
// RegExp literals containing string quotes must not desync the parser
var d = 1 / 2 / 4;
var s = " x " + /^\d/.match("0815").replace(/[a-z]/g, '@');
var s1 = /"/.match(_("RegExp test string #1"));
var s2 = /'/.match(_("RegExp test string #2"));
var s3 = /['a-b]/.match(_('RegExp test string #3'));
var s4 = /["a-b]/.match(_('RegExp test string #4'));
var s5 = /[a-b']/.match(_('RegExp test string #5'));
var s6 = /[a-b"]/.match(_('RegExp test string #6'));
var c = 35 / 2 / 8 + _("RegExp test string #7").length / 32.0;
var sizestr = Math.round(size/1024*factor)/factor+_("RegExp test string #8");
var cssClassType = attr.type.replace(/^.*\//, _('RegExp test string #9')).replace(/\./g, '-');
var lookup = lookuptable[idx]/factor+_("RegExp test string #10");
function doit() {
return /\./.match(_("RegExp test string #11"));
}
if (false)
/foo/.match(_("RegExp test string #12"));
else
/foo/.match(_("RegExp test string #13"));
EOF
tmpfiles="$tmpfiles xg-js-2.err xg-js-2.tmp xg-js-2.pot"
: ${XGETTEXT=xgettext}
${XGETTEXT} --add-comments --no-location -o xg-js-2.tmp xg-js-2.js 2>xg-js-2.err
test $? = 0 || { cat xg-js-2.err; rm -fr $tmpfiles; exit 1; }
# Don't simplify this to "grep ... < xg-js-2.tmp", otherwise OpenBSD 4.0 grep
# only outputs "Binary file (standard input) matches".
cat xg-js-2.tmp | grep -v 'POT-Creation-Date' | LC_ALL=C tr -d '\r' > xg-js-2.pot
tmpfiles="$tmpfiles xg-js-2.ok"
cat <<\EOF > xg-js-2.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=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "RegExp test string #1"
msgstr ""
msgid "RegExp test string #2"
msgstr ""
msgid "RegExp test string #3"
msgstr ""
msgid "RegExp test string #4"
msgstr ""
msgid "RegExp test string #5"
msgstr ""
msgid "RegExp test string #6"
msgstr ""
msgid "RegExp test string #7"
msgstr ""
msgid "RegExp test string #8"
msgstr ""
msgid "RegExp test string #9"
msgstr ""
msgid "RegExp test string #10"
msgstr ""
msgid "RegExp test string #11"
msgstr ""
msgid "RegExp test string #12"
msgstr ""
msgid "RegExp test string #13"
msgstr ""
EOF
: ${DIFF=diff}
${DIFF} xg-js-2.ok xg-js-2.pot
result=$?
rm -fr $tmpfiles
exit $result

View File

@ -0,0 +1,63 @@
#!/bin/sh
# Test of JavaScript support.
# Playing with concatenation of string literals within the gettext function
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles xg-js-2.js"
cat <<\EOF > xg-js-2.js
// The usual way to concatenate strings is the plus '+' sign
var s1 = _("Concatenation #1 " + "- String part added");
var s2 = _('Concatenation #2 ' + '- String part added');
var s3 = _("This" + " whole "
+ "string" +
' should' + " be " + 'extracted');
EOF
tmpfiles="$tmpfiles xg-js-2.err xg-js-2.tmp xg-js-2.pot"
: ${XGETTEXT=xgettext}
${XGETTEXT} --add-comments --no-location -o xg-js-2.tmp xg-js-2.js 2>xg-js-2.err
test $? = 0 || { cat xg-js-2.err; rm -fr $tmpfiles; exit 1; }
# Don't simplify this to "grep ... < xg-js-2.tmp", otherwise OpenBSD 4.0 grep
# only outputs "Binary file (standard input) matches".
cat xg-js-2.tmp | grep -v 'POT-Creation-Date' | LC_ALL=C tr -d '\r' > xg-js-2.pot
tmpfiles="$tmpfiles xg-js-2.ok"
cat <<\EOF > xg-js-2.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=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Concatenation #1 - String part added"
msgstr ""
msgid "Concatenation #2 - String part added"
msgstr ""
msgid "This whole string should be extracted"
msgstr ""
EOF
: ${DIFF=diff}
${DIFF} xg-js-2.ok xg-js-2.pot
result=$?
rm -fr $tmpfiles
exit $result

View File

@ -0,0 +1,55 @@
#!/bin/sh
# Test of JavaScript Unicode support.
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
tmpfiles="$tmpfiles xg-js-1.js"
cat <<\EOF > xg-js-1.js
var s1 = _("Unicode escape \u3042");
var s2 = _("Surrogate pair \uD835\uDC9C");
EOF
tmpfiles="$tmpfiles xg-js-1.err xg-js-1.tmp xg-js-1.pot"
: ${XGETTEXT=xgettext}
${XGETTEXT} --add-comments --no-location -o xg-js-1.tmp xg-js-1.js 2>xg-js-1.err
test $? = 0 || { cat xg-js-1.err; rm -fr $tmpfiles; exit 1; }
# Don't simplify this to "grep ... < xg-js-1.tmp", otherwise OpenBSD 4.0 grep
# only outputs "Binary file (standard input) matches".
cat xg-js-1.tmp | grep -v 'POT-Creation-Date' | LC_ALL=C tr -d '\r' > xg-js-1.pot
tmpfiles="$tmpfiles xg-js-1.ok"
cat <<\EOF > xg-js-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 "Unicode escape あ"
msgstr ""
msgid "Surrogate pair 𝒜"
msgstr ""
EOF
: ${DIFF=diff}
${DIFF} xg-js-1.ok xg-js-1.pot
result=$?
rm -fr $tmpfiles
exit $result

View File

@ -30,6 +30,7 @@ VARIABLE(formatstring_elisp)
VARIABLE(formatstring_gcc_internal)
VARIABLE(formatstring_gfc_internal)
VARIABLE(formatstring_java)
VARIABLE(formatstring_javascript)
VARIABLE(formatstring_kde)
VARIABLE(formatstring_librep)
VARIABLE(formatstring_lisp)