From: Bruno Haible Date: Mon, 9 Sep 2002 11:24:56 +0000 (+0000) Subject: Smalltalk support. X-Git-Tag: v0.12~1280 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee63b8d8c9ebf2b406fc32a6f8c88bf56ccd4d98;p=thirdparty%2Fgettext.git Smalltalk support. --- diff --git a/NEWS b/NEWS index 577f15e08..156951c8d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +Version 0.11.6 - September 2002 + +* xgettext now also supports Smalltalk and PHP. + +Version 0.11.5 - August 2002 + +* Bug fixes in the gettext.m4 autoconf macros. + Version 0.11.4 - July 2002 * The tools now know about the ISO C 99 format string directive diff --git a/doc/ChangeLog b/doc/ChangeLog index 4a62043a0..fa7b3f9ee 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2002-09-09 Bruno Haible + + * gettext.texi (Smalltalk): Update. + * xgettext.texi: Mention language Smalltalk. + 2002-08-18 Bruno Haible * gettext.texi (php-format): New subsection. diff --git a/doc/gettext.texi b/doc/gettext.texi index f2415b246..855c40544 100644 --- a/doc/gettext.texi +++ b/doc/gettext.texi @@ -6885,7 +6885,7 @@ that language, and to combine the resulting files using @code{msgcat}. @c Haskell 9 @c Visual Basic 9 @c C# 6 -@c Smalltalk 6 +@c Smalltalk 6 * @c Basic 5 @c Erlang 5 @c Modula 5 @@ -7343,37 +7343,33 @@ smalltalk @code{st} @item String syntax -@code{''abc''} +@code{'abc'} @item gettext shorthand -@code{NLS? ''abc''} -@*@code{self? ''abc''} +@code{NLS ? 'abc'} @item gettext/ngettext functions @code{LcMessagesDomain>>#at:}, @code{LcMessagesDomain>>#at:plural:with:} @item textdomain -@code{LcMessages>>#?} (returns a @code{LcMessagesDomain} object).@* -Example: @code{Locale default messages ? 'gettext'} +@code{LcMessages>>#domain:localeDirectory:} (returns a @code{LcMessagesDomain} +object).@* +Example: @code{I18N Locale default messages domain: 'gettext' localeDirectory: /usr/local/share/locale'} @item bindtextdomain -@code{LcMessages>>#domain:directory:} (returns a @code{LcMessagesDomain} -object) +@code{LcMessages>>#domain:localeDirectory:}, see above. @item setlocale -You can obtain any @code{Locale} object from @code{Locale} class methods -such as @code{#fromString:} or @code{#default}.@* -Example: @code{Locale default messages} gives the @code{LcMessages} -object for the default locale. +Automatic if you use @code{I18N Locale default}. @item Prerequisite -The gettext code is contained in the @file{I18N} package. +@code{PackageLoader fileInPackage: 'I18N'!} @item Use or emulate GNU gettext emulate @item Extractor ---- +@code{xgettext} @item Formatting with positions @code{'%1 %2' bindWith: 'Hello' with: 'world'} diff --git a/doc/xgettext.texi b/doc/xgettext.texi index 49e3c2083..7385d504e 100644 --- a/doc/xgettext.texi +++ b/doc/xgettext.texi @@ -70,8 +70,8 @@ is written to standard output. @cindex supported languages, @code{xgettext} Specifies the language of the input files. The supported languages are @code{C}, @code{C++}, @code{ObjectiveC}, @code{PO}, @code{Python}, -@code{Lisp}, @code{EmacsLisp}, @code{librep}, @code{Java}, @code{awk}, -@code{YCP}, @code{Tcl}, @code{PHP}, @code{RST}, @code{Glade}. +@code{Lisp}, @code{EmacsLisp}, @code{librep}, @code{Smalltalk}, @code{Java}, +@code{awk}, @code{YCP}, @code{Tcl}, @code{PHP}, @code{RST}, @code{Glade}. @item -C @itemx --c++ diff --git a/src/ChangeLog b/src/ChangeLog index 326e23ab1..d5a0d8ead 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2002-09-09 Bruno Haible + + * x-smalltalk.h: New file. + * x-smalltalk.c: New file. + * xgettext.c: Include x-smalltalk.h. + (usage): Mention Smalltalk language. + (language_to_extractor): Add Smalltalk support. + (extension_to_language): Likewise. + * Makefile.am (noinst_HEADERS): Add x-smalltalk.h. + (xgettext_SOURCES): Add x-smalltalk.c. + 2002-08-18 Bruno Haible * message.h (enum format_type): New enum value 'format_php'. diff --git a/src/Makefile.am b/src/Makefile.am index 1ad2ad059..96f1a5cd0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,8 @@ po-gram-gen.h po-hash-gen.h msgl-charset.h msgl-equal.h msgl-iconv.h \ msgl-ascii.h msgl-cat.h msgl-english.h msgfmt.h msgunfmt.h read-mo.h \ 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-java.h x-awk.h x-ycp.h x-tcl.h x-php.h x-rst.h x-glade.h +x-elisp.h x-librep.h x-smalltalk.h x-java.h x-awk.h x-ycp.h x-tcl.h x-php.h \ +x-rst.h x-glade.h EXTRA_DIST = FILES project-id msgunfmt.tcl \ gnu/gettext/DumpResource.java gnu/gettext/GetURL.java @@ -94,8 +95,8 @@ msgfmt_SOURCES = msgfmt.c write-mo.c write-java.c write-tcl.c plural-eval.c msgmerge_SOURCES = msgmerge.c 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-java.l x-awk.c \ - x-ycp.c x-tcl.c x-php.c x-rst.c x-glade.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 msgattrib_SOURCES = msgattrib.c msgcat_SOURCES = msgcat.c msgcomm_SOURCES = msgcomm.c diff --git a/src/x-smalltalk.c b/src/x-smalltalk.c new file mode 100644 index 000000000..6537ac747 --- /dev/null +++ b/src/x-smalltalk.c @@ -0,0 +1,598 @@ +/* xgettext Smalltalk backend. + Copyright (C) 2002 Free Software Foundation, Inc. + + This file was written by Bruno Haible , 2002. + + 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 "message.h" +#include "x-smalltalk.h" +#include "xgettext.h" +#include "error.h" +#include "xmalloc.h" +#include "exit.h" +#include "gettext.h" + +#define _(s) gettext(s) + +/* The relevant parts of the Smalltalk syntax are: + + stringliteral ::= string | stringconst | symconst + stringconst ::= "#"string + string ::= "'"[char]*"'" + symconst ::= "#"symbol + symbol ::= id | binsel | keysel[keysel]* + keysel ::= id":" + id ::= letter[letter|digit]* + letter ::= "A".."Z" | "a".."z" + digit ::= "0".."9" + binsel ::= selchar[selchar] + selchar ::= "+" | "-" | "*" | "/" | "~" | "|" | "," | "<" | ">" + | "=" | "&" | "@" | "?" | "%" | "\" + + Strings can contain any characters; to include the string delimiter itself, + it must be duplicated. + + Character constants are written "$"char + + Comments are enclosed within double quotes. + + In well-formed expressions, {} and [] and () are balanced. + */ + +enum token_type_ty +{ + token_type_eof, + token_type_uniq, /* # */ + token_type_symbol, /* symbol */ + token_type_string_literal, /* string, stringconst, symbolconst */ + token_type_other /* misc. operator */ +}; +typedef enum token_type_ty token_type_ty; + +typedef struct token_ty token_ty; +struct token_ty +{ + token_type_ty type; + char *string; /* for token_type_string_literal, token_type_symbol */ + int line_number; +}; + + +/* Prototypes for local functions. Needed to ensure compiler checking of + function argument counts despite of K&R C function definition syntax. */ +static int phase1_getc PARAMS ((void)); +static void phase1_ungetc PARAMS ((int c)); +static inline void comment_start PARAMS ((void)); +static inline void comment_add PARAMS ((int c)); +static inline void comment_line_end PARAMS ((void)); +static void phase2_get PARAMS ((token_ty *tp)); +static void phase2_unget PARAMS ((token_ty *tp)); +static void x_smalltalk_lex PARAMS ((token_ty *tp)); + + +/* ======================== Reading of characters. ======================== */ + + +/* 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; + + +/* 1. line_number handling. */ + +static int +phase1_getc () +{ + int c = getc (fp); + + if (c == EOF) + { + if (ferror (fp)) + error (EXIT_FAILURE, errno, _("error while reading \"%s\""), + real_file_name); + return EOF; + } + + if (c == '\n') + line_number++; + + return c; +} + +static void +phase1_ungetc (c) + int c; +{ + if (c != EOF) + { + if (c == '\n') + --line_number; + + ungetc (c, fp); + } +} + + +/* Accumulating comments. */ + +static char *buffer; +static size_t bufmax; +static size_t buflen; + +static inline void +comment_start () +{ + buflen = 0; +} + +static inline void +comment_add (c) + int c; +{ + if (buflen >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[buflen++] = c; +} + +static inline void +comment_line_end () +{ + while (buflen >= 1 + && (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t')) + --buflen; + if (buflen >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[buflen] = '\0'; + xgettext_comment_add (buffer); +} + + +/* These are for tracking whether comments count as immediately before + keyword. */ +static int last_comment_line; +static int last_non_comment_line; + + +/* 2. Combine characters into tokens. Discard comments and whitespace. */ + +/* Maximum used guaranteed to be < 2. */ +static token_ty phase2_pushback[2]; +static int phase2_pushback_length; + +static void +phase2_get (tp) + token_ty *tp; +{ + static char *buffer; + static int bufmax; + int bufpos; + int c; + + if (phase2_pushback_length) + { + *tp = phase2_pushback[--phase2_pushback_length]; + return; + } + + tp->string = NULL; + + for (;;) + { + tp->line_number = line_number; + c = phase1_getc (); + switch (c) + { + case EOF: + tp->type = token_type_eof; + return; + + case '"': + { + /* Comment. */ + int lineno; + + comment_start (); + lineno = line_number; + for (;;) + { + c = phase1_getc (); + if (c == '"' || c == EOF) + break; + if (c == '\n') + { + comment_line_end (); + comment_start (); + } + else + { + /* We skip all leading white space, but not EOLs. */ + if (!(buflen == 0 && (c == ' ' || c == '\t'))) + comment_add (c); + } + } + comment_line_end (); + last_comment_line = lineno; + continue; + } + + case '\n': + if (last_non_comment_line > last_comment_line) + xgettext_comment_reset (); + /* FALLTHROUGH */ + case ' ': + case '\t': + case '\r': + /* Ignore whitespace. */ + continue; + } + + last_non_comment_line = tp->line_number; + + switch (c) + { + case '\'': + /* String literal. */ + bufpos = 0; + for (;;) + { + c = phase1_getc (); + if (c == EOF) + break; + if (c == '\'') + { + c = phase1_getc (); + if (c != '\'') + { + phase1_ungetc (c); + break; + } + } + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + } + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos] = 0; + tp->type = token_type_string_literal; + tp->string = xstrdup (buffer); + return; + + case '+': + case '-': + case '*': + case '/': + case '~': + case '|': + case ',': + case '<': + case '>': + case '=': + case '&': + case '@': + case '?': + case '%': + case '\\': + { + char *name; + int c2 = phase1_getc (); + switch (c2) + { + case '+': + case '-': + case '*': + case '/': + case '~': + case '|': + case ',': + case '<': + case '>': + case '=': + case '&': + case '@': + case '?': + case '%': + name = xmalloc (3); + name[0] = c; + name[1] = c2; + name[2] = '\0'; + tp->type = token_type_symbol; + tp->string = name; + return; + default: + phase1_ungetc (c2); + break; + } + name = xmalloc (2); + name[0] = c; + name[1] = '\0'; + tp->type = token_type_symbol; + tp->string = name; + return; + } + + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + /* Recognize id or id":"[id":"]* or id":"[id":"]*id. */ + bufpos = 0; + for (;;) + { + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + c = phase1_getc (); + switch (c) + { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + continue; + case ':': + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + c = phase1_getc (); + switch (c) + { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + continue; + default: + phase1_ungetc (c); + break; + } + break; + default: + phase1_ungetc (c); + break; + } + break; + } + if (bufpos >= bufmax) + { + bufmax += 100; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos] = '\0'; + tp->string = xstrdup (buffer); + tp->type = token_type_symbol; + return; + + case '#': + /* Uniquification operator. */ + tp->type = token_type_uniq; + return; + + case '$': + c = phase1_getc (); + tp->type = token_type_other; + return; + + default: + tp->type = token_type_other; + return; + } + } +} + +static void +phase2_unget (tp) + token_ty *tp; +{ + if (tp->type != token_type_eof) + phase2_pushback[phase2_pushback_length++] = *tp; +} + + +/* 3. Combine "# string_literal" and "# symbol" to a single token. */ + +static void +x_smalltalk_lex (tp) + token_ty *tp; +{ + phase2_get (tp); + if (tp->type == token_type_uniq) + { + token_ty token2; + + phase2_get (&token2); + if (token2.type == token_type_symbol + || token2.type == token_type_string_literal) + { + tp->type = token_type_string_literal; + tp->string = token2.string; + } + else + phase2_unget (&token2); + } +} + + +/* ========================= Extracting strings. ========================== */ + +/* The file is broken into tokens. Scan the token stream, looking for the + following patterns + NLS ? + NLS at: + NLS at: plural: + where is one of + string_literal + # string_literal + # symbol + */ + +void +extract_smalltalk (f, real_filename, logical_filename, mdlp) + 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; + + last_comment_line = -1; + last_non_comment_line = -1; + + /* Eat tokens until eof is seen. */ + { + /* 0 when no "NLS" has been seen. + 1 after "NLS". + 2 after "NLS ?". + 3 after "NLS at:". + 4 after "NLS at: ". + 5 after "NLS at: plural:". */ + int state; + /* Remember the message containing the msgid, for msgid_plural. + Non-NULL in states 4, 5. */ + message_ty *plural_mp = NULL; + + /* Start state is 0. */ + state = 0; + + for (;;) + { + token_ty token; + + x_smalltalk_lex (&token); + + switch (token.type) + { + case token_type_symbol: + state = (strcmp (token.string, "NLS") == 0 ? 1 : + strcmp (token.string, "?") == 0 && state == 1 ? 2 : + strcmp (token.string, "at:") == 0 && state == 1 ? 3 : + strcmp (token.string, "plural:") == 0 && state == 4 ? 5 : + 0); + free (token.string); + break; + + case token_type_string_literal: + if (state == 2) + { + lex_pos_ty pos; + pos.file_name = logical_file_name; + pos.line_number = token.line_number; + remember_a_message (mlp, token.string, &pos); + state = 0; + break; + } + if (state == 3) + { + lex_pos_ty pos; + pos.file_name = logical_file_name; + pos.line_number = token.line_number; + plural_mp = remember_a_message (mlp, token.string, &pos); + state = 4; + break; + } + if (state == 5) + { + lex_pos_ty pos; + pos.file_name = logical_file_name; + pos.line_number = token.line_number; + remember_a_message_plural (plural_mp, token.string, &pos); + state = 0; + break; + } + state = 0; + free (token.string); + break; + + case token_type_uniq: + case token_type_other: + state = 0; + break; + + case token_type_eof: + break; + + default: + abort (); + } + + if (token.type == token_type_eof) + break; + } + } + + /* Close scanner. */ + fp = NULL; + real_file_name = NULL; + logical_file_name = NULL; + line_number = 0; +} diff --git a/src/x-smalltalk.h b/src/x-smalltalk.h new file mode 100644 index 000000000..75be85f4f --- /dev/null +++ b/src/x-smalltalk.h @@ -0,0 +1,29 @@ +/* xgettext Smalltalk backend. + Copyright (C) 2002 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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_SMALLTALK \ + { "st", "Smalltalk" }, \ + +#define SCANNERS_SMALLTALK \ + { "Smalltalk", extract_smalltalk, &formatstring_smalltalk }, \ + +/* Scan a Smalltalk file and add its translatable strings to mdlp. */ +extern void extract_smalltalk PARAMS ((FILE *fp, const char *real_filename, + const char *logical_filename, + msgdomain_list_ty *mdlp)); diff --git a/src/xgettext.c b/src/xgettext.c index 92b9dbf50..4224c2e95 100644 --- a/src/xgettext.c +++ b/src/xgettext.c @@ -63,6 +63,7 @@ #include "x-lisp.h" #include "x-elisp.h" #include "x-librep.h" +#include "x-smalltalk.h" #include "x-java.h" #include "x-awk.h" #include "x-ycp.h" @@ -580,8 +581,8 @@ If output file is -, output is written to standard output.\n\ Choice of input file language:\n\ -L, --language=NAME recognise the specified language\n\ (C, C++, ObjectiveC, PO, Python, Lisp,\n\ - EmacsLisp, librep, Java, awk, YCP, Tcl,\n\ - PHP, RST, Glade)\n\ + EmacsLisp, librep, Smalltalk, Java, awk,\n\ + YCP, Tcl, PHP, RST, Glade)\n\ -C, --c++ shorthand for --language=C++\n\ By default the language is guessed depending on the input file name extension.\n\ ")); @@ -1278,6 +1279,7 @@ language_to_extractor (name) SCANNERS_LISP SCANNERS_ELISP SCANNERS_LIBREP + SCANNERS_SMALLTALK SCANNERS_JAVA SCANNERS_AWK SCANNERS_YCP @@ -1325,6 +1327,7 @@ extension_to_language (extension) EXTENSIONS_LISP EXTENSIONS_ELISP EXTENSIONS_LIBREP + EXTENSIONS_SMALLTALK EXTENSIONS_JAVA EXTENSIONS_AWK EXTENSIONS_YCP diff --git a/tests/ChangeLog b/tests/ChangeLog index 12a0c5ada..96292d025 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2002-09-09 Bruno Haible + + * lang-smalltalk: New file. + * Makefile.am (TESTS): Add it. + 2002-08-18 Bruno Haible * format-php-1: New file. diff --git a/tests/Makefile.am b/tests/Makefile.am index a7ed94a6a..649ec7ec6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,7 +58,7 @@ TESTS = gettext-1 gettext-2 \ format-tcl-1 format-tcl-2 \ format-ycp-1 format-ycp-2 \ plural-1 plural-2 \ - lang-c lang-c++ lang-objc lang-python lang-clisp lang-elisp lang-librep lang-java lang-gawk lang-pascal lang-ycp lang-tcl lang-php lang-po lang-rst \ + lang-c lang-c++ lang-objc lang-python lang-clisp lang-elisp lang-librep lang-smalltalk lang-java lang-gawk lang-pascal lang-ycp lang-tcl lang-php lang-po lang-rst \ rpath-1a rpath-1b \ rpath-2aaa rpath-2aab rpath-2aac rpath-2aad \ rpath-2aba rpath-2abb rpath-2abc rpath-2abd \ diff --git a/tests/lang-smalltalk b/tests/lang-smalltalk new file mode 100755 index 000000000..1b39df417 --- /dev/null +++ b/tests/lang-smalltalk @@ -0,0 +1,118 @@ +#! /bin/sh + +# Test of gettext facilities in the GNU smalltalk language. +# Assumes an fr_FR locale is installed. +# Assumes the following packages are installed: smalltalk. + +tmpfiles="" +trap 'rm -fr $tmpfiles' 1 2 3 15 + +tmpfiles="$tmpfiles prog.st" +cat <<\EOF > prog.st +PackageLoader fileInPackage: 'I18N' ! + +Object subclass: #Main + instanceVariableNames: '' + classVariableNames: 'NLS' + poolDictionaries: '' + category: 'Program' +! +!Main methodsFor: 'running'! +run + | n | + NLS := I18N Locale default messages domain: 'prog' localeDirectory: '.'. + n := 2. + Transcript showCr: + (NLS ? '''Your command, please?'', asked the waiter.'). + Transcript showCr: + ((NLS at: 'a piece of cake' plural: '%1 pieces of cake' with: n) bindWith: n). + Transcript showCr: + ((NLS ? '%1 is replaced by %2.') bindWith: 'FF' with: 'EUR').! +! + +Main new run! +EOF + +tmpfiles="$tmpfiles prog.pot" +: ${XGETTEXT=xgettext} +${XGETTEXT} -o prog.pot --omit-header --no-location prog.st + +tmpfiles="$tmpfiles prog.ok" +cat < prog.ok +msgid "'Your command, please?', asked the waiter." +msgstr "" + +#, smalltalk-format +msgid "a piece of cake" +msgid_plural "%1 pieces of cake" +msgstr[0] "" +msgstr[1] "" + +#, smalltalk-format +msgid "%1 is replaced by %2." +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" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "'Your command, please?', asked the waiter." +msgstr "«Votre commande, s'il vous plait», dit le garçon." + +# Les gateaux allemands sont les meilleurs du monde. +#, smalltalk-format +msgid "a piece of cake" +msgid_plural "%1 pieces of cake" +msgstr[0] "un morceau de gateau" +msgstr[1] "%1 morceaux de gateau" + +# Reverse the arguments. +#, smalltalk-format +msgid "%1 is replaced by %2." +msgstr "%2 remplace %1." +EOF + +tmpfiles="$tmpfiles fr.po.new" +: ${MSGMERGE=msgmerge} +${MSGMERGE} -q -o fr.po.new fr.po prog.pot + +: ${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 gst version 2.0.6 or newer. +(gst --version) >/dev/null 2>/dev/null \ + || { echo "SKIP: lang-smalltalk"; rm -fr $tmpfiles; exit 77; } +case `gst --version | sed -n -e 1p | sed -e 's/^[^0-9]*//'` in + 0.* | 1.* | 2.0 | 2.0.[0-5]) + echo "SKIP: lang-smalltalk"; rm -fr $tmpfiles; exit 77;; +esac + +tmpfiles="$tmpfiles prog.ok prog.out" +: ${DIFF=diff} +cat <<\EOF > prog.ok +Loading package I18N +«Votre commande, s'il vous plait», dit le garçon. +2 morceaux de gateau +EUR remplace FF. +EOF + +LANGUAGE= LC_ALL=fr_FR gst -Q prog.st > prog.out || exit 1 +${DIFF} prog.ok prog.out || exit 1 + +rm -fr $tmpfiles + +exit 0