Commit 0b6f61c9 authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Set up gettext

parent ebdcdbda
Pipeline #108350 passed with stages
in 5 minutes and 35 seconds
......@@ -16,7 +16,7 @@
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
SUBDIRS = lib-library lib-program
SUBDIRS = po lib-library lib-program
if NEED_LIBOPTS
SUBDIRS += $(LIBOPTS_DIR)
......@@ -27,7 +27,7 @@ include defaults.am
ACLOCAL_AMFLAGS = -I m4 -I lib-library/m4 -I lib-program/m4
AUTOMAKE_OPTIONS = subdir-objects
dist_pkgdata_DATA += COPYING
EXTRA_DIST += lib-library/m4/gnulib-cache.m4
EXTRA_DIST += lib-library/m4/gnulib-cache.m4 po/Rules-html
include desktop.am
include version-gen.am
......
......@@ -32,7 +32,8 @@ gnulib-tool --libtool \
--source-base=lib-program \
--m4-base=lib-program/m4 \
--macro-prefix=gl_program \
--import assert git-version-gen getopt-gnu gitlog-to-changelog setenv xalloc readline || exit 1
--import assert git-version-gen getopt-gnu gitlog-to-changelog setenv xalloc readline \
setlocale || exit 1
./gitlog-to-changelog > ChangeLog
rm -rf libopts libopts-* || exit 1
gunzip -c `autoopts-config libsrc` | tar -xvf - || exit 1
......
......@@ -29,8 +29,8 @@ sh autogen.sh VALAFLAGS="--target-glib=2.50" || exit 1
--enable-silent-rules=yes \
|| (cat config.log ; exit 1) \
|| exit 1
(cd lib-library && make -j 16) || exit 1
(cd lib-program && make -j 16) || exit 1
(cd lib-library && make -j 16 CFLAGS="-Wno-error -g $CFLAGS") || exit 1
(cd lib-program && make -j 16 CFLAGS="-Wno-error -g $CFLAGS") || exit 1
make -j 16 distcheck || exit 1
make -j 16 check || exit 1
make -j 16 install install-html || exit 1
......@@ -69,6 +69,8 @@ do
case $source in
*.po | *.pot)
echo "Ignoring PO file $source, as it has a date in it.";;
./po/en@quot.header | ./po/en@boldquot.header | ./po/Rules-quot | ./po/remove-potcdate.sin | ./po/boldquot.sed | ./po/quot.sed | ./po/insert-header.sin | ./po/Makefile.in.in)
echo "Ignoring Gettext garbage $source.";;
./libopts/*)
echo "Ignoring embedded file $source, as it is not ours.";;
./.tarball-version)
......
......@@ -15,6 +15,10 @@ AC_SUBST([LIBTOOL_CURRENT], m4_esyscmd([./get-version.sh libtool | cut -d ':' -f
AC_SUBST([LIBTOOL_REVISION], m4_esyscmd([./get-version.sh libtool | cut -d ':' -f 2]))
AC_SUBST([LIBTOOL_AGE], m4_esyscmd([./get-version.sh libtool | cut -d ':' -f 3]))
AC_ARG_ENABLE([runtime-prefix], AS_HELP_STRING([--enable-runtime-prefix=ENV],
[At runtime, prepend the value of the environment variable ENV to the installation prefix. This is useful to make the package relocatable. If ENV is empty or 'no', this is disabled.]))
AC_DEFINE_UNQUOTED([RUNTIME_PREFIX_ENV], "$enable_runtime_prefix", [Environment variable to look up the installation prefix])
# Checks for programs.
AC_PROG_CC
AC_PROG_CC_STDC
......@@ -112,6 +116,9 @@ AS_IF([test "x$WITH_GTK" != "xno"], [
AC_SEARCH_LIBS([atan2], [m])
AC_SEARCH_LIBS([sin], [m])
AC_SEARCH_LIBS([cos], [m])
AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.19.8])
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$PACKAGE", [This needs to be defined in config.h manually...])
# Checks for header files.
AC_HEADER_STDBOOL
......@@ -130,7 +137,7 @@ AC_DEFINE([FIRST_LINE], [1], [First line of a file, for the lexer])
AC_DEFINE([FIRST_COLUMN], [1], [First column in a line, for the lexer])
AC_DEFINE([TAB_WIDTH], [8], [Number of columns in a tab])
AC_CONFIG_FILES([
AC_CONFIG_FILES([ po/Makefile.in
Makefile
lib-library/Makefile
lib-program/Makefile
......
fr
\ No newline at end of file
# Makefile variables for PO directory in any package using GNU gettext.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --from-code=UTF-8
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
# package. (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.) Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Vivien Kraus
# This tells whether or not to prepend "GNU " prefix to the package
# name that gets inserted into the header of the $(DOMAIN).pot file.
# Possible values are "yes", "no", or empty. If it is empty, try to
# detect it automatically by scanning the files in $(top_srcdir) for
# "GNU packagename" string.
PACKAGE_GNU =
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = vivien@planete-kraus.eu
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =
# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
# context. Possible values are "yes" and "no". Set this to yes if the
# package uses functions taking also a message context, like pgettext(), or
# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
USE_MSGCTXT = no
# These options get passed to msgmerge.
# Useful options are in particular:
# --previous to keep previous msgids of translated messages,
# --quiet to reduce the verbosity.
MSGMERGE_OPTIONS =
# These options get passed to msginit.
# If you want to disable line wrapping when writing PO files, add
# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and
# MSGINIT_OPTIONS.
MSGINIT_OPTIONS =
# This tells whether or not to regenerate a PO file when $(DOMAIN).pot
# has changed. Possible values are "yes" and "no". Set this to no if
# the POT file is checked in the repository and the version control
# program ignores timestamps.
PO_DEPENDS_ON_POT = yes
# This tells whether or not to forcibly update $(DOMAIN).pot and
# regenerate PO files on "make dist". Possible values are "yes" and
# "no". Set this to no if the POT file and PO files are maintained
# externally.
DIST_DEPENDS_ON_UPDATE_PO = yes
# List of source files which contain translatable strings.
src/tarot_cli.vala
src/engine/application.vala
src/engine/pretty_status.vala
src/engine/solo.vala
src/tarot-cli-opts.h
src/tarot-cli-opts.c
\ No newline at end of file
.PHONY: dvi install-dvi html install-html install-info install-man install-pdf pdf install-ps ps
dvi:
install-dvi:
html:
install-html:
install-info:
install-man:
install-pdf:
pdf:
install-ps:
ps:
\ No newline at end of file
This diff is collapsed.
......@@ -23,6 +23,7 @@ include %reldir%/libtarot-vapi.am
include %reldir%/libtarot-gir.am
include %reldir%/libtarot-typelib.am
include %reldir%/tarot-cli-program.am
include %reldir%/gettext-h.am
AM_CPPFLAGS += -I $(srcdir)/%reldir% -I %reldir%
......
......@@ -234,11 +234,11 @@ namespace Tarot {
seed_bytes[i] = seed[i];
}
if (e.set_setup (n_players, with_call) != 0) {
stderr.printf ("Dynamic memory exhausted\n");
stderr.printf (_ ("Dynamic memory exhausted\n"));
GLib.Process.abort ();
}
if (game.add_event (e) != 0) {
stderr.printf ("ERROR: this is not possible.\n");
stderr.printf (_ ("ERROR: this is not possible.\n"));
GLib.Process.abort ();
}
for (int i = 0; i <= retry; i++) {
......@@ -248,7 +248,7 @@ namespace Tarot {
deal_seed_bytes[j] = deal_current_seed[j];
}
if (e.set_deal_all_random (game.n_players (), deal_seed_bytes) != 0) {
stderr.printf ("ERROR: this is not possible.\n");
stderr.printf (_ ("ERROR: this is not possible.\n"));
GLib.Process.abort ();
}
if (game.add_event (e) == 0) {
......@@ -256,19 +256,19 @@ namespace Tarot {
autoreveal (game, false);
while (game.step () != Tarot.Step.END) {
if (mcts.set_base (game) != 0) {
stderr.printf ("Could not set up the MCTS.\n");
stderr.printf (_ ("Could not set up the MCTS.\n"));
GLib.Process.abort ();
}
if (mcts.run (n_iterations, seed_bytes) != 0) {
stderr.printf ("Could not explore this game.\n");
stderr.printf (_ ("Could not explore this game.\n"));
GLib.Process.abort ();
}
if (mcts.get_best (e) != 0) {
stderr.printf ("No exploration has been performed.\n");
stderr.printf (_ ("No exploration has been performed.\n"));
GLib.Process.abort ();
}
if (game.add_event (e) != 0) {
stderr.printf ("ERROR: the MCTS is not coherent.\n");
stderr.printf (_ ("ERROR: the MCTS is not coherent.\n"));
GLib.Process.abort ();
}
autoreveal (game, false);
......
......@@ -25,43 +25,43 @@ namespace Tarot {
private static string print_bid_cell (Tarot.Bid bid) {
switch (bid) {
case Tarot.Bid.PASS:
return " pass ";
return _ (" pass ");
case Tarot.Bid.TAKE:
return " take ";
return _ (" take ");
case Tarot.Bid.PUSH:
return " push ";
return _ (" push ");
case Tarot.Bid.STRAIGHT_KEEP:
return "str. kp.";
return _ ("str. kp.");
case Tarot.Bid.DOUBLE_KEEP:
return "dbl. kp.";
return _ ("dbl. kp.");
default:
assert_not_reached ();
}
}
private static string print_decl_cell (bool decl) {
if (decl) {
return " slam! ";
return _ (" slam! ");
} else {
return " pass ";
return _ (" pass ");
}
}
private static string print_player_cell (Tarot.Player player, bool taker, bool partner) {
// The 8 columns are divided as 3 + 2 + 3, with a 3-column
// marker left and right, to mark the taker and the
// partner respectively.
string marker_left = (taker ? "** " : " ");
string marker_right = (partner ? " * " : " ");
string marker_left = (taker ? _ ("** ") : " ");
string marker_right = (partner ? _ (" * ") : " ");
string middle = "??";
if (player == 0) {
middle = "P1";
middle = _ ("P1");
} else if (player == 1) {
middle = "P2";
middle = _ ("P2");
} else if (player == 2) {
middle = "P3";
middle = _ ("P3");
} else if (player == 3) {
middle = "P4";
middle = _ ("P4");
} else if (player == 4) {
middle = "P5";
middle = _ ("P5");
}
return marker_left + middle + marker_right;
}
......@@ -211,7 +211,7 @@ namespace Tarot {
return cell[first:last];
}
private static string print_call (Tarot.Card card) {
return " - Call: %s\n".printf (print_card (card));
return _ (" - Call: %s\n").printf (print_card (card));
}
private static string print_optional_call (Tarot.Card? card) {
if (card == null) {
......@@ -240,7 +240,7 @@ namespace Tarot {
}
}
private static string print_dog (Tarot.CardArray cards) {
return " - Dog: %s\n".printf (print_card_array (cards));
return _ (" - Dog: %s\n").printf (print_card_array (cards));
}
private static string print_optional_dog (Tarot.CardArray? cards) {
if (cards == null) {
......@@ -251,11 +251,11 @@ namespace Tarot {
}
private static string print_discard (Tarot.CardArray cards, bool full) {
if (cards.size () == 0) {
return " - The discard has been done.\n";
return _ (" - The discard has been done.\n");
} else if (full) {
return " - Discard: %s\n".printf (print_card_array (cards));
return _ (" - Discard: %s\n").printf (print_card_array (cards));
} else {
return " - Some cards of the discard: %s\n".printf (print_card_array (cards));
return _ (" - Some cards of the discard: %s\n").printf (print_card_array (cards));
}
}
private static string print_optional_discard (Tarot.CardArray? cards, bool full) {
......@@ -282,13 +282,13 @@ namespace Tarot {
if (size != 0) {
switch (size) {
case 1:
return (" - Simple handful of %s: %s\n"
return (_ (" - Simple handful of %s: %s\n")
.printf (print_player (who), print_card_array (cards)));
case 2:
return (" - Double handful of %s: %s\n"
return (_ (" - Double handful of %s: %s\n")
.printf (print_player (who), print_card_array (cards)));
case 3:
return (" - Triple handful of %s: %s\n"
return (_ (" - Triple handful of %s: %s\n")
.printf (print_player (who), print_card_array (cards)));
default:
assert_not_reached ();
......@@ -355,7 +355,7 @@ namespace Tarot {
}
private static string print_remaining (Tarot.Player who, Tarot.RemainingStatus remaining) {
if (remaining.known && remaining.cards.size () != 0) {
return " - Cards of %s: %s\n".printf (print_player (who), print_card_array (remaining.cards));
return _ (" - Cards of %s: %s\n").printf (print_player (who), print_card_array (remaining.cards));
}
return "";
}
......@@ -374,13 +374,13 @@ namespace Tarot {
switch (hint.mini) {
case Tarot.Bid.PASS:
case Tarot.Bid.TAKE:
return "%s may bid.\n".printf (player_name);
return _ ("%s may bid.\n").printf (player_name);
case Tarot.Bid.PUSH:
return "%s may pass, or at least push.\n".printf (player_name);
return _ ("%s may pass, or at least push.\n").printf (player_name);
case Tarot.Bid.STRAIGHT_KEEP:
return "%s may pass, straight or double keep.\n".printf (player_name);
return _ ("%s may pass, straight or double keep.\n").printf (player_name);
case Tarot.Bid.DOUBLE_KEEP:
return "%s mau pass, or double keep.\n".printf (player_name);
return _ ("%s mau pass, or double keep.\n").printf (player_name);
default:
assert_not_reached ();
}
......@@ -391,9 +391,9 @@ namespace Tarot {
}
string player_name = print_player (hint.who);
if (hint.allowed) {
return "%s may declare slam or pass.\n".printf (player_name);
return _ ("%s may declare slam or pass.\n").printf (player_name);
} else {
return "%s may not declare or pass.\n".printf (player_name);
return _ ("%s may not declare or pass.\n").printf (player_name);
}
}
private static string print_hint_call (Tarot.HintCall? hint) {
......@@ -403,13 +403,13 @@ namespace Tarot {
string player_name = print_player (hint.who);
switch (hint.mini) {
case 14:
return "%s may call a king.\n".printf (player_name);
return _ ("%s may call a king.\n").printf (player_name);
case 13:
return "%s may call a queen or a king.\n".printf (player_name);
return _ ("%s may call a queen or a king.\n").printf (player_name);
case 12:
return "%s may call a queen, a knight or a king.\n".printf (player_name);
return _ ("%s may call a queen, a knight or a king.\n").printf (player_name);
case 11:
return "%s may call any face card.\n".printf (player_name);
return _ ("%s may call any face card.\n").printf (player_name);
default:
assert_not_reached ();
}
......@@ -420,15 +420,15 @@ namespace Tarot {
}
string player_name = print_player (hint.who);
if (hint.prio.size () == 0) {
return "%s should discard %lu cards\n".printf (player_name, hint.n_cards);
return _ ("%s should discard %lu cards\n").printf (player_name, hint.n_cards);
} else if (hint.prio.size () > hint.n_cards) {
return ("%s should discard %lu cards among %s\n"
return (_ ("%s should discard %lu cards among %s\n")
.printf (player_name, hint.n_cards, print_card_array (hint.prio)));
} else if (hint.prio.size () == hint.n_cards) {
return ("%s should discard exactly these %lu cards: %s\n"
return (_ ("%s should discard exactly these %lu cards: %s\n")
.printf (player_name, hint.n_cards, print_card_array (hint.prio)));
} else {
return ("%s should discard %s, and %lu cards among %s\n"
return (_ ("%s should discard %s, and %lu cards among %s\n")
.printf (player_name, print_card_array (hint.prio),
hint.n_cards - hint.prio.size (),
print_card_array (hint.additional)));
......@@ -443,13 +443,13 @@ namespace Tarot {
string ret = "";
if (hint.prio.size () + hint.additional.size () >= hint.n_simple) {
if (hint.prio.size () > hint.n_simple) {
ret += ("%s can show a simple handful with %lu cards among %s\n"
ret += (_ ("%s can show a simple handful with %lu cards among %s\n")
.printf (player_name, hint.n_simple, print_card_array (hint.prio)));
} else if (hint.prio.size () == hint.n_simple) {
ret += ("%s can show a simple handful with these %lu cards: %s\n"
ret += (_ ("%s can show a simple handful with these %lu cards: %s\n")
.printf (player_name, hint.n_simple, print_card_array (hint.prio)));
} else {
ret += ("%s can show a simple handful with %s, and %lu cards among %s\n"
ret += (_ ("%s can show a simple handful with %s, and %lu cards among %s\n")
.printf (player_name, print_card_array (hint.prio),
hint.n_simple - hint.prio.size (),
print_card_array (hint.additional)));
......@@ -457,13 +457,13 @@ namespace Tarot {
}
if (hint.prio.size () + hint.additional.size () >= hint.n_double) {
if (hint.prio.size () > hint.n_double) {
ret += ("%s can show a double handful with %lu cards among %s\n"
ret += (_ ("%s can show a double handful with %lu cards among %s\n")
.printf (player_name, hint.n_double, print_card_array (hint.prio)));
} else if (hint.prio.size () == hint.n_double) {
ret += ("%s can show a double handful with these %lu cards: %s\n"
ret += (_ ("%s can show a double handful with these %lu cards: %s\n")
.printf (player_name, hint.n_double, print_card_array (hint.prio)));
} else {
ret += ("%s can show a double handful with %s, and %lu cards among %s\n"
ret += (_ ("%s can show a double handful with %s, and %lu cards among %s\n")
.printf (player_name, print_card_array (hint.prio),
hint.n_double - hint.prio.size (),
print_card_array (hint.additional)));
......@@ -471,13 +471,13 @@ namespace Tarot {
}
if (hint.prio.size () + hint.additional.size () >= hint.n_triple) {
if (hint.prio.size () > hint.n_triple) {
ret += ("%s can show a triple handful with %lu cards among %s\n"
ret += (_ ("%s can show a triple handful with %lu cards among %s\n")
.printf (player_name, hint.n_triple, print_card_array (hint.prio)));
} else if (hint.prio.size () == hint.n_triple) {
ret += ("%s can show a triple handful with these %lu cards: %s\n"
ret += (_ ("%s can show a triple handful with these %lu cards: %s\n")
.printf (player_name, hint.n_triple, print_card_array (hint.prio)));
} else {
ret += ("%s can show a triple handful with %s, and %lu cards among %s\n"
ret += (_ ("%s can show a triple handful with %s, and %lu cards among %s\n")
.printf (player_name, print_card_array (hint.prio),
hint.n_triple - hint.prio.size (),
print_card_array (hint.additional)));
......@@ -491,11 +491,11 @@ namespace Tarot {
}
string player_name = print_player (hint.who);
if (hint.playable.size () == 0) {
return "%s may play a card\n".printf (player_name);
return _ ("%s may play a card\n").printf (player_name);
} else if (hint.playable.size () == 1) {
return "%s may play %s\n".printf (player_name, print_card (hint.playable[0]));
return _ ("%s may play %s\n").printf (player_name, print_card (hint.playable[0]));
} else {
return "%s may play a card among %s\n".printf (player_name, print_card_array (hint.playable));
return _ ("%s may play a card among %s\n").printf (player_name, print_card_array (hint.playable));
}
}
public static string print (Tarot.Status status) {
......
......@@ -29,7 +29,7 @@ namespace Tarot {
output = null;
app.broadcast_event.connect ((e) => {
if (my_game.add_event (e) != 0) {
stderr.printf ("Could not add an event of type %s to game %s.\n",
stderr.printf (_ ("Could not add an event of type %s to game %s.\n"),
e.type ().to_string (), my_game.save_to_xml ());
assert (false);
}
......@@ -37,7 +37,7 @@ namespace Tarot {
app.unicast_event.connect ((e, who) => {
if (who == myself) {
if (my_game.add_event (e) != 0) {
stderr.printf ("Could not add an event of type %s to game %s.\n",
stderr.printf (_ ("Could not add an event of type %s to game %s.\n"),
e.type ().to_string (), my_game.save_to_xml ());
assert (false);
}
......@@ -47,23 +47,17 @@ namespace Tarot {
my_game = new Tarot.Game.alloc ();
});
if (!app.new_game (n_players, call)) {
stderr.printf ("Error: wrong number of players (%lu) or the call is not accepted\n",
stderr.printf (_ ("Error: wrong number of players (%lu) or the call is not accepted\n"),
n_players);
return 1;
}
if (!app.deal_random (seed, retry)) {
stderr.printf ("Error: wrong seed '%s', try another one\n", seed);
stderr.printf (_ ("Error: wrong seed '%s', try another one\n"), seed);
return 1;
}
bool eof = false;
stdout.printf ("
tarot %s
Copyright (C) 2019 Vivien Kraus\n
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it under
the conditions of the GNU General Public License, version 3 or later.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.\n", tarot_version);
stdout.printf (_ ("tarot %s\nCopyright (C) 2019 Vivien Kraus\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under\nthe conditions of the GNU General Public License, version 3 or later.\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <http://www.gnu.org/licenses/>.\n"),
tarot_version);
while (!eof && my_game.step () != Tarot.Step.END) {
var s = new Tarot.Status (my_game);
var ss = s.pretty;
......@@ -71,65 +65,56 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.\n", tarot_
assert (my_game.has_next ());
if (my_game.next () != myself) {
if (!app.mcts (seed, (int) n_iterations)) {
stderr.printf ("Error: could not auto play. Try with more iterations.\n");
stderr.printf (_ ("Error: could not auto play. Try with more iterations.\n"));
return 1;
}
} else {
string help_about_card_names = "The cards are formed by a number followed by a suit indicator. Examples are:
- AH: the ace of hearts;
- 10C: the ten of clubs;
- JS: the jack of spades;
- CD: the knight of diamonds;
- QH: the queen of hearts;
- KD: the knight of diamonds;
- 12T: the twelve of trumps;
- EXC: the excuse.
";
string help_about_card_names = _ ("The cards are formed by a number followed by a suit indicator. Examples are:\n - AH: the ace of hearts;\n - 10C: the ten of clubs;\n - JS: the jack of spades;\n - CD: the knight of diamonds;\n - QH: the queen of hearts;\n - KD: the knight of diamonds;\n - 12T: the twelve of trumps;\n - EXC: the excuse.\n");
var step = my_game.step ();
switch (step) {
case Tarot.Step.BIDS:
var line = readline ("bid> ");
var line = readline (_ ("bid> "));
if (line != null) {
line = line.strip ();
if (line == "pass" && app.bid (Tarot.Bid.PASS)) {
add_history ("pass");
} else if (line == "take" && app.bid (Tarot.Bid.TAKE)) {
add_history ("take");
} else if (line == "push" && app.bid (Tarot.Bid.PUSH)) {
add_history ("push");
} else if (line == "straight keep" && app.bid (Tarot.Bid.STRAIGHT_KEEP)) {
add_history ("straight keep");
} else if (line == "double keep" && app.bid (Tarot.Bid.DOUBLE_KEEP)) {
add_history ("double keep");
if (line == _ ("pass") && app.bid (Tarot.Bid.PASS)) {
add_history (_ ("pass"));
} else if (line == _ ("take") && app.bid (Tarot.Bid.TAKE)) {
add_history (_ ("take"));
} else if (line == _ ("push") && app.bid (Tarot.Bid.PUSH)) {
add_history (_ ("push"));
} else if (line == _ ("straight keep") && app.bid (Tarot.Bid.STRAIGHT_KEEP)) {
add_history (_ ("straight keep"));
} else if (line == _ ("double keep") && app.bid (Tarot.Bid.DOUBLE_KEEP)) {
add_history (_ ("double keep"));
} else {
stderr.printf ("The bids are 'pass', 'take', 'push', 'straight keep' and 'double keep', but you have to outbid.\n");
stderr.printf (_ ("The bids are 'pass', 'take', 'push', 'straight keep' and 'double keep', but you have to outbid.\n"));
}
} else {
eof = true;
}
break;
case Tarot.Step.DECLS:
var line = readline ("declare> ");
var line = readline (_ ("declare> "));
if (line != null) {
line = line.strip ();
if (line == "pass" && app.decl (false)) {
add_history ("pass");
} else if (line == "slam" && app.decl (true)) {
add_history ("slam");
if (line == _ ("pass") && app.decl (false)) {
add_history (_ ("pass"));
} else if (line == _ ("slam") && app.decl (true)) {
add_history (_ ("slam"));
} else {
stderr.printf ("The declarations are 'pass' or 'slam'.\n");
stderr.printf (_ ("The declarations are 'pass' or 'slam'.\n"));
}
} else {