commit b9921b07e7f30f23f9f6d5ecf52e0b87903a289f Author: Ahmed Siam Date: Fri Aug 18 15:47:37 2023 +0300 I18n of apertium diff --git a/.gitignore b/.gitignore index 22a1a23..2558425 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,9 @@ Makefile.in *.egg /apertium/apertium_deshtml_noent.cc /apertium/apertium_rehtml_alt.cc + +/.vscode/ +/locales/Makefile +/locales/Makefile.in +*.res +*.dat diff --git a/Makefile.am b/Makefile.am index dc6873f..a240334 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ACLOCAL_AMFLAGS=-I m4 -SUBDIRS = $(PACKAGE_NAME) scripts tests +SUBDIRS = $(PACKAGE_NAME) scripts tests locales DIST_SUBDIRS = $(PACKAGE_NAME) scripts tests modesdir=$(prefix)/share/apertium/modes @@ -23,3 +23,8 @@ install-data-local: # just a synonym: test: check + + +export LTTB_I18N_DATA=$(datadir)/lttoolbox/lttoolbox.dat +export LOCALES_DIR=$(datadir)/$(PACKAGE_NAME) +export APER_I18N_DATA=$(LOCALES_DIR)/apertium.dat diff --git a/README.md b/README.md deleted file mode 120000 index 100b938..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -README \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..da4b466 Binary files /dev/null and b/README.md differ diff --git a/apertium/Makefile.am b/apertium/Makefile.am index 6612f0c..af061ab 100644 --- a/apertium/Makefile.am +++ b/apertium/Makefile.am @@ -294,9 +294,9 @@ apertium_adapt_docx_SOURCES = adapt_docx.cc apertium_gen_modes_SOURCES = gen_modes.cc if WINDOWS -AM_CPPFLAGS = -I$(top_srcdir)/apertium/win32 -I$(top_srcdir) $(APERTIUM_CFLAGS) $(ICU_CFLAGS) +AM_CPPFLAGS = -I$(top_srcdir)/apertium/win32 -I$(top_srcdir) $(APERTIUM_CFLAGS) $(ICU_CFLAGS) -DAPER_I18N_DATA='"$(APER_I18N_DATA)"' -DLTTB_I18N_DATA='"$(LTTB_I18N_DATA)"' else -AM_CPPFLAGS = -I$(top_srcdir) $(APERTIUM_CFLAGS) $(ICU_CFLAGS) +AM_CPPFLAGS = -I$(top_srcdir) $(APERTIUM_CFLAGS) $(ICU_CFLAGS) -DAPER_I18N_DATA='"$(APER_I18N_DATA)"' -DLTTB_I18N_DATA='"$(LTTB_I18N_DATA)"' endif CLEANFILES = *~ apertium_destxt.cc apertium_retxt.cc apertium_deshtml.cc \ apertium_rehtml.cc apertium_desrtf.cc apertium_rertf.cc \ diff --git a/apertium/a.cc b/apertium/a.cc index f6644e1..1a938c3 100644 --- a/apertium/a.cc +++ b/apertium/a.cc @@ -16,6 +16,8 @@ #include "a.h" #include "exception.h" +#include +#include namespace Apertium { bool operator==(const a &a_, const a &b_) { @@ -33,14 +35,10 @@ a::a() : TheTags(), TheMorphemes() {} a::a(const Analysis &Analysis_) : TheTags(), TheMorphemes() { if (Analysis_.TheMorphemes.empty()) - throw Exception::Analysis::TheMorphemes_empty("can't convert const " - "Analysis & comprising empty " - "Morpheme std::vector to a"); + throw Exception::Analysis::TheMorphemes_empty(I18n(APER_I18N_DATA, "apertium").format("APER1013", {"letter"}, {"a"})); if (Analysis_.TheMorphemes.front().TheTags.empty()) - throw Exception::Morpheme::TheTags_empty("can't convert const Analysis & " - "comprising Morpheme comprising " - "empty Tag std::vector to a"); + throw Exception::Morpheme::TheTags_empty(I18n(APER_I18N_DATA, "apertium").format("APER1014", {"letter"}, {"a"})); TheTags = Analysis_.TheMorphemes.front().TheTags; TheMorphemes = std::vector(Analysis_.TheMorphemes.begin() + 1, diff --git a/apertium/adapt_docx.cc b/apertium/adapt_docx.cc index 91f4937..783d18e 100644 --- a/apertium/adapt_docx.cc +++ b/apertium/adapt_docx.cc @@ -32,24 +32,25 @@ #include #include "unicode/uchar.h" +#include +#include using namespace std; void endProgram(char *name) { - cout << basename(name) << ": makes some changes to .xml files from .docx components" << endl; - cout << "- moves word boundaries to 'legal' positions" << endl; - cout << "Gets input file name from stdin (or from -f), writes to stdout" << endl; - cout << "USAGE: " << basename(name) << " [-n] [-p] [-f filename]" << endl; - cout << "Options:" << endl; + I18n i18n {APER_I18N_DATA, "apertium"}; + cout << basename(name) << ": " << i18n.format("adapt_docx_desc") << endl; + cout << i18n.format("usage") << ": " << basename(name) << " [-n] [-p] [-f filename]" << endl; + cout << i18n.format("options") << ":" << endl; #if HAVE_GETOPT_LONG - cout << " -n, --name: writes \"< file name=\"filename\">\" to output" << endl; - cout << " -f, --file: gets file name as parameter" << endl; - cout << " -p, --pretty: outputs xml with a pretty format" << endl; + cout << " -n, --name: " << i18n.format("name_desc") << endl; + cout << " -f, --file: " << i18n.format("file_desc") << endl; + cout << " -p, --pretty: " << i18n.format("pretty_desc") << endl; #else - cout << " -n: writes \"< file name=\"filename\">\" to output" << endl; - cout << " -f: gets file name as parameter" << endl; - cout << " -p: outputs xml with a pretty format" << endl; + cout << " -n: " << i18n.format("name_desc") << endl; + cout << " -f: " << i18n.format("file_desc") << endl; + cout << " -p: " << i18n.format("pretty_desc") << endl; #endif exit(EXIT_FAILURE); } @@ -233,7 +234,7 @@ Paragraph::Paragraph(xmlNode *_root) void showParagraphs(xmlNode *root) { vector pp = Walker::findAll(root, "p", true); - cout << pp.size() << " paragraphs found" << endl; + cout << pp.size() << " " << I18n(APER_I18N_DATA, "apertium").format("paragraphs_found") << endl; for (auto it1 = pp.begin(); it1 != pp.end(); it1++) { Paragraph p(*it1); bool first = true; @@ -403,7 +404,7 @@ void process(string fileName, bool outputsName, bool pretty) { xmlDoc *document = xmlReadFile(fileName.c_str(), NULL, XML_PARSE_NOENT); if (document == NULL) { - cerr << "error: could not parse file \"" << fileName << "\"" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {fileName.c_str()}, false); return; } process(xmlDocGetRootElement(document)); @@ -411,7 +412,7 @@ void process(string fileName, bool outputsName, bool pretty) int sizeBuffer; xmlDocDumpFormatMemory(document, &buffer, &sizeBuffer, pretty ? 1: 0); if (outputsName) - cout << " "; + cout << "<" << I18n(APER_I18N_DATA, "apertium").format("file_name") << "=\"" << fileName << "\"/> "; const unsigned char *p = buffer; p = printNl2spc(p); if (pretty) diff --git a/apertium/analysis.cc b/apertium/analysis.cc index 48dfcd3..aab1be9 100644 --- a/apertium/analysis.cc +++ b/apertium/analysis.cc @@ -17,6 +17,8 @@ #include "exception.h" +#include + namespace Apertium { std::ostream &operator<<(std::ostream &Stream_, const Analysis &Analysis_) { ::operator<<(Stream_, static_cast(Analysis_)); @@ -35,9 +37,7 @@ bool operator<(const Analysis &a, const Analysis &b) { Analysis::operator UString() const { if (TheMorphemes.empty()) - throw Exception::Analysis::TheMorphemes_empty( - "can't convert Analysis comprising empty Morpheme std::vector to " - "UString"); + throw Exception::Analysis::TheMorphemes_empty(I18n(APER_I18N_DATA, "apertium").format("APER1015")); std::vector::const_iterator Morpheme_ = TheMorphemes.begin(); UString UString_ = *Morpheme_; @@ -62,7 +62,7 @@ Analysis::read(InputFile& in) c = in.get(); } while (c == '+'); if (in.eof() || c == '\0') { - throw Exception::Stream::UnexpectedEndOfFile("Unterminated lexical unit"); + throw Exception::Stream::UnexpectedEndOfFile(I18n(APER_I18N_DATA, "apertium").format("APER1016")); } in.unget(c); // leave $ or / for caller } diff --git a/apertium/apertium-header.sh b/apertium/apertium-header.sh index a2ffd63..853ff6c 100644 --- a/apertium/apertium-header.sh +++ b/apertium/apertium-header.sh @@ -17,23 +17,8 @@ # along with this program; if not, see . message () { - echo "USAGE: $(basename "$0") [-d datadir] [-f format] [-u] [in [out]]" - echo " -d datadir directory of linguistic data" - echo " -f format one of: txt (default), html, rtf, odt, odp, docx, wxml, xlsx, pptx," - echo " xpresstag, html-noent, html-alt, latex, latex-raw, line" - echo " -a display ambiguity" - echo " -u don't display marks '*' for unknown words" - echo " -n don't insert period before possible sentence-ends" - echo " -m memory.tmx use a translation memory to recycle translations" - echo " -o direction translation direction using the translation memory," - echo " by default 'direction' is used instead" - echo " -l lists the available translation directions and exits" - echo " -V print Apertium version" - # This is wrong and should be deprecated, but until all tools consider \0 flush without -z then this helps to have - echo " -z force null-flush mode on all parts of the pipe" - echo " direction typically, LANG1-LANG2, but see modes.xml in language data" - echo " in input file (stdin by default)" - echo " out output file (stdout by default)" + # -z option is wrong and should be deprecated, but until all tools consider \0 flush without -z then this helps to have + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "apertium_desc" "basename" "$(basename "$0")" exit 1 } @@ -47,7 +32,7 @@ locale_utf8 () { export LC_CTYPE LC_CTYPE=$(locale -a|grep -i "utf[.-]*8"|head -1) if [[ -z ${LC_CTYPE} ]]; then - echo "Error: Install an UTF-8 locale in your system" + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1158" exit 1 fi } @@ -57,7 +42,7 @@ check_encoding () { local encoding encoding=$(file -b --mime-encoding "${file}") if [[ "${encoding}" != utf-8 && "${encoding}" != us-ascii ]]; then - echo "Input seems to be non-UTF-8, please convert to UTF-8 (e.g. with 'iconv -f ${encoding} -t utf-8')" >&2 + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1159" "encoding" "$encoding" >&2 exit 1 fi } @@ -67,7 +52,7 @@ check_transfuse () { has_tf=$(command -v tf-extract) if [[ "$APERTIUM_TRANSFUSE" = "1" || "$APERTIUM_TRANSFUSE" = "yes" ]]; then if [[ -z "$has_tf" ]]; then - echo "APERTIUM_TRANSFUSE=$APERTIUM_TRANSFUSE but couldn't find Transfuse's tf-extract in PATH" + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1159" "APERTIUM_TRANSFUSE" "$APERTIUM_TRANSFUSE" exit 1 fi fi @@ -111,19 +96,19 @@ run_mode_wblank_force_flush () { test_zip () { if ! command -v zip &>/dev/null; then - echo "Error: Install 'zip' command in your system"; + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1161" "command" "zip" exit 1; fi if ! command -v unzip &>/dev/null; then - echo "Error: Install 'unzip' command in your system"; + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1161" "command" "unzip" exit 1; fi } test_gawk () { if ! command -v gawk &>/dev/null; then - echo "Error: Install 'gawk' in your system" + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1161" "command" "gawk" exit 1 fi } @@ -462,8 +447,8 @@ while getopts ":uahlVzf:d:m:o:nH" opt; do V) echo "${apertium_version}" && exit 0 ;; z) NULL_FLUSH+=(-z) ;; h) message ;; - \?) echo "ERROR: Unknown option $OPTARG" >&2; message >&2 ;; - *) echo "ERROR: $OPTARG requires an argument" >&2; message >&2 ;; + \?) icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1108" "opt" "$OPTARG" >&2; message >&2 ;; + *) icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1162" "opt" "$OPTARG" >&2; message >&2 ;; esac done shift $(( OPTIND-1 )) @@ -493,29 +478,28 @@ case "$#" in esac if [[ ! -e "$INFILE" ]]; then - echo "Error: file '$INFILE' not found." >&2 + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$INFILE" >&2 message >&2 elif [[ ! -r "$INFILE" ]]; then - echo "Error: file '$INFILE' is not readable by you." >&2 + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$INFILE" >&2 message >&2 fi if [[ -n $TRANSLATION_MEMORY_FILE ]]; then if ! lt-tmxcomp "$TRANSLATION_MEMORY_DIRECTION" "$TRANSLATION_MEMORY_FILE" "$TMCOMPFILE" >/dev/null; then - echo "Error: Cannot compile TM '$TRANSLATION_MEMORY_FILE'" >&2 - echo" hint: use -o parameter" >&2 + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1163" "file" "$TRANSLATION_MEMORY_FILE" >&2 message >&2 fi fi if [[ ! -d "$DATADIR/modes" ]]; then - echo "Error: Directory '$DATADIR/modes' does not exist." >&2 + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1164" "directory" "$DATADIR/modes" >&2 message >&2 fi if [[ ! -e "$DATADIR/modes/$PAIR.mode" ]]; then { - echo -n "Error: Mode $PAIR does not exist" + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1164" "mode" "$PAIR" c=$(find "$DATADIR/modes" -name '*.mode' | wc -l) if [[ "$c" -le 1 ]]; then echo "." @@ -637,7 +621,7 @@ case "$FORMAT" in OPTION="-n"; MILOCALE=$(locale -a | grep -E -i -v -m1 'utf|^C|^POSIX$') if [[ -z "$MILOCALE" ]]; then - echo "Error: Install a ISO-8859-1 compatible locale in your system"; + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1166"; exit 1; fi export LC_CTYPE=$MILOCALE @@ -674,7 +658,7 @@ case "$FORMAT" in *) # Por defecto asumimos txt - echo "$0 WARNING: Unknown format ${FORMAT}, treating as 'txt'" >&2 + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1167" "arg" "format" "$0" "${FORMAT}" >&2 FORMAT="txt" OPTION="-g" ;; diff --git a/apertium/apertium-multiple-translations.cc b/apertium/apertium-multiple-translations.cc index f7a6443..1ef82ea 100644 --- a/apertium/apertium-multiple-translations.cc +++ b/apertium/apertium-multiple-translations.cc @@ -28,16 +28,19 @@ #include #include #endif +#include +#include using namespace std; void message(char *progname) { - cerr << "USAGE: " << basename(progname) << " preproc biltrans [input [output]]" << endl; - cerr << " preproc result of preprocess trules file" << endl; - cerr << " biltrans bilingual letter transducer file" << endl; - cerr << " input input file, standard input by default" << endl; - cerr << " output output file, standard output by default" << endl; + I18n i18n {APER_I18N_DATA, "apertium"}; + cerr << i18n.format("usage") << ": " << basename(progname) << " preproc biltrans [input [output]]" << endl; + cerr << " preproc " << i18n.format("preproc_desc") << endl; + cerr << " biltrans " << i18n.format("biltrans_desc") << endl; + cerr << " input " << i18n.format("input_desc") << endl; + cerr << " output " << i18n.format("output_desc") << endl; exit(EXIT_FAILURE); } @@ -55,9 +58,7 @@ int main(int argc, char *argv[]) struct stat mybuf; if(stat(argv[i], &mybuf) == -1) { - cerr << "Error: can't stat file '"; - cerr << argv[i] << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {argv[i]}, true); } } @@ -66,17 +67,14 @@ int main(int argc, char *argv[]) if(argc >= 4) { if (!input.open(argv[3])) { - cerr << "Error: can't open input file '" << argv[3] << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {argv[3]}, true); } if(argc == 5) { output = u_fopen(argv[4], "w", NULL, NULL); if(!output) { - cerr << "Error: can't open output file '"; - cerr << argv[4] << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {argv[4]}, true); } } } diff --git a/apertium/apertium_cleanstream.cc b/apertium/apertium_cleanstream.cc index 444bfb8..4b0c22d 100644 --- a/apertium/apertium_cleanstream.cc +++ b/apertium/apertium_cleanstream.cc @@ -29,6 +29,7 @@ #ifdef __MINGW32__ #include #endif +#include using namespace std; @@ -63,7 +64,7 @@ main (int argc, char** argv) c = input.get(); if (c == '^') { if (intoken) { - cerr << "Error: unescaped '^': " << buf << "^" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1001", {"buf"}, {icu::UnicodeString(buf.data())}, false); buf += "\\^"_u; } else { intoken = true; @@ -79,7 +80,7 @@ main (int argc, char** argv) write(buf, output); buf.clear(); } else { - cerr << "Error: stray '$'" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1002", {}, {}, false); } } else if(c == '\\') { c = input.get(); diff --git a/apertium/apertium_compile_caps.cc b/apertium/apertium_compile_caps.cc index 04b8681..faa705c 100644 --- a/apertium/apertium_compile_caps.cc +++ b/apertium/apertium_compile_caps.cc @@ -19,12 +19,14 @@ #include #include #include +#include int main(int argc, char** argv) { + I18n i18n {APER_I18N_DATA, "apertium"}; LtLocale::tryToSetLocale(); - CLI cli("compile capitalization restoration rules"); - cli.add_bool_arg('h', "help", "print this message and exit"); + CLI cli(i18n.format("compile_caps_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.add_file_arg("rule_file", false); cli.add_file_arg("output_file", false); cli.parse_args(argc, argv); diff --git a/apertium/apertium_extract_caps.cc b/apertium/apertium_extract_caps.cc index 60af6f6..b49e951 100644 --- a/apertium/apertium_extract_caps.cc +++ b/apertium/apertium_extract_caps.cc @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef __MINGW32__ #include @@ -64,13 +65,14 @@ std::pair read_lu(InputFile& input) int main(int argc, char* argv[]) { + I18n i18n {APER_I18N_DATA, "apertium"}; LtLocale::tryToSetLocale(); - CLI cli("Transfer capitalization information to word-bound blanks"); + CLI cli(i18n.format("extract_caps_desc")); cli.add_file_arg("input_file"); cli.add_file_arg("output_file"); - cli.add_bool_arg('s', "surface", "keep surface forms"); - cli.add_bool_arg('z', "null-flush", "flush output on the null character"); - cli.add_bool_arg('h', "help", "print this message and exit"); + cli.add_bool_arg('s', "surface", i18n.format("surface_desc")); + cli.add_bool_arg('z', "null-flush", i18n.format("null_flush_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.parse_args(argc, argv); bool keep_surf = cli.get_bools()["surface"]; diff --git a/apertium/apertium_filter_ambiguity.cc b/apertium/apertium_filter_ambiguity.cc index c9c61c3..ed7b1a0 100644 --- a/apertium/apertium_filter_ambiguity.cc +++ b/apertium/apertium_filter_ambiguity.cc @@ -33,6 +33,8 @@ #include #include #endif +#include +#include using namespace Apertium; using namespace std; @@ -43,7 +45,7 @@ int main(int argc, char *argv[]) if(argc < 2 || argc > 4) { - cerr << "USAGE: " << basename(argv[0]) << " tsx_file [input [output]" << endl; + cerr << I18n(APER_I18N_DATA, "apertium").format("usage") << ": " << basename(argv[0]) << " tsx_file [input [output]" << endl; exit(EXIT_FAILURE); } @@ -54,8 +56,7 @@ int main(int argc, char *argv[]) case 4: output = u_fopen(argv[3], "w", NULL, NULL); if (!output) { - cerr << "Error: Unable to open '" << argv[3] << "' for writing." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {argv[3]}, true); } // no break case 3: diff --git a/apertium/apertium_interchunk.cc b/apertium/apertium_interchunk.cc index d2ea8c7..b699568 100644 --- a/apertium/apertium_interchunk.cc +++ b/apertium/apertium_interchunk.cc @@ -18,24 +18,22 @@ #include #include #include +#include int main(int argc, char *argv[]) { + I18n i18n {APER_I18N_DATA, "apertium"}; LtLocale::tryToSetLocale(); - CLI cli("process stream with interchunker"); + CLI cli(i18n.format("interchunck_desc")); cli.add_file_arg("t2x", false); cli.add_file_arg("preproc", false); cli.add_file_arg("input"); cli.add_file_arg("output"); - cli.add_bool_arg('t', "trace", "trace mode"); - cli.add_bool_arg('w', "dictionary-case", "ignore capitalization manipulation instructions"); - cli.add_bool_arg('z', "null-flush", "flush buffer on '\\0'"); - cli.add_bool_arg('h', "help", "show this message and exit"); - cli.set_epilog("FILES:\n" \ - " t2x t2x rules file\n" \ - " preproc result of preprocess trules file\n" \ - " input input file, standard input by default\n" \ - " output output file, standard output by default"); + cli.add_bool_arg('t', "trace", i18n.format("trace_desc")); + cli.add_bool_arg('w', "dictionary-case", i18n.format("dictionary_case_desc")); + cli.add_bool_arg('z', "null-flush", i18n.format("null_flush_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); + cli.set_epilog(i18n.format("chunck_epilog")); cli.parse_args(argc, argv); Interchunk i; diff --git a/apertium/apertium_perceptron_trace.cc b/apertium/apertium_perceptron_trace.cc index e2c3299..4656322 100644 --- a/apertium/apertium_perceptron_trace.cc +++ b/apertium/apertium_perceptron_trace.cc @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace Apertium { @@ -29,9 +31,9 @@ int perceptron_trace(int argc, char* argv[]) PerceptronSpec spec; MTXReader mtx_reader(spec); mtx_reader.read(argv[2]); - std::cout << "== Macro definitions ==\n"; + std::cout << "== " << I18n(APER_I18N_DATA, "apertium").format("macro_definitions") << " ==\n"; mtx_reader.printTmplDefns(); - std::cout << "== Spec ==\n"; + std::cout << "== " << I18n(APER_I18N_DATA, "apertium").format("spec") << " ==\n"; std::cout << spec; } else if (argc == 5 && std::string(argv[1]) == "path") @@ -88,15 +90,7 @@ int perceptron_trace(int argc, char* argv[]) } else { - std::cout << "Run with one of:\n"; - std::cout << argv[0] << " model \n"; - std::cout << "Output features and weights from a model file.\n"; - std::cout << argv[0] << " mtx \n"; - std::cout << "Output macros and features from an mtx file.\n"; - std::cout << argv[0] << " path \n"; - std::cout << "Trace a particular path through giving which features fire " - << "and the resulting score. Useful for interactively " - << "designing feature sets.\n"; + std::cout << I18n(APER_I18N_DATA, "apertium").format("perceptron_trace_desc", {"program_name"}, {argv[0]}); } return 0; } diff --git a/apertium/apertium_postchunk.cc b/apertium/apertium_postchunk.cc index ec7da0d..9e8f1f1 100644 --- a/apertium/apertium_postchunk.cc +++ b/apertium/apertium_postchunk.cc @@ -18,24 +18,22 @@ #include #include #include +#include int main(int argc, char *argv[]) { + I18n i18n {APER_I18N_DATA, "apertium"}; LtLocale::tryToSetLocale(); - CLI cli("process stream with postchunker"); + CLI cli(i18n.format("postchunck_desc")); cli.add_file_arg("t3x", false); cli.add_file_arg("preproc", false); cli.add_file_arg("input"); cli.add_file_arg("output"); - cli.add_bool_arg('t', "trace", "trace mode"); - cli.add_bool_arg('w', "dictionary-case", "ignore capitalization manipulation instructions"); - cli.add_bool_arg('z', "null-flush", "flush buffer on '\\0'"); - cli.add_bool_arg('h', "help", "show this message and exit"); - cli.set_epilog("FILES:\n" \ - " t3x t3x rules file\n" \ - " preproc result of preprocess trules file\n" \ - " input input file, standard input by default\n" \ - " output output file, standard output by default"); + cli.add_bool_arg('t', "trace", i18n.format("trace_desc")); + cli.add_bool_arg('w', "dictionary-case", i18n.format("dictionary_case_desc")); + cli.add_bool_arg('z', "null-flush", i18n.format("null_flush_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); + cli.set_epilog(i18n.format("chunck_epilog")); cli.parse_args(argc, argv); Postchunk p; diff --git a/apertium/apertium_posttransfer.cc b/apertium/apertium_posttransfer.cc index a19b7b7..0427f31 100644 --- a/apertium/apertium_posttransfer.cc +++ b/apertium/apertium_posttransfer.cc @@ -28,15 +28,18 @@ #include #include #include +#include +#include using namespace std; void usage(char *progname) { - cerr << "USAGE: " << basename(progname) << " [input_file [output_file]]" << endl; - cerr << " -z null-flushing output on '\0'" << endl; - cerr << " -h shows this message" << endl; + I18n i18n {APER_I18N_DATA, "apertium"}; + cerr << i18n.format("usage") << ": " << basename(progname) << " [input_file [output_file]]" << endl; + cerr << " -z " << i18n.format("null_flush_desc") << endl; + cerr << " -h " << i18n.format("help_desc") << endl; exit(EXIT_FAILURE); } @@ -121,8 +124,7 @@ int main(int argc, char *argv[]) if(input.eof()) { - cerr << "ERROR: Can't read file '" << argv[1] << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {argv[1]}, true); } processStream(input, output, null_flush); diff --git a/apertium/apertium_pretransfer.cc b/apertium/apertium_pretransfer.cc index f5c07f0..b682b7c 100644 --- a/apertium/apertium_pretransfer.cc +++ b/apertium/apertium_pretransfer.cc @@ -28,16 +28,19 @@ #include #include #include +#include +#include using namespace std; void usage(char *progname) { - cerr << "USAGE: " << basename(progname) << " [input_file [output_file]]" << endl; - cerr << " -n assume no surface forms" << endl; - cerr << " -e treat ~ as compound separator" << endl; - cerr << " -z null-flushing output on '\\0'" << endl; - cerr << " -h shows this message" << endl; + I18n i18n {APER_I18N_DATA, "apertium"}; + cerr << i18n.format("usage") << ": " << basename(progname) << " [input_file [output_file]]" << endl; + cerr << " -n " << i18n.format("no_surface_forms_desc") << endl; + cerr << " -e " << i18n.format("compounds_desc") << endl; + cerr << " -z " << i18n.format("null_flush_desc") << endl; + cerr << " -h " << i18n.format("help_desc") << endl; exit(EXIT_FAILURE); } @@ -116,8 +119,7 @@ int main(int argc, char *argv[]) if(input.eof()) { - cerr << "ERROR: Can't read file '" << argv[1] << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {argv[1]}, true); } processStream(input, output, null_flush, surface_forms, compound_sep); diff --git a/apertium/apertium_re.cc b/apertium/apertium_re.cc index c128abf..637d571 100644 --- a/apertium/apertium_re.cc +++ b/apertium/apertium_re.cc @@ -37,8 +37,7 @@ ApertiumRE::read(FILE *input) { unsigned int size = Compression::multibyte_read(input); if (fseek(input, size, SEEK_CUR) != 0) { - cerr << "Error reading regexp" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1017", {}, {}, true); } } @@ -52,9 +51,8 @@ ApertiumRE::compile(UString const &str) UErrorCode err = U_ZERO_ERROR; re = RegexPattern::compile(s, UREGEX_DOTALL|UREGEX_CASE_INSENSITIVE, err); if(U_FAILURE(err)) { - cerr << "Error: unable to compile regular expression '" << str << "'." << endl; - cerr << "error code: " << u_errorName(err) << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1018", {"exp", "error"}, + {icu::UnicodeString(str.data()), u_errorName(err)}, true); } } @@ -62,8 +60,7 @@ void ApertiumRE::write(FILE *output) const { if (re == nullptr) { - cerr << "Error, cannot write empty regexp" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1019", {}, {}, true); } // for backwards compatibility, write empty binary form Compression::multibyte_write(0, output); @@ -81,9 +78,8 @@ ApertiumRE::match(UString const &str) const RegexMatcher* m = re->matcher(s, err); if (U_FAILURE(err)) { - cerr << "Error: Unable to apply regexp" << endl; - cerr << "error code: " << u_errorName(err) << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1020", {"error"}, + {u_errorName(err)}, true); } if (!m->find()) { @@ -93,9 +89,8 @@ ApertiumRE::match(UString const &str) const UString ret = m->group(err).getTerminatedBuffer(); if (U_FAILURE(err)) { - cerr << "Error: Unable to extract substring from regexp match" << endl; - cerr << "error code: " << u_errorName(err) << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1021", {"error"}, + {u_errorName(err)}, true); } delete m; @@ -116,9 +111,8 @@ ApertiumRE::replace(UString &str, UString const &value) const RegexMatcher* m = re->matcher(s, err); if (U_FAILURE(err)) { - cerr << "Error: Unable to apply regexp" << endl; - cerr << "error code: " << u_errorName(err) << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1020", {"error"}, + {u_errorName(err)}, true); } // do this manually rather than call m->replaceFirst() diff --git a/apertium/apertium_restore_caps.cc b/apertium/apertium_restore_caps.cc index 9cf1b79..b4d0ece 100644 --- a/apertium/apertium_restore_caps.cc +++ b/apertium/apertium_restore_caps.cc @@ -19,14 +19,16 @@ #include #include #include +#include int main(int argc, char** argv) { LtLocale::tryToSetLocale(); - CLI cli("compile capitalization restoration rules"); - cli.add_bool_arg('k', "keep", "retain all wblanks"); - cli.add_bool_arg('z', "null-flush", "flush output on null character"); - cli.add_bool_arg('h', "help", "print this message and exit"); + I18n i18n {APER_I18N_DATA, "apertium"}; + CLI cli(i18n.format("restore_caps_desc")); + cli.add_bool_arg('k', "keep", i18n.format("keep_desc")); + cli.add_bool_arg('z', "null-flush", i18n.format("null_flush_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.add_file_arg("rule_file", false); cli.add_file_arg("input_file", true); cli.add_file_arg("output_file", true); diff --git a/apertium/apertium_tagger.cc b/apertium/apertium_tagger.cc index a58f861..47e9200 100644 --- a/apertium/apertium_tagger.cc +++ b/apertium/apertium_tagger.cc @@ -29,13 +29,15 @@ #include #include #include +#include +#include int main(int argc, char **argv) { LtLocale::tryToSetLocale(); try { Apertium::apertium_tagger(argc, argv); } catch (const Apertium::Exception::apertium_tagger::err_Exception &err_Exception_) { - std::cerr << "Try 'apertium-tagger --help' for more information." << std::endl; + std::cerr << I18n(APER_I18N_DATA, "apertium").format("tagger_note") << std::endl; return 1; } catch (...) { throw; diff --git a/apertium/apertium_tagger_apply_new_rules.cc b/apertium/apertium_tagger_apply_new_rules.cc index e99997f..da271c1 100644 --- a/apertium/apertium_tagger_apply_new_rules.cc +++ b/apertium/apertium_tagger_apply_new_rules.cc @@ -28,6 +28,8 @@ #include #include #include +#include +#include using namespace Apertium; @@ -39,21 +41,21 @@ TTag eos; //End-of-sentence tag void check_file(FILE *f, const string& path) { if (!f) { - cerr<<"Error: cannot open file '"< #include +#include +#include using namespace std; @@ -35,8 +37,7 @@ bool check_ambclasses; void check_file(FILE *f, const string& path) { if (!f) { - cerr<<"Error: cannot open file '"<get_tags()]; if ((k>=tagger_data_hmm.getM())||(k<0)) { - cerr<<"Error: Ambiguity class number out of range: "<get_superficial_form() << "\n"; - cerr<<"Ambiguity class: "<< word->get_string_tags() << "\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1025", {"number", "word", "class"}, + {k, icu::UnicodeString(word->get_superficial_form().data()), + icu::UnicodeString(word->get_string_tags().data())}, false); } } @@ -68,18 +69,19 @@ void readwords (int corpus_length) { word=lexmorfo.get_next_word(); } - cerr<] < file.crp \n\n"; - cerr<<"ARGUMENTS: \n" - <<" --tsxfile|-x: Specify a tagger specification file\n" - <<" --probfile|-p: Specify a tagger parameter file\n" - <<" --clength|-l: Specify the length of the corpus to process\n"; + cerr<< i18n.format("arguments") << ": \n" + <<" --tsxfile|-x: " << i18n.format("readwords_tsxfile") << "Specify a tagger specification file\n" + <<" --probfile|-p: " << i18n.format("probfile_desc") << "\n" + <<" --clength|-l: " << i18n.format("clength_desc") << "\n"; } @@ -92,9 +94,10 @@ int main(int argc, char* argv[]) { int c; int option_index=0; - cerr<<"LOCALE: "< #include "apertium_config.h" #include +#include +#include using namespace std; void usage(char *progname) { - cerr << "USAGE: " << basename(progname) << " [options] code1 code2 doc1 doc2 [output_file]" << endl; - cerr << "Options:" << endl; - cerr << " -p percent number 0 < n <= 1 to set margin of confidence of TU's " << endl; - cerr << " (0.85 by default) in length terms" << endl; - cerr << " -e edit number 0 < n <= 1 to set margin of confidence of TU's " << endl; - cerr << " (0.30 by default) in edit distance terms" << endl; - cerr << " -l low-limit ignore percent if the segment is less than lowlimit" < #include #endif +#include +#include using namespace std; void message(char *progname) { - cerr << "USAGE: " << basename(progname) << " trules preproc biltrans [input [output]]" << endl; + I18n i18n {APER_I18N_DATA, "apertium"}; + cerr << i18n.format("usage") << ": " + << basename(progname) << " trules preproc biltrans [input [output]]" << endl; cerr << " " << basename(progname) << " -b trules preproc [input [output]]" << endl; cerr << " " << basename(progname) << " -n trules preproc [input [output]]" << endl; cerr << " " << basename(progname) << " -x extended trules preproc biltrans [input [output]]" << endl; cerr << " " << basename(progname) << " -c trules preproc biltrans [input [output]]" << endl; cerr << " " << basename(progname) << " -t trules preproc biltrans [input [output]]" << endl; - cerr << " trules transfer rules file" << endl; - cerr << " preproc result of preprocess trules file" << endl; - cerr << " biltrans bilingual letter transducer file" << endl; - cerr << " input input file, standard input by default" << endl; - cerr << " output output file, standard output by default" << endl; - cerr << " -b input from lexical transfer" << endl; - cerr << " -n don't use bilingual dictionary" << endl; - cerr << " -x bindix extended mode with user dictionary" << endl; - cerr << " -c case-sensitiveness while accessing bilingual dictionary" << endl; - cerr << " -t trace (show rule numbers and patterns matched)" << endl; - cerr << " -T trace, for apertium-transfer-tools (also sets -t)" << endl; - cerr << " -w ignore capitalization manipulation instructions" << endl; - cerr << " -z null-flushing output on '\0'" << endl; - cerr << " -h shows this message" << endl; + cerr << " trules " << i18n.format("trules_desc") << endl; + cerr << " preproc " << i18n.format("preproc_desc") << endl; + cerr << " biltrans " << i18n.format("biltrans_desc") << endl; + cerr << " input " << i18n.format("input_desc") << endl; + cerr << " output " << i18n.format("output_desc") << endl; + cerr << " -b " << i18n.format("from_bilingual_desc") << endl; + cerr << " -n " << i18n.format("no_bilingual_desc") << endl; + cerr << " -x bindix " << i18n.format("extended_desc") << endl; + cerr << " -c " << i18n.format("case_sensitive_desc") << endl; + cerr << " -t " << i18n.format("trace_desc") << endl; + cerr << " -T " << i18n.format("trace_att_desc") << endl; + cerr << " -w " << i18n.format("dictionary_case_desc") << endl; + cerr << " -z " << i18n.format("null_flush_desc") << endl; + cerr << " -h " << i18n.format("help_desc") << endl; exit(EXIT_FAILURE); @@ -64,18 +68,14 @@ void testfile(string const &filename) struct stat mybuf; if(stat(filename.c_str(), &mybuf) == -1) { - cerr << "Error: can't stat file '"; - cerr << filename << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {filename.c_str()}, true); } } void open_input(InputFile& input, const char* filename) { if (!input.open(filename)) { - cerr << "Error: can't open input file '"; - cerr << filename << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {filename}, true); } } @@ -83,9 +83,7 @@ UFILE* open_output(const char* filename) { UFILE* output = u_fopen(filename, "w", NULL, NULL); if(!output) { - cerr << "Error: can't open output file '"; - cerr << filename << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {filename}, true); } return output; } diff --git a/apertium/caps_compiler.cc b/apertium/caps_compiler.cc index 628688d..83d7dfa 100644 --- a/apertium/caps_compiler.cc +++ b/apertium/caps_compiler.cc @@ -175,10 +175,12 @@ CapsCompiler::compile_match(xmlNode* node, int32_t state) UString select = getattr(node, CAPS_COMPILER_SELECT_ATTR); if (lemma != "*"_u && tlcaps != "*"_u) { - error_and_die(node, "Attribute lemma conflicts with attribute trglem"); + I18n(APER_I18N_DATA, "apertium").error("APER1029", {"file_name", "line_number"}, + {(char*)node->doc->URL, node->line}, true); } if (surf != "*"_u && tscaps != "*"_u) { - error_and_die(node, "Attribute surface conflicts with attribute trgsurf"); + I18n(APER_I18N_DATA, "apertium").error("APER1030", {"file_name", "line_number"}, + {(char*)node->doc->URL, node->line}, true); } state = compile_caps_specifier(sscaps, state); @@ -238,7 +240,8 @@ CapsCompiler::compile_match(xmlNode* node, int32_t state) } else if (select == CAPS_COMPILER_DIX_VAL) { state = trans.insertSingleTransduction(dix_sym, state); } else { - error_and_die(node, "Unknown select value '%S'", select.c_str()); + I18n(APER_I18N_DATA, "apertium").error("APER1031", {"file_name", "line_number", "select"}, + {(char*)node->doc->URL, node->line, (char*)select.c_str()}, true); } return state; @@ -265,9 +268,11 @@ CapsCompiler::compile_repeat(xmlNode* node, int32_t start_state) int from = StringUtils::stoi(xfrom); int upto = StringUtils::stoi(xupto); if(from < 0 || upto < 0) { - error_and_die(node, "Number of repetitions cannot be negative."); + I18n(APER_I18N_DATA, "apertium").error("APER1032", {"file_name", "line_number"}, + {(char*)node->doc->URL, node->line}, true); } else if(from > upto) { - error_and_die(node, "Lower bound on number of repetitions cannot be larger than upper bound."); + I18n(APER_I18N_DATA, "apertium").error("APER1033", {"file_name", "line_number"}, + {(char*)node->doc->URL, node->line}, true); } int count = upto - from; Transducer temp = trans; diff --git a/apertium/deformat-header.sh b/apertium/deformat-header.sh index 3ba3904..6f69e32 100644 --- a/apertium/deformat-header.sh +++ b/apertium/deformat-header.sh @@ -1,17 +1,11 @@ if [ $# != 2 ] then if [ $# != 3 ] - then echo "USAGE: $(basename "$0") -[aAmM] "; - echo " -a: apertium standard mode"; - echo " -A: apertium optimized mode (default mode)"; - echo " -m: matxin standard mode"; - echo " -M: matxin optimized mode"; + then icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" \ + "deformat_desc" "first_line" "$(basename "$0") -[aAmM] " exit 1; elif [ "$1" != "-a" ] && [ "$1" != "-A" ] && [ "$1" != "-m" ] && [ "$1" != "-M" ] - then echo "USAGE: $(basename "$0") -[AaMm] "; - echo " -a: apertium standard mode"; - echo " -A: apertium optimized mode (default mode)"; - echo " -m: matxin standard mode"; - echo " -M: matxin optimized mode"; + then icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" \ + "deformat_desc" "first_line" "$(basename "$0") -[AaMm] " exit 1; fi fi @@ -22,7 +16,7 @@ FILE2=$2; if [ $# = 2 ] then if [ ! -e "$1" ] - then echo "ERROR: '$1' file not found"; + then icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$1"; exit 1; fi fi @@ -31,7 +25,7 @@ MODE="apertium" # default mode if [ $# = 3 ] then if [ ! -e "$2" ] - then echo "ERROR: '$2' file not found"; + then echo icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$2"; exit 1; fi diff --git a/apertium/exception.h b/apertium/exception.h index 3b97a76..9f55d30 100644 --- a/apertium/exception.h +++ b/apertium/exception.h @@ -29,6 +29,7 @@ namespace Exception { EXCEPTION_TYPE(const std::stringstream &what_) : ExceptionType(what_) {} \ EXCEPTION_TYPE(const UChar *const what_) : ExceptionType(what_) {} \ EXCEPTION_TYPE(const UString &what_) : ExceptionType(what_) {} \ + EXCEPTION_TYPE(const icu::UnicodeString &what_) : ExceptionType(what_) {} \ ~EXCEPTION_TYPE() throw() {} \ }; diff --git a/apertium/exception_type.cc b/apertium/exception_type.cc index f4fef68..80301ca 100644 --- a/apertium/exception_type.cc +++ b/apertium/exception_type.cc @@ -25,18 +25,21 @@ std::string res; namespace Apertium { ExceptionType::ExceptionType(const char *const what_) - : what_(to_ustring(what_)) {} + : what_(to_ustring(what_).data()) {} ExceptionType::ExceptionType(const std::string &what_) - : what_(to_ustring(what_.c_str())) {} + : what_(to_ustring(what_.c_str()).data()) {} ExceptionType::ExceptionType(const std::stringstream &what_) - : what_(to_ustring(what_.str().c_str())) {} + : what_(to_ustring(what_.str().c_str()).data()) {} ExceptionType::ExceptionType(const UChar *const what_) : what_(what_) {} ExceptionType::ExceptionType(const UString &what_) + : what_(what_.data()) {} + +ExceptionType::ExceptionType(const icu::UnicodeString &what_) : what_(what_) {} ExceptionType::~ExceptionType() throw() {} @@ -44,7 +47,7 @@ ExceptionType::~ExceptionType() throw() {} const char *ExceptionType::what() const throw() { res.clear(); - utf8::utf16to8(what_.begin(), what_.end(), std::back_inserter(res)); + what_.toUTF8String(res); return res.c_str(); } } diff --git a/apertium/exception_type.h b/apertium/exception_type.h index 9ee46ac..88ade99 100644 --- a/apertium/exception_type.h +++ b/apertium/exception_type.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include namespace Apertium { class ExceptionType : public std::exception { @@ -29,11 +31,12 @@ public: ExceptionType(const std::stringstream &what_); ExceptionType(const UChar *wchar_t_what_); ExceptionType(const UString &wchar_t_what_); + ExceptionType(const icu::UnicodeString &wchar_t_what_); virtual ~ExceptionType() throw() = 0; const char *what() const throw(); protected: - UString what_; + icu::UnicodeString what_; }; } diff --git a/apertium/file_morpho_stream.cc b/apertium/file_morpho_stream.cc index b823688..b8cbce1 100644 --- a/apertium/file_morpho_stream.cc +++ b/apertium/file_morpho_stream.cc @@ -24,6 +24,7 @@ #include #include "apertium_config.h" #include +#include FileMorphoStream::FileMorphoStream(const char* ftxt, bool d, TaggerData *t) : ms() { @@ -223,8 +224,9 @@ FileMorphoStream::lrlmClassify(UString const &str, int &ivwords) { if (debug) { - cerr<<"Warning: There is not coarse tag for the fine tag '"<< str.substr(floor) <<"' of '" << str << "'\n"; - cerr<<" This is because of an incomplete tagset definition or a dictionary error\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1034", {"substr", "str"}, + {icu::UnicodeString(str.substr(floor).data()), + icu::UnicodeString(str.data())}, false); } vwords[ivwords]->add_tag(ca_tag_kundef, str.substr(floor) , td->getPreferRules()); return; @@ -255,8 +257,9 @@ FileMorphoStream::lrlmClassify(UString const &str, int &ivwords) { if (debug) { - cerr<<"Warning: There is not coarse tag for the fine tag '"<< str.substr(floor) <<"' of '" << str << "'\n"; - cerr<<" This is because of an incomplete tagset definition or a dictionary error\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1034", {"substr", "str"}, + {icu::UnicodeString(str.substr(floor).data()), + icu::UnicodeString(str.data())}, false); } vwords[ivwords]->add_tag(ca_tag_kundef, str.substr(floor) , td->getPreferRules()); return; @@ -271,8 +274,9 @@ FileMorphoStream::lrlmClassify(UString const &str, int &ivwords) val = ca_tag_kundef; if (debug) { - cerr<<"Warning: There is not coarse tag for the fine tag '"<< str.substr(floor) <<"' of '" << str << "'\n"; - cerr<<" This is because of an incomplete tagset definition or a dictionary error\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1034", {"substr", "str"}, + {icu::UnicodeString(str.substr(floor).data()), + icu::UnicodeString(str.data())}, false); } if(ivwords > initial_iv) { // We've partially added a multiword -- undo the previous add to avoid outputting a partial (chopped off) lexical form: @@ -305,9 +309,9 @@ FileMorphoStream::readRestOfWord(int &ivwords) if(str.size() > 0) { vwords[ivwords]->add_ignored_string(str); - cerr<<"Warning (internal): kIGNORE was returned while reading a word\n"; - cerr<<"Word being read: "<get_superficial_form()<<"\n"; - cerr<<"Debug: "<< str <<"\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1035", {"word", "str"}, + {icu::UnicodeString(vwords[ivwords]->get_superficial_form().data()), + icu::UnicodeString(str.data())}, false); } vwords[ivwords]->add_tag(ca_tag_keof, ""_u, td->getPreferRules()); return; @@ -347,9 +351,9 @@ FileMorphoStream::readRestOfWord(int &ivwords) if(str.size() > 0) { vwords[ivwords]->add_ignored_string(str); - cerr<<"Warning (internal): kIGNORE was returned while reading a word\n"; - cerr<<"Word being read: "<get_superficial_form()<<"\n"; - cerr<<"Debug: "<< str <<"\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1035", {"word", "str"}, + {icu::UnicodeString(vwords[ivwords]->get_superficial_form().data()), + icu::UnicodeString(str.data())}, false); } vwords[ivwords]->add_tag(ca_tag_keof, ""_u, td->getPreferRules()); return; diff --git a/apertium/gen-header.sh b/apertium/gen-header.sh index b9a4092..692c80d 100644 --- a/apertium/gen-header.sh +++ b/apertium/gen-header.sh @@ -14,14 +14,14 @@ FILE2=$2; if [ $# = 2 ] then if [ ! -e "$1" ] - then echo "ERROR: '$1' file not found"; + then echo icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$1"; exit 1; fi fi if [ $# = 3 ] then if [ ! -e "$2" ] - then echo "ERROR: '$2' file not found"; + then echo icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$2"; exit 1; fi FLEXOPTS="-Cfer"; diff --git a/apertium/gen_modes.cc b/apertium/gen_modes.cc index 450936c..4c3df2c 100644 --- a/apertium/gen_modes.cc +++ b/apertium/gen_modes.cc @@ -28,6 +28,7 @@ #include #include #include +#include using namespace std; @@ -222,7 +223,9 @@ void gen_debug_modes(map& modes) set_trace_opt(debug); modes[debug.name] = debug; } else { - cerr << "Debug mode name " << debug.name << " generated multiple times, disregarding result from " << mode_name << " step " << (i+1) << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1036", {"debug_name", "mode_name", "step_num"}, + {debug.name.c_str(), mode_name.c_str(), + to_string(i+1).c_str()}, false); continue; } @@ -255,8 +258,7 @@ void gen_mode(pipeline& mode, fs::path& file_dir, fs::path& write_dir) ofstream f(modefile, std::ios::binary); if (!f) { - cerr << "ERROR: Could not write to " << modefile << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {modefile.c_str()}, true); } for (size_t i = 0; i < mode.steps.size(); ++i) { @@ -297,12 +299,13 @@ void gen_modes(map& modes, fs::path& install_dir, fs::path& de int main(int argc, char* argv[]) { + I18n i18n {APER_I18N_DATA, "apertium"}; LtLocale::tryToSetLocale(); - CLI cli("Generate mode command files from XML"); - cli.add_bool_arg('f', "full", "expect absolute installation path"); - cli.add_bool_arg('l', "local", "output to current directory rather than directory of modes.xml"); - cli.add_bool_arg('v', "verbose", "print more detailed messages"); - cli.add_bool_arg('h', "help", "print this message and exit"); + CLI cli(i18n.format("gen_modes_desc")); + cli.add_bool_arg('f', "full", i18n.format("full_desc")); + cli.add_bool_arg('l', "local", i18n.format("local_desc")); + cli.add_bool_arg('v', "verbose", i18n.format("verbose_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.add_file_arg("modes.xml", false); cli.add_file_arg("install_path", true); cli.parse_args(argc, argv); @@ -319,8 +322,7 @@ int main(int argc, char* argv[]) if (!output_path.empty()) { install_dir = output_path; if (install_dir == dev_dir) { - cerr << basename(argv[0]) << " ERROR: Installation prefix is the same directory as modes.xml; give a different INSTALLDIR." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1037", {"program"}, {basename(argv[0])}, true); } } } diff --git a/apertium/hmm.cc b/apertium/hmm.cc index 3dd9414..4d07919 100644 --- a/apertium/hmm.cc +++ b/apertium/hmm.cc @@ -32,6 +32,8 @@ #include #include #include +#include +#include inline bool p_isnan(double v) { #if __cplusplus >= 201103L @@ -295,11 +297,10 @@ HMM::init_probabilities_from_tagged_text(MorphoStream &stream_tagged, cerr<<" -- "<<*word_untagged<<"\n"; if (word_tagged->get_superficial_form()!=word_untagged->get_superficial_form()) { - cerr<<"\nTagged text (.tagged) and analyzed text (.untagged) streams are not aligned.\n"; - cerr<<"Take a look at tagged text (.tagged).\n"; - cerr<<"Perhaps this is caused by a multiword unit that is not a multiword unit in one of the two files.\n"; - cerr<<*word_tagged<<" -- "<<*word_untagged<<"\n"; - exit(1); + cerr << "\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1038", {"word_tagged", "word_untagged"}, + {icu::UnicodeString(word_tagged->get_superficial_form().data()), + icu::UnicodeString(word_untagged->get_superficial_form().data())}, true); } if (++nw%100==0) cerr<<'.'<get_tags().size()==0) // Unknown word tag1 = -1; else if (word_tagged->get_tags().size()>1) // Ambiguous word - cerr<<"Error in tagged text. An ambiguous word was found: "<get_superficial_form()<<"\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1040", {"word"}, + {icu::UnicodeString(word_tagged->get_superficial_form().data())}, false); else tag1 = *(word_tagged->get_tags()).begin(); @@ -416,7 +417,8 @@ void HMM::post_ambg_class_scan() { int N = (tdhmm.getTagIndex()).size(); int M = (tdhmm.getOutput()).size(); - cerr << N << " states and " << M <<" ambiguity classes\n"; + cerr << I18n(APER_I18N_DATA, "apertium").format("num_of_states_and_ambiguity_classes", + {"states", "classes"}, {N, M}) << endl; tdhmm.setProbabilities(N, M); } @@ -573,10 +575,9 @@ HMM::train(MorphoStream &morpho_stream) { } if ((pending.size()>1) || ((tag!=eos)&&(tag != (tdhmm.getTagIndex())["TAG_kEOF"_u]))) { - cerr << "Warning: The last tag is not the end-of-sentence-tag " - << "but rather " << tdhmm.getArrayTags()[tag] << ". Line: " << nw - << ". Pending: " << pending.size() << ". Tags: "; - cerr << "\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1041", {"tag", "line", "pending"}, + {icu::UnicodeString(tdhmm.getArrayTags()[tag].data()), + nw, to_string(pending.size()).c_str()}, false); } int N = tdhmm.getN(); @@ -597,7 +598,7 @@ HMM::train(MorphoStream &morpho_stream) { j = jt->first; if (xsi[i][j]>0) { if (gamma[i]==0) { - cerr<<"Warning: gamma["<get_superficial_form()<<"' "<get_string_tags()<<"\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1043", {"word", "tags"}, + {icu::UnicodeString(word->get_superficial_form().data()), + icu::UnicodeString(word->get_string_tags().data())}, false); } for (unsigned t=0; t1)&&(TheFlags.getDebug())) { - cerr << "Error: The text to disambiguate has finished, but there are ambiguous words that has not been disambiguated.\n"; - cerr << "This message should never appears. If you are reading this ..... these are very bad news.\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1043", {}, {}, false); } } diff --git a/apertium/i.cc b/apertium/i.cc index 2affc5c..8e79fd6 100644 --- a/apertium/i.cc +++ b/apertium/i.cc @@ -16,6 +16,8 @@ #include "i.h" #include "exception.h" +#include +#include namespace Apertium { bool operator==(const i &a_, const i &b_) { return a_.TheTags == b_.TheTags; } @@ -26,22 +28,17 @@ i::i() {} i::i(const Analysis &Analysis_) : TheTags() { if (Analysis_.TheMorphemes.empty()) - throw Exception::Analysis::TheMorphemes_empty("can't convert const " - "Analysis & comprising empty " - "Morpheme std::vector to i"); + throw Exception::Analysis::TheMorphemes_empty(I18n(APER_I18N_DATA, "apertium").format("APER1013", {"letter"}, {"i"})); if (Analysis_.TheMorphemes.front().TheTags.empty()) - throw Exception::Morpheme::TheTags_empty("can't convert const Analysis & " - "comprising Morpheme comprising " - "empty Tag std::vector to i"); + throw Exception::Morpheme::TheTags_empty(I18n(APER_I18N_DATA, "apertium").format("APER1046", {"letter"}, {"i"})); TheTags = Analysis_.TheMorphemes.front().TheTags; } i::i(const Morpheme &Morpheme_) : TheTags() { if (Morpheme_.TheTags.empty()) - throw Exception::Morpheme::TheTags_empty( - "can't convert const Morpheme & comprising empty Tag std::vector to i"); + throw Exception::Morpheme::TheTags_empty(I18n(APER_I18N_DATA, "apertium").format("APER1045", {"letter"}, {"i"})); TheTags = Morpheme_.TheTags; } diff --git a/apertium/interchunk.cc b/apertium/interchunk.cc index a80897d..90820bd 100644 --- a/apertium/interchunk.cc +++ b/apertium/interchunk.cc @@ -20,6 +20,7 @@ #include #include +#include using namespace std; @@ -31,16 +32,19 @@ Interchunk::checkIndex(xmlNode *element, int index, int limit) { if(index >= limit) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": index >= limit" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1047", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } if(index < 0) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": index < 0" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1048", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } if(word[index] == 0) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": Null access at word[index]" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1049", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } return true; @@ -129,23 +133,20 @@ Interchunk::processBlank(xmlNode* element) void Interchunk::processLuCount(xmlNode* element) { - cerr << "Error: unexpected expression: '" << element->name << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1050", {"expression"}, {(char*)element->name}, true); } UString Interchunk::processLu(xmlNode* element) { - cerr << "Error: unexpected expression: '" << element->name << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1050", {"expression"}, {(char*)element->name}, true); return ""_u; // make the type checker happy } UString Interchunk::processMlu(xmlNode* element) { - cerr << "Error: unexpected expression: '" << element->name << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1050", {"expression"}, {(char*)element->name}, true); return ""_u; // make the type checker happy } @@ -223,7 +224,7 @@ Interchunk::processLet(xmlNode *localroot) bool match = word[ti.getPos()]->setChunkPart(attr_items[ti.getContent()], evalString(rightSide)); if(!match && trace) { - cerr << "apertium-interchunk warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1053", {"line", "tag"}, {localroot->line, ""}, false); } } return; @@ -260,7 +261,7 @@ Interchunk::processLet(xmlNode *localroot) evalString(rightSide)); if(!match && trace) { - cerr << "apertium-interchunk warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1053", {"line", "tag"}, {localroot->line, ""}, false); } evalStringCache[leftSide] = TransferInstr(ti_clip_tl, part, @@ -305,7 +306,7 @@ Interchunk::processModifyCase(xmlNode *localroot) bool match = word[pos]->setChunkPart(attr_items[part], result); if(!match && trace) { - cerr << "apertium-interchunk warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1052", {"tag", "line"}, {"", localroot->line}, false); } } else if(!xmlStrcmp(leftSide->name, (const xmlChar *) "var")) @@ -530,7 +531,10 @@ Interchunk::interchunk(InputFile& in, UFILE* out) if(trace) { - cerr << endl << "apertium-interchunk: Rule " << val << " line " << lastrule_line; + + cerr << endl + << I18n(APER_I18N_DATA, "apertium").format("interchunk_rule_line", {"value", "line"}, + {val, to_string(lastrule_line).c_str()}); for (auto& it : tmpword) { cerr << " " << *it; } @@ -565,7 +569,7 @@ Interchunk::interchunk(InputFile& in, UFILE* out) break; default: - cerr << "Error: Unknown input token." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1051", {}, {}, false); return; } } diff --git a/apertium/lemma.cc b/apertium/lemma.cc index 629870c..22a4a1a 100644 --- a/apertium/lemma.cc +++ b/apertium/lemma.cc @@ -16,6 +16,7 @@ #include "lemma.h" #include "exception.h" +#include namespace Apertium { bool operator==(const Lemma &a_, const Lemma &b_) { @@ -31,22 +32,18 @@ Lemma::Lemma() : TheLemma() {} Lemma::Lemma(const Analysis &Analysis_) : TheLemma() { if (Analysis_.TheMorphemes.empty()) throw Exception::Analysis::TheMorphemes_empty( - "can't convert const Analysis & comprising empty Morpheme std::vector " - "to Lemma"); + I18n(APER_I18N_DATA, "apertium").format("APER1013", {"letter"}, {"Lemma"})); if (Analysis_.TheMorphemes.front().TheLemma.empty()) throw Exception::Morpheme::TheLemma_empty( - "can't convert const Analysis & comprising Morpheme comprising empty " - "Lemma UString to Lemma"); + I18n(APER_I18N_DATA, "apertium").format("APER1054")); TheLemma = Analysis_.TheMorphemes.front().TheLemma; } Lemma::Lemma(const Morpheme &Morpheme_) : TheLemma() { if (Morpheme_.TheLemma.empty()) - throw Exception::Morpheme::TheLemma_empty("can't convert const Morpheme & " - "comprising empty Lemma " - "UString to Lemma"); + throw Exception::Morpheme::TheLemma_empty(I18n(APER_I18N_DATA, "apertium").format("APER1055")); TheLemma = Morpheme_.TheLemma; } diff --git a/apertium/morpheme.cc b/apertium/morpheme.cc index 7a78c36..0c5f51e 100644 --- a/apertium/morpheme.cc +++ b/apertium/morpheme.cc @@ -16,6 +16,7 @@ #include "morpheme.h" #include "exception.h" +#include namespace Apertium { bool operator==(const Morpheme &a, const Morpheme &b) { @@ -42,14 +43,10 @@ std::ostream& operator<<(std::ostream& out, const Morpheme &morph) { Morpheme::operator UString() const { if (TheTags.empty()) - throw Exception::Morpheme::TheTags_empty("can't convert Morpheme " - "comprising empty Tag std::vector " - "to UString"); + throw Exception::Morpheme::TheTags_empty(I18n(APER_I18N_DATA, "apertium").format("APER1056")); if (TheLemma.empty()) - throw Exception::Morpheme::TheLemma_empty("can't convert Morpheme " - "comprising empty TheLemma " - "UString to UString"); + throw Exception::Morpheme::TheLemma_empty(I18n(APER_I18N_DATA, "apertium").format("APER1057")); UString ustring_ = TheLemma; @@ -70,39 +67,39 @@ Morpheme::read(InputFile& in) TheLemma += c; if (c == '\\') { if (in.eof() || in.peek() == '\0') { - throw Exception::Stream::UnexpectedEndOfFile("Unterminted lexical unit"); + throw Exception::Stream::UnexpectedEndOfFile(I18n(APER_I18N_DATA, "apertium").format("APER1058")); } TheLemma += in.get(); } c = in.get(); } if (TheLemma.empty()) { - throw Exception::Morpheme::TheLemma_empty("empty lemma"); + throw Exception::Morpheme::TheLemma_empty(I18n(APER_I18N_DATA, "apertium").format("APER1059")); } while (c == '<') { UString tg = in.readBlock('<', '>'); if (tg.size() == 2) { - throw Exception::Morpheme::TheTags_empty("invalid tag <>"); + throw Exception::Morpheme::TheTags_empty(I18n(APER_I18N_DATA, "apertium").format("APER1060")); } TheTags.push_back(tg.substr(1, tg.size()-2)); c = in.get(); } if (TheTags.empty()) { - throw Exception::Morpheme::TheTags_empty("morpheme has no tags"); + throw Exception::Morpheme::TheTags_empty(I18n(APER_I18N_DATA, "apertium").format("APER1061")); } if (c == '#') { while (c != '<' && c != '$' && c != '/' && c != '\0' && c != '+') { TheLemma += c; if (c == '\\') { if (in.eof() || in.peek() == '\0') { - throw Exception::Stream::UnexpectedEndOfFile("trailing backslash"); + throw Exception::Stream::UnexpectedEndOfFile(I18n(APER_I18N_DATA, "apertium").format("APER1062")); } TheLemma += in.get(); } c = in.get(); } if (c == '<') { - throw Exception::Stream::UnexpectedCharacter("unexpected < after lemma queue"); + throw Exception::Stream::UnexpectedCharacter(I18n(APER_I18N_DATA, "apertium").format("APER1063")); } } in.unget(c); diff --git a/apertium/mtx_reader.cc b/apertium/mtx_reader.cc index ea7e597..8c0a763 100644 --- a/apertium/mtx_reader.cc +++ b/apertium/mtx_reader.cc @@ -26,6 +26,7 @@ #include #include #include +#include // XML parsing function guideline // When control is pass to you, you might need to stepToTag @@ -112,7 +113,8 @@ void MTXReader::procSetDef() std::string str = attrib_str("str"_u); vm_set.insert(tag.empty() ? str : tag); } else { - parseError("Expected set-member"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1064", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), xmlTextReaderGetParserColumnNumber(reader)}, true); } stepToNextTag(); } @@ -245,7 +247,8 @@ MTXReader::procIntExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected an integer expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1065", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), xmlTextReaderGetParserColumnNumber(reader)}, true); } } return true; @@ -273,7 +276,8 @@ MTXReader::procStrArrExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected a string list expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1066", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), xmlTextReaderGetParserColumnNumber(reader)}, true); } stepToNextTag(); } @@ -333,7 +337,9 @@ bool MTXReader::tryProcArg(ExprType expr_type, bool allow_fail) return true; } if (!allow_fail) { - parseError("No such argument " + var_name); + I18n(APER_I18N_DATA, "apertium").error("APER1067", {"line", "column", "var"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), var_name.c_str()}, true); } } } @@ -348,7 +354,9 @@ bool MTXReader::tryProcVar(VM::StackValueType svt) VarNVMap::const_iterator slot_names_it = slot_names.find(var_name); if (slot_names_it != slot_names.end()) { if (slot_types[slot_names_it->second] != svt) { - parseError("Variable " + var_name + " has the wrong type"); + I18n(APER_I18N_DATA, "apertium").error("APER1068", {"line", "column", "var"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), var_name.c_str()}, true); } emitOpcode(VM::GETVAR); emitUInt(slot_names_it->second); @@ -356,17 +364,23 @@ bool MTXReader::tryProcVar(VM::StackValueType svt) return true; } - parseError("Variable " + var_name + " has not been set."); + I18n(APER_I18N_DATA, "apertium").error("APER1069", {"line", "column", "var"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), var_name.c_str()}, true); } else if (!in_global_defn && name == "macro"_u) { // Get template data std::string var_name = attrib_str("name"_u); VarNVMap::const_iterator template_name_it = template_slot_names.find(var_name); if (template_name_it == template_slot_names.end()) { - parseError("No such macro " + var_name); + I18n(APER_I18N_DATA, "apertium").error("APER1070", {"line", "column", "var"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), var_name.c_str()}, true); } size_t templ_idx = template_name_it->second; if (template_slot_types[templ_idx] != svt) { - parseError("Macro " + var_name + " returns the wrong type"); + I18n(APER_I18N_DATA, "apertium").error("APER1071", {"line", "column", "var"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), var_name.c_str()}, true); } std::pair &templ_defn = template_defns[templ_idx]; // Get arg values @@ -457,7 +471,9 @@ MTXReader::procStrExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected a string expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1072", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } assert(type == XML_READER_TYPE_END_ELEMENT); stepToNextTag(); @@ -558,7 +574,9 @@ MTXReader::procBoolExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected a boolean expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1078", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } } return true; @@ -600,7 +618,9 @@ MTXReader::procAddrExpr() emitOpcode(VM::CLAMPADDR); stepToNextTag(); } else { - parseError("Expected an address expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1073", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } } } @@ -622,7 +642,9 @@ MTXReader::procWordoidArrExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected a wordoid array expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1074", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } stepToNextTag(); } @@ -644,7 +666,9 @@ MTXReader::procWordoidExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected a wordoid expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1075", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } assert(type == XML_READER_TYPE_END_ELEMENT); stepToNextTag(); @@ -676,7 +700,9 @@ MTXReader::getConstRef( exists = true; VarNVMap::iterator sit = const_map.find(const_name); if (sit == const_map.end()) { - parseError("No "_u + what + " named "_u + to_ustring(const_name.c_str())); + I18n(APER_I18N_DATA, "apertium").error("APER1078", {"line", "column", "what", "name"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(what.data()), const_name.c_str()}, true); } return sit->second; } @@ -701,7 +727,9 @@ MTXReader::getSetRef() bool has_attr; size_t set_ref = getSetRef(has_attr); if (!has_attr) { - parseError("Set required"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1076", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } return set_ref; } @@ -718,7 +746,9 @@ MTXReader::getStrRef() bool has_attr; size_t str_ref = getStrRef(has_attr); if (!has_attr) { - parseError("String required"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1077", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } return str_ref; } @@ -750,7 +780,9 @@ MTXReader::getInt(const UString& attr_name) bool has_attr; int i = getInt(attr_name, has_attr); if (!has_attr) { - parseError("String required"); + I18n(APER_I18N_DATA, "apertium").error("APER1077", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } return i; } @@ -769,7 +801,9 @@ MTXReader::emitAttr( bool has_attr = false; GetT val = (this->*getter)(has_attr); if (!has_attr) { - parseError(what + " required"); + I18n(APER_I18N_DATA, "apertium").error("APER1079", {"line", "column", "what"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(what.data())}, true); } (this->*emitter)(val); } @@ -809,7 +843,9 @@ MTXReader::procInst() val = getInt(has_int_lit); int num_operands = has_set_ref + has_str_ref + has_int_lit; if (num_operands > 1) { - parseError("Opcodes can have at most one operand."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1080", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } else if (num_operands == 1) { if (has_int_lit) { emitInt(val); @@ -837,7 +873,9 @@ MTXReader::procOut() has_expr = true; } if (!has_expr) { - parseError("Expected a string, bool or int expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1081", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } stepToTag(); assert(name == "out"_u && type == XML_READER_TYPE_END_ELEMENT); @@ -968,7 +1006,9 @@ MTXReader::procForEach(ExprType expr_type) { std::string var_name = attrib_str("as"_u); if (var_name.empty()) { - parseError("'as' attribute required for for-each."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1082", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } size_t slot_idx = slot_counter++; slot_names[var_name] = slot_idx; @@ -983,7 +1023,9 @@ MTXReader::procForEach(ExprType expr_type) has_expr = true; } if (!has_expr) { - parseError("Expected a string array or wordoid array expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1083", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } emitOpcode(VM::FOREACHINIT); @@ -1035,7 +1077,9 @@ MTXReader::procVoidExpr(bool allow_fail) if (allow_fail) { return false; } - parseError("Expected a void expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1084", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } return true; } @@ -1051,7 +1095,9 @@ MTXReader::procDefMacro() std::string var_name = attrib_str("as"_u); if (var_name.empty()) { - parseError("'as' attribute required for def-macro."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1085", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } template_slot_names[var_name] = template_slot_counter; @@ -1095,7 +1141,9 @@ MTXReader::procDefMacro() has_expr = true; } if (!has_expr) { - parseError("Expected a non-void expression."_u); + I18n(APER_I18N_DATA, "apertium").error("APER1086", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } assert(name == "def-macro"_u && type == XML_READER_TYPE_END_ELEMENT); stepToNextTag(); @@ -1152,7 +1200,9 @@ MTXReader::parse() stepToNextTag(); } if (name != "metatag"_u) { - parseError("expected tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1087", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } stepToNextTag(); if (name == "coarse-tags"_u) { diff --git a/apertium/perceptron_spec.cc b/apertium/perceptron_spec.cc index e0050cc..972f639 100644 --- a/apertium/perceptron_spec.cc +++ b/apertium/perceptron_spec.cc @@ -5,7 +5,7 @@ #include #include #include - +#include namespace Apertium { @@ -737,9 +737,10 @@ PerceptronSpec::Machine::getValue() void PerceptronSpec::Machine::unimplemented_opcode(std::string opstr) { int bytecode_idx = bytecode_iter - feat.begin(); - std::stringstream msg; - msg << "Unimplemented opcode: " << opstr; - msg << " at " << (is_feature ? "feature" : "global") << " #" << feat_idx << " address #" << bytecode_idx; + icu::UnicodeString msg = I18n(APER_I18N_DATA, "apertium").format("APER1088", + {"opstr", "feature", "feat_idx", "bytecode_idx"}, + {opstr.c_str(), (is_feature ? "feature" : "global"), + to_string(feat_idx).c_str(), to_string(bytecode_idx).c_str()}); throw Apertium::Exception::apertium_tagger::UnimplementedOpcode(msg); } diff --git a/apertium/perceptron_tagger.cc b/apertium/perceptron_tagger.cc index 01f800a..b8e49c6 100644 --- a/apertium/perceptron_tagger.cc +++ b/apertium/perceptron_tagger.cc @@ -5,6 +5,7 @@ #include #include #include +#include namespace Apertium { @@ -183,14 +184,13 @@ bool PerceptronTagger::trainSentence( return true; } else { std::stringstream what_; - what_ << "Tagged analysis unavailable in untagged/ambigous input.\n"; - what_ << "Available:\n"; for (analys_it = analyses.begin(); analys_it != analyses.end(); analys_it++) { what_ << *analys_it << "\n"; } - what_ << "Required: " << *tagged_tok << "\n"; - what_ << "Rerun with --skip-on-error to skip this sentence."; - throw Apertium::Exception::PerceptronTagger::CorrectAnalysisUnavailable(what_); + icu::UnicodeString msg = I18n(APER_I18N_DATA, "apertium").format("APER1089", + {"available", "required"}, {what_.str().c_str(), + icu::UnicodeString(static_cast(*tagged_tok).data())}); + throw Apertium::Exception::PerceptronTagger::CorrectAnalysisUnavailable(msg); } } // Apply the beam @@ -259,10 +259,10 @@ void PerceptronTagger::train( } avg_weights.average(); if (avail_skipped) { - std::cerr << "Skipped " << tc.skipped << " sentences due to token " - << "misalignment and " << avail_skipped << " sentences due to " - << "tagged token being unavailable in untagged file out of " - << tc.sentences.size() << " total sentences.\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1090", + {"skipped", "avail_skipped", "total"}, + {to_string(tc.skipped).c_str(), to_string(avail_skipped).c_str(), + to_string(tc.sentences.size()).c_str()}, false); } //std::cerr << *this; } diff --git a/apertium/postchunk.cc b/apertium/postchunk.cc index 3389d2e..ccb6080 100644 --- a/apertium/postchunk.cc +++ b/apertium/postchunk.cc @@ -18,6 +18,7 @@ #include #include +#include #include @@ -31,16 +32,20 @@ Postchunk::checkIndex(xmlNode *element, int index, int limit) { if(index > limit) // Note: Unlike transfer/interchunk, we allow index==limit! { + I18n(APER_I18N_DATA, "apertium").error("APER1091", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": index > limit" << endl; return false; } if(index < 0) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": index < 0" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1048", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } if(word[index] == 0) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": Null access at word[index]" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1049", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } return true; @@ -224,8 +229,7 @@ Postchunk::processMlu(xmlNode* element) UString Postchunk::processChunk(xmlNode* element) { - cerr << "Error: unexpected expression: '" << element->name << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1050", {"expression"}, {(char*)element->name}, true); return ""_u; // make the type checker happy } @@ -294,7 +298,8 @@ Postchunk::processLet(xmlNode *localroot) bool match = word[ti.getPos()]->setChunkPart(attr_items[ti.getContent()], evalString(rightSide)); if(!match && trace) { - cerr << "apertium-postchunk warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1092", {"tag", "line"}, + {"", localroot->line}, false); } } return; @@ -339,7 +344,8 @@ Postchunk::processLet(xmlNode *localroot) evalString(rightSide)); if(!match && trace) { - cerr << "apertium-postchunk warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1092", {"tag", "line"}, + {"", localroot->line}, false); } evalStringCache[leftSide] = TransferInstr(ti_clip_tl, part, pos, NULL); } @@ -383,7 +389,8 @@ Postchunk::processModifyCase(xmlNode *localroot) if(!match && trace) { - cerr << "apertium-postchunk warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1092", {"tag", "line"}, + {"", localroot->line}, false); } } else if(!xmlStrcmp(leftSide->name, (const xmlChar *) "var")) @@ -412,7 +419,7 @@ Postchunk::processCallMacro(xmlNode *localroot) if (npar <= 0) { - throw "Postchunk::processCallMacro() assumes npar > 0, but got npar <= 0"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1093"); } InterchunkWord **myword = NULL; @@ -444,7 +451,8 @@ Postchunk::processCallMacro(xmlNode *localroot) } } else { - cerr << "Warning: Not calling macro \"" << n << "\" from line " << localroot->line << " (empty word?)" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1094", {"macro", "line"}, + {icu::UnicodeString(n.data()), localroot->line}, false); } swap(myword, word); @@ -623,7 +631,9 @@ Postchunk::postchunk(InputFile& in, UFILE* out) if(trace) { - cerr << endl << "apertium-postchunk: Rule " << val << " line " << lastrule_line; + cerr << endl + << I18n(APER_I18N_DATA, "apertium").format("postchunk_rule_line", {"value", "line"}, + {val, to_string(lastrule_line).c_str()}); for (auto& it : tmpword) { cerr << " " << *it; } @@ -657,7 +667,7 @@ Postchunk::postchunk(InputFile& in, UFILE* out) break; default: - cerr << "Error: Unknown input token." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1051", {}, {}, false); return; } } diff --git a/apertium/pretransfer.cc b/apertium/pretransfer.cc index 5b5c76c..c1af8a9 100644 --- a/apertium/pretransfer.cc +++ b/apertium/pretransfer.cc @@ -7,6 +7,7 @@ #include #include +#include UString storeAndWriteWblank(InputFile& input, UFILE* output) { @@ -18,8 +19,7 @@ UString storeAndWriteWblank(InputFile& input, UFILE* output) mychar = input.get(); if(input.eof()) { - std::cerr << "ERROR: Unexpected EOF" << std::endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1095", {}, {}, true); } content += mychar; @@ -55,8 +55,7 @@ void readAndWriteUntil(InputFile& input, UFILE* output, int const charcode) { if(input.eof()) { - std::cerr << "ERROR: Unexpected EOF" << std::endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1095", {}, {}, true); } u_fputc(mychar, output); if(mychar == '\\') @@ -85,8 +84,7 @@ void procWord(InputFile& input, UFILE* output, bool surface_forms, bool compound { if(input.eof()) { - std::cerr << "ERROR: Unexpected EOF" << std::endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1095", {}, {}, true); } switch(mychar) @@ -180,8 +178,7 @@ void processStream(InputFile& input, UFILE* output, bool null_flush, bool surfac } else { - std::cerr << "ERROR: Wordbound blank isn't immediately followed by the Lexical Unit." << std::endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1096", {}, {}, true); } } else diff --git a/apertium/sentence_stream.cc b/apertium/sentence_stream.cc index 79b2798..895ac68 100644 --- a/apertium/sentence_stream.cc +++ b/apertium/sentence_stream.cc @@ -3,6 +3,7 @@ #include #include #include +#include namespace Apertium { namespace SentenceStream { @@ -111,14 +112,12 @@ TrainingCorpus::TrainingCorpus(Stream &tagged, Stream &untagged, //std::cerr << tagged_token.TheLexicalUnit->TheSurfaceForm << " || " << untagged_token.TheLexicalUnit->TheSurfaceForm << "\n"; if (untagged_token.TheLexicalUnit->TheSurfaceForm != tagged_token.TheLexicalUnit->TheSurfaceForm) { if (!skip_on_error) { - std::stringstream what_; - what_ << "Streams diverged at line " << tagged_line << "\n"; - what_ << "Untagged token: " - << untagged_token.TheLexicalUnit->TheSurfaceForm << "\n"; - what_ << "Tagged token: " - << tagged_token.TheLexicalUnit->TheSurfaceForm << "\n"; - what_ << "Rerun with --skip-on-error to skip this sentence."; - throw Exception::UnalignedStreams(what_); + icu::UnicodeString msg = I18n(APER_I18N_DATA, "apertium").format("APER1097", + {"tagged_line", "untagged_token", "tagged_token"}, + {std::to_string(tagged_line).c_str(), + icu::UnicodeString(untagged_token.TheLexicalUnit->TheSurfaceForm.data()), + icu::UnicodeString(tagged_token.TheLexicalUnit->TheSurfaceForm.data())}); + throw Exception::UnalignedStreams(msg); } skipped++; @@ -175,10 +174,7 @@ bool TrainingCorpus::contToEndOfSent(Stream &stream, StreamedType token, void TrainingCorpus::prematureEnd() { - std::stringstream what_; - what_ << "One stream has ended prematurely. " - << "Please check if they are aligned.\n"; - throw Exception::UnalignedStreams(what_); + throw Exception::UnalignedStreams(I18n(APER_I18N_DATA, "apertium").format("APER1098", {}, {})); } void TrainingCorpus::shuffle() diff --git a/apertium/shell_utils.cc b/apertium/shell_utils.cc index e9d040c..e7e2518 100644 --- a/apertium/shell_utils.cc +++ b/apertium/shell_utils.cc @@ -1,5 +1,6 @@ #include #include +#include #ifdef _MSC_VER #include @@ -12,7 +13,6 @@ namespace ShellUtils { void expect_file_arguments(int actual, int lower, int upper) { if (actual < lower || actual >= upper) { std::stringstream what_; - what_ << "expected "; for (int i=lower;i +#include namespace Apertium { Stream::Stream(TaggerFlags &Flags_) @@ -48,13 +49,13 @@ StreamedType Stream::get() { c = TheCharacterStream.get(); } if (c == '$') { - throw Exception::Analysis::TheMorphemes_empty("lexical unit has no analyses"); + throw Exception::Analysis::TheMorphemes_empty(I18n(APER_I18N_DATA, "apertium").format("APER1101")); } else if (TheStreamedType.TheLexicalUnit->TheSurfaceForm.empty()) { - throw Exception::Stream::UnexpectedCharacter("unexpected /, surface form is empty"); + throw Exception::Stream::UnexpectedCharacter(I18n(APER_I18N_DATA, "apertium").format("APER1102")); } c = TheCharacterStream.get(); if (c == '$') { - throw Exception::Analysis::TheMorphemes_empty("lexical unit has no analyses"); + throw Exception::Analysis::TheMorphemes_empty(I18n(APER_I18N_DATA, "apertium").format("APER1101")); } else if (c == '*') { TheCharacterStream.readBlock(c, '$'); } else { @@ -65,7 +66,7 @@ StreamedType Stream::get() { c = TheCharacterStream.get(); } while (c == '/'); if (c != '$') { - throw Exception::Stream::UnexpectedEndOfFile("unterminated lexical unit"); + throw Exception::Stream::UnexpectedEndOfFile(I18n(APER_I18N_DATA, "apertium").format("APER1103")); } } } diff --git a/apertium/tagger.cc b/apertium/tagger.cc index 8022c0f..04fb1fa 100644 --- a/apertium/tagger.cc +++ b/apertium/tagger.cc @@ -43,6 +43,7 @@ #include #include #include +#include namespace Apertium { using namespace ShellUtils; @@ -117,13 +118,8 @@ apertium_tagger::apertium_tagger(int &argc, char **&argv) } { - std::stringstream what_; - what_ << "invalid argument '" << optarg << "' for '--unigram'\n" - "Valid arguments are:\n" - " - '1'\n" - " - '2'\n" - " - '3'"; - throw Exception::apertium_tagger::InvalidArgument(what_); + throw Exception::apertium_tagger::InvalidArgument( + I18n(APER_I18N_DATA, "apertium").format("APER1107", {"optarg"}, {optarg})); } break; case 'w': @@ -213,9 +209,8 @@ apertium_tagger::apertium_tagger(int &argc, char **&argv) switch (*TheFunctionTypeType) { case Unigram: { - std::stringstream what_; - what_ << "invalid option -- 'u'"; - throw Exception::apertium_tagger::InvalidOption(what_); + throw Exception::apertium_tagger::InvalidOption( + I18n(APER_I18N_DATA, "apertium").format("APER1108", {"opt"}, {"u"})); } case SlidingWindow: { LSWPoST SlidingWindowTagger_(TheFlags); @@ -252,9 +247,8 @@ apertium_tagger::apertium_tagger(int &argc, char **&argv) s_StreamTaggerTrainer(UnigramTagger_); } break; case SlidingWindow: { - std::stringstream what_; - what_ << "invalid option -- 'w'"; - throw Exception::apertium_tagger::InvalidOption(what_); + throw Exception::apertium_tagger::InvalidOption( + I18n(APER_I18N_DATA, "apertium").format("APER1108", {"opt"}, {"w"})); } break; case Perceptron: { PerceptronTagger perceptron(TheFlags); @@ -274,9 +268,8 @@ apertium_tagger::apertium_tagger(int &argc, char **&argv) switch (*TheFunctionTypeType) { case Unigram: { - std::stringstream what_; - what_ << "invalid option -- 'u'"; - throw Exception::apertium_tagger::InvalidOption(what_); + throw Exception::apertium_tagger::InvalidOption( + I18n(APER_I18N_DATA, "apertium").format("APER1108", {"opt"}, {"u"})); } case SlidingWindow: { LSWPoST SlidingWindowTagger_(TheFlags); @@ -299,6 +292,7 @@ apertium_tagger::apertium_tagger(int &argc, char **&argv) apertium_tagger::~apertium_tagger() {} void apertium_tagger::help() { + I18n i18n {APER_I18N_DATA, "apertium"}; std::cerr << "Usage: apertium-tagger [OPTION]... -g SERIALISED_TAGGER \\\n" @@ -335,40 +329,54 @@ void apertium_tagger::help() { " TAGGER_SPECIFICATION \\\n" " SERIALISED_TAGGER\n" "\n" -"Mandatory arguments to long options are mandatory for short options too.\n" -"\n"; - - std::vector > options_description_; - options_description_.push_back(std::make_pair("-d, --debug", "with -g, print error messages about the input")); - options_description_.push_back(std::make_pair("-f, --first", "with -g, reorder each lexical unit's analyses so that the chosen one is first")); - options_description_.push_back(std::make_pair("-m, --mark", "with -g, mark disambiguated lexical units")); - options_description_.push_back(std::make_pair("-p, --show-superficial", "with -g, output each lexical unit's surface form")); - options_description_.push_back(std::make_pair("-z, --null-flush", "with -g, flush the output after getting each null character")); +<< i18n.format("tagger_cc_note") +<< "\n\n" +<< i18n.format("apertium_tagger_desc"); +/* + std::vector > options_description_; + options_description_.push_back(std::make_pair("-d, --debug", + i18n.format("tagger_debug_desc"))); + options_description_.push_back(std::make_pair("-f, --first", + i18n.format("tagger_first_desc"))); + options_description_.push_back(std::make_pair("-m, --mark", + i18n.format("tagger_mark_desc"))); + options_description_.push_back(std::make_pair("-p, --show-superficial", + i18n.format("tagger_show_superficial_desc"))); + options_description_.push_back(std::make_pair("-z, --null-flush", + i18n.format("tagger_null_flush_desc"))); align::align_(options_description_); std::cerr << '\n'; options_description_.clear(); - options_description_.push_back(std::make_pair("-u, --unigram=MODEL", "use unigram algorithm MODEL from ")); + options_description_.push_back(std::make_pair("-u, --unigram=MODEL", + i18n.format("tagger_unigram_desc"))); align::align_(options_description_); std::cerr << '\n'; options_description_.clear(); - options_description_.push_back(std::make_pair("-w, --sliding-window", "use the Light Sliding Window algorithm")); - options_description_.push_back(std::make_pair("-x, --perceptron", "use the averaged perceptron algorithm")); - options_description_.push_back(std::make_pair("-e, --skip-on-error", "with -xs, ignore certain types of errors with the training corpus")); + options_description_.push_back(std::make_pair("-w, --sliding-window", + i18n.format("tagger_sliding_window_desc"))); + options_description_.push_back(std::make_pair("-x, --perceptron", + i18n.format("perceptron_desc"))); + options_description_.push_back(std::make_pair("-e, --skip-on-error", + i18n.format("tagger_skip_on_error_desc"))); align::align_(options_description_); std::cerr << '\n'; options_description_.clear(); - options_description_.push_back(std::make_pair("-g, --tagger", "disambiguate the input")); + options_description_.push_back(std::make_pair("-g, --tagger", + i18n.format("tagger_desc"))); align::align_(options_description_); std::cerr << '\n'; options_description_.clear(); - options_description_.push_back(std::make_pair("-r, --retrain=ITERATIONS", "with -u: exit;\notherwise: retrain the tagger with ITERATIONS unsupervised iterations")); - options_description_.push_back(std::make_pair("-s, --supervised=ITERATIONS", "with -u: train the tagger with a hand-tagged corpus;\nwith -w: exit;\notherwise: initialise the tagger with a hand-tagged corpus and retrain it with ITERATIONS unsupervised iterations")); - options_description_.push_back(std::make_pair("-t, --train=ITERATIONS", "with -u: exit;\notherwise: train the tagger with ITERATIONS unsupervised iterations")); + options_description_.push_back(std::make_pair("-r, --retrain=ITERATIONS", + i18n.format("tagger_retrain_desc"))); + options_description_.push_back(std::make_pair("-s, --supervised=ITERATIONS", + i18n.format("tagger_supervised_desc"))); + options_description_.push_back(std::make_pair("-t, --train=ITERATIONS", + i18n.format("tagger_train_desc"))); align::align_(options_description_); std::cerr << '\n'; options_description_.clear(); - options_description_.push_back(std::make_pair("-h, --help", "display this help and exit")); - align::align_(options_description_); + options_description_.push_back(std::make_pair("-h, --help", i18n.format("help_desc"))); + align::align_(options_description_);*/ } const struct option apertium_tagger::longopts[] = { @@ -437,10 +445,9 @@ void apertium_tagger::flagOptionCase( bool (TaggerFlags::*GetFlag)(), void (TaggerFlags::*SetFlag)(const bool &)) { if ((TheFlags.*GetFlag)()) { - std::stringstream what_; - what_ << "unexpected '" << option_string() << "' following '" - << option_string() << '\''; - throw Exception::apertium_tagger::UnexpectedFlagOption(what_); + throw Exception::apertium_tagger::UnexpectedFlagOption( + I18n(APER_I18N_DATA, "apertium").format("APER1109", {"opt1", "opt2"}, + {option_string().c_str(), option_string().c_str()})); } (TheFlags.*SetFlag)(true); @@ -453,11 +460,9 @@ std::string apertium_tagger::option_string() { void apertium_tagger::functionTypeTypeOptionCase( const FunctionTypeType &FunctionTypeType_) { if (FunctionTypeTypeOption_indexptr) { - std::stringstream what_; - what_ << "unexpected '" << option_string() << "' following '" - << option_string(*FunctionTypeTypeOption_indexptr) - << '\''; - throw Exception::apertium_tagger::UnexpectedFunctionTypeTypeOption(what_); + throw Exception::apertium_tagger::UnexpectedFunctionTypeTypeOption( + I18n(APER_I18N_DATA, "apertium").format("APER1109", {"opt1", "opt2"}, + {option_string().c_str(), option_string(*FunctionTypeTypeOption_indexptr).c_str()})); } TheFunctionTypeType = FunctionTypeType_; @@ -467,11 +472,9 @@ void apertium_tagger::functionTypeTypeOptionCase( void apertium_tagger::functionTypeOptionCase( const FunctionType &FunctionType_) { if (FunctionTypeOption_indexptr) { - std::stringstream what_; - what_ << "unexpected '" << option_string() << "' following '" - << option_string(*FunctionTypeOption_indexptr) - << '\''; - throw Exception::apertium_tagger::UnexpectedFunctionTypeOption(what_); + throw Exception::apertium_tagger::UnexpectedFunctionTypeOption( + I18n(APER_I18N_DATA, "apertium").format("APER1109", {"opt1", "opt2"}, + {option_string().c_str(), option_string(*FunctionTypeOption_indexptr).c_str()})); } TheFunctionType = FunctionType_; @@ -482,10 +485,9 @@ void apertium_tagger::getIterationsArgument() { try { TheFunctionTypeOptionArgument = optarg_unsigned_long("ITERATIONS"); } catch (const ExceptionType &ExceptionType_) { - std::stringstream what_; - what_ << "invalid argument '" << optarg << "' for '" << option_string() - << '\''; - throw Exception::apertium_tagger::InvalidArgument(what_); + throw Exception::apertium_tagger::InvalidArgument( + I18n(APER_I18N_DATA, "apertium").format("APER1110", {"arg", "opt"}, + {optarg, option_string().c_str()})); } } @@ -495,22 +497,18 @@ static unsigned long parse_unsigned_long(const char *metavar, const char *val) { unsigned long N_0 = std::strtoul(val, &str_end, 10); if (*str_end != '\0') { - std::stringstream what_; - what_ << "can't convert " << metavar << " \"" << val << "\" to unsigned long"; - throw Exception::apertium_tagger::str_end_not_eq_NULL(what_); + throw Exception::apertium_tagger::str_end_not_eq_NULL( + I18n(APER_I18N_DATA, "apertium").format("APER1111", {"metavar", "val"}, {metavar, val})); } if (*val == '\0') { - std::stringstream what_; - what_ << "can't convert " << metavar << " of size 1 \"\" to unsigned long"; - throw Exception::apertium_tagger::optarg_eq_NULL(what_); + throw Exception::apertium_tagger::optarg_eq_NULL( + I18n(APER_I18N_DATA, "apertium").format("APER1112", {"metavar"}, {metavar})); } if (errno == ERANGE) { - std::stringstream what_; - what_ << "can't convert " << metavar << " \"" << val - << "\" to unsigned long, not in unsigned long range"; - throw Exception::apertium_tagger::ERANGE_(what_); + throw Exception::apertium_tagger::ERANGE_( + I18n(APER_I18N_DATA, "apertium").format("APER1113", {"metavar", "val"}, {metavar, val})); } return N_0; @@ -578,10 +576,9 @@ void apertium_tagger::g_StreamTagger(StreamTagger &StreamTagger_) { try { StreamTagger_.deserialise(SerialisedAnalysisFrequencies); } catch (const ExceptionType &ExceptionType_) { - std::stringstream what_; - what_ << "can't deserialise SERIALISED_TAGGER file \"" << argv[optind] - << "\" Reason: " << ExceptionType_.what(); - throw Exception::apertium_tagger::deserialise(what_); + throw Exception::apertium_tagger::deserialise( + I18n(APER_I18N_DATA, "apertium").format("APER1114", {"file", "what"}, + {argv[optind], ExceptionType_.what()})); } if (nonoptarg < 2) { @@ -608,10 +605,9 @@ void apertium_tagger::s_StreamTaggerTrainer( locale_global_(); if (TheFunctionTypeOptionArgument != 0 && *TheFunctionTypeType != Perceptron) { - std::stringstream what_; - what_ << "invalid argument '" << TheFunctionTypeOptionArgument - << "' for '--supervised'"; - throw Exception::apertium_tagger::InvalidArgument(what_); + throw Exception::apertium_tagger::InvalidArgument( + I18n(APER_I18N_DATA, "apertium").format("APER1110", {"arg", "opt"}, + {to_string(TheFunctionTypeOptionArgument).c_str(), "--supervised"})); } if (*TheFunctionTypeType == Perceptron) { diff --git a/apertium/tagger_utils.cc b/apertium/tagger_utils.cc index 3da0415..dc3def9 100644 --- a/apertium/tagger_utils.cc +++ b/apertium/tagger_utils.cc @@ -23,6 +23,7 @@ #include #include #include +#include void tagger_utils::fatal_error (UString const &s) { @@ -166,30 +167,25 @@ tagger_utils::find_similar_ambiguity_class(TaggerData &td, set &c) { void tagger_utils::require_ambiguity_class(TaggerData &td, set &tags, TaggerWord &word, int nw) { if (td.getOutput().has_not(tags)) { - UString errors; - errors = "A new ambiguity class was found. I cannot continue.\nWord '"_u; - errors += word.get_superficial_form(); - errors += "' not found in the dictionary.\n"_u; - errors += "New ambiguity class: "_u; - errors += word.get_string_tags(); - errors += '\n'; - if (nw >= 0) { - std::ostringstream ws; + std::ostringstream ws; + if (nw >= 0) ws << (nw + 1); - errors += "Line number: "_u; - errors += to_ustring(ws.str().c_str()); - errors += '\n'; - } - errors += "Take a look at the dictionary, then retrain."_u; - fatal_error(errors); + else + ws << "N/A"; + + I18n(APER_I18N_DATA, "apertium").error("APER1104", + {"word", "class", "line"}, + {icu::UnicodeString(word.get_superficial_form().data()), + icu::UnicodeString(word.get_string_tags().data()), + ws.str().c_str()}, true); } } static void _warn_absent_ambiguity_class(TaggerWord &word) { - cerr << "Error: A new ambiguity class was found. \n"; - cerr << "Retraining the tagger is necessary so as to take it into account.\n"; - cerr << "Word '" << word.get_superficial_form() << "'.\n"; - cerr << "New ambiguity class: " << word.get_string_tags() << "\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1104", + {"word", "class"}, + {icu::UnicodeString(word.get_superficial_form().data()), + icu::UnicodeString(word.get_string_tags().data())}, false); } set & @@ -236,7 +232,7 @@ istream& operator>> (istream& is, map & f) { is>>i; // warning: does not work if both is>>f[i]; // lines merged in a single one } - if (is.bad()) tagger_utils::fatal_error("reading map"_u); + if (is.bad()) I18n(APER_I18N_DATA, "apertium").error("APER1106", {}, {}, true); return is; } diff --git a/apertium/tmx_aligner_tool.cc b/apertium/tmx_aligner_tool.cc index 9dc7e7b..999bd89 100644 --- a/apertium/tmx_aligner_tool.cc +++ b/apertium/tmx_aligner_tool.cc @@ -11,6 +11,8 @@ *************************************************************************/ #include #include +#include +#include namespace TMXAligner { @@ -28,16 +30,16 @@ void readTrailOrBisentenceList( std::istream& is, Trail& trail ) is >> huPos; if (is.peek()!=' ') { - std::cerr << "no space in line" << std::endl; - throw "data error"; + I18n(APER_I18N_DATA, "apertium").error("APER1115", {}, {}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1122"); } is.ignore(); is >> enPos; if (is.peek()!='\n') { - std::cerr << "too much data in line" << std::endl; - throw "data error"; + I18n(APER_I18N_DATA, "apertium").error("APER1116", {}, {}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1122"); } is.ignore(); @@ -236,7 +238,7 @@ double alignerToolWithObjects( const DictionaryItems& dictionary, SentenceList huBisentences,enBisentences; - throw "unimplemented"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1123"); // std::cerr << "Plausible bisentences filtered." << std::endl; modelOne.build(huBisentences,enBisentences); @@ -474,69 +476,7 @@ void fillPercentParameter( Arguments& args, const std::string& argName, double& void main_alignerToolUsage() { - std::cerr << "Usage (either):\n\ - alignerTool [ common_arguments ] [ -hand=hand_align_file ] dictionary_file source_text target_text\n\ -\n\ -or:\n\ - alignerTool [ common_arguments ] -batch dictionary_file batch_file\n\ -\n\ -where\n\ -common_arguments ::= [ -text ] [ -bisent ] [ -utf ] [ -cautious ] [ -realign [ -autodict=filename ] ]\n\ - [ -thresh=n ] [ -ppthresh=n ] [ -headerthresh=n ] [ -topothresh=n ]\n\ -\n\ -Arguments:\n\ -\n\ --text\n\ - The output should be in text format, rather than the default (numeric) ladder format.\n\ -\n\ --bisent\n\ - Only bisentences (one-to-one alignment segments) are printed. In non-text mode, their\n\ - starting rung is printed.\n\ -\n\ --cautious\n\ - In -bisent mode, only bisentences for which both the preceding and the following\n\ - segments are one-to-one are printed. In the default non-bisent mode, only rungs\n\ - for which both the preceding and the following segments are one-to-one are printed.\n\ -\n\ --hand=file\n\ - When this argument is given, the precision and recall of the alignment is calculated\n\ - based on the manually built ladder file. Information like the following is written\n\ - on the standard error: \n\ - 53 misaligned out of 6446 correct items, 6035 bets.\n\ - Precision: 0.991218, Recall: 0.928017\n\ - \n\ - Note that by default, 'item' means rung. The switch -bisent also changes the semantics\n\ - of the scoring from rung-based to bisentence-based and in this case 'item' means bisentences.\n\ - See File formats about the format of this input align file.\n\ -\n\ --autodict=filename\n\ - The dictionary built during realign is saved to this file. By default, it is not saved.\n\ -\n\ --utf\n\ - The system uses the character counts of the sentences as information for the\n\ - pairing of sentences. By default, it assumes one-byte character encoding such\n\ - as ISO Latin-1 when calculating these counts. If our text is in UTF-8 format,\n\ - byte counts and character counts are different, and we must use the -utf switch\n\ - to force the system to properly calculate character counts.\n\ - Note: UTF-16 input is not supported.\n\ -\n\ -Postfiltering options:\n\ -There are various postprocessors which remove implausible rungs based on various heuristics.\n\ -\n\ --thresh=n\n\ - Don't print out segments with score lower than n/100.\n\ -\n\ --ppthresh=n\n\ - Filter rungs with less than n/100 average score in their vicinity.\n\ -\n\ --headerthresh=n\n\ - Filter all rungs at the start and end of texts until finding a reliably\n\ - plausible region.\n\ -\n\ --topothresh=n\n\ - Filter rungs with less than n percent of one-to-one segments in their vicinity.\n\ -\n\ -"; + std::cerr << I18n(APER_I18N_DATA, "apertium").format("tmx_aligner_tool_desc"); } int main_alignerTool(int argC, char* argV[]) @@ -548,7 +488,7 @@ int main_alignerTool(int argC, char* argV[]) if (argC<4) { main_alignerToolUsage(); - throw ""; + throw icu::UnicodeString(""); } Arguments args; @@ -586,11 +526,11 @@ int main_alignerTool(int argC, char* argV[]) if (batchMode && (remains.size()!=2) ) { - std::cerr << "Batch mode requires exactly two file arguments." << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1117", {}, {}, false); std::cerr << std::endl; main_alignerToolUsage(); - throw "argument error"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } std::string handArgumentname = "hand"; @@ -598,8 +538,8 @@ int main_alignerTool(int argC, char* argV[]) { if (batchMode) { - std::cerr << "-batch and -" << handArgumentname << " are incompatible switches." << std::endl; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1047", {"arg"}, {handArgumentname.c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } else { @@ -608,8 +548,8 @@ int main_alignerTool(int argC, char* argV[]) if (alignParameters.handAlignFilename.empty()) { - std::cerr << "-" << handArgumentname << " switch requires a filename value." << std::endl; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1119", {"arg"}, {handArgumentname.c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } } } @@ -619,8 +559,8 @@ int main_alignerTool(int argC, char* argV[]) { if (batchMode) { - std::cerr << "-batch and -" << autoDictDumpArgumentname << " are incompatible switches." << std::endl; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1118", {"arg"}, {autoDictDumpArgumentname.c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } else { @@ -629,19 +569,19 @@ int main_alignerTool(int argC, char* argV[]) if (alignParameters.autoDictionaryDumpFilename.empty()) { - std::cerr << "-" << autoDictDumpArgumentname << " switch requires a filename value." << std::endl; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1119", {"arg"}, {autoDictDumpArgumentname.c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } } } if (!batchMode && (remains.size()!=3) ) { - std::cerr << "Nonbatch mode requires exactly three file arguments." << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1120", {}, {}, false); std::cerr << std::endl; main_alignerToolUsage(); - throw "argument error"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } try @@ -653,7 +593,7 @@ int main_alignerTool(int argC, char* argV[]) std::cerr << std::endl; main_alignerToolUsage(); - throw "argument error"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } // std::cerr << "Reading dictionary..." << std::endl; @@ -677,8 +617,8 @@ int main_alignerTool(int argC, char* argV[]) if (words.size()!=3) { - std::cerr << "Batch file has incorrect format." << std::endl; - throw "data error"; + I18n(APER_I18N_DATA, "apertium").error("APER1121", {}, {}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1122"); } std::string huFilename, enFilename, outFilename; @@ -692,25 +632,25 @@ int main_alignerTool(int argC, char* argV[]) { alignerToolWithFilenames( dictionary, huFilename, enFilename, alignParameters, outFilename ); } - catch ( const char* errorType ) + catch ( icu::UnicodeString errorType ) { std::cerr << errorType << std::endl; failed = true; } catch ( std::exception& e ) { - std::cerr << "some failed assertion:" << e.what() << std::endl; + I18n(APER_I18N_DATA, "apertium").error("some_failed_assertion", {"what"}, {e.what()}, false); failed = true; } catch ( ... ) { - std::cerr << "some unknown failed assertion..." << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1168", {}, {}, false); failed = true; } if (failed) { - std::cerr << "Align failed for " << outFilename << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1169", {"file"}, {outFilename.c_str()}, false); } } } @@ -723,19 +663,19 @@ int main_alignerTool(int argC, char* argV[]) } } #ifndef _DEBUG - catch ( const char* errorType ) + catch ( icu::UnicodeString errorType ) { std::cerr << errorType << std::endl; return -1; } catch ( std::exception& e ) { - std::cerr << "some failed assertion:" << e.what() << std::endl; + I18n(APER_I18N_DATA, "apertium").error("some_failed_assertion", {"what"}, {e.what()}, false); return -1; } catch ( ... ) { - std::cerr << "some unknown failed assertion..." << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1168", {}, {}, false); return -1; } #endif diff --git a/apertium/tmx_alignment.cc b/apertium/tmx_alignment.cc index 97ae617..b0a545d 100644 --- a/apertium/tmx_alignment.cc +++ b/apertium/tmx_alignment.cc @@ -19,6 +19,7 @@ #include #include #include +#include // Copypaste-elve. TODO Elhelyezni. #define massert(e) if (!(e)) { std::cerr << #e << " failed" << std::endl; throw "assert"; } @@ -314,7 +315,7 @@ void trelliToLadder( const TrelliMatrix& trellis, Trail& bestTrail ) bestTrail.clear(); bestTrail.push_back(std::make_pair(huBookSize,enBookSize)); bestTrail.push_back(std::make_pair(0,0)); - std::cerr << "Error: hopelessly bad trail." << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1125", {}, {}, false); } std::reverse(bestTrail.begin(), bestTrail.end() ); diff --git a/apertium/tmx_arguments_parser.cc b/apertium/tmx_arguments_parser.cc index acd00ec..b04de00 100644 --- a/apertium/tmx_arguments_parser.cc +++ b/apertium/tmx_arguments_parser.cc @@ -13,6 +13,7 @@ #include #include #include +#include // Could be better. bool alphabetic( char c) @@ -27,16 +28,16 @@ bool Arguments::read( int argc, char **argv ) std::string p = argv[i]; if (p.empty() || p[0]!='-') { - std::cerr << p << ": unable to parse argument\n"; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1126", {}, {}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); return false; } p.erase(0,1); if (p.empty()) { - std::cerr << "Empty argument\n"; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1127", {}, {}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); return false; } @@ -86,8 +87,8 @@ bool Arguments::read( int argc, char **argv, std::vector& remains ) if (p.empty()) { - std::cerr << "Empty argument\n"; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1127", {}, {}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); return false; } @@ -130,8 +131,8 @@ bool Arguments::getNumericParam( const std::string& name, int& num ) if (it->second.kind != AnyData::Int) { - std::cerr << "Argument -" << name << ": integer expected.\n"; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1128", {"arg"}, {name.c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } num = it->second.dInt; @@ -149,7 +150,7 @@ bool Arguments::getSwitchConst( const ArgName& name, bool& sw ) const } else if (! it->second.dString.empty()) { - std::cerr << "Argument -" << name << ": value is not allowed.\n"; + I18n(APER_I18N_DATA, "apertium").error("APER1129", {"arg"}, {name.c_str()}, false); return false; } else @@ -179,8 +180,8 @@ bool Arguments::getSwitchCompact( const ArgName& name ) } else { - std::cerr << "No value is allowed for argument -" << name << ".\n"; - throw "argument error"; + I18n(APER_I18N_DATA, "apertium").error("APER1130", {"arg"}, {name.c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } } @@ -188,7 +189,7 @@ void Arguments::checkEmptyArgs() const { if (!empty()) { - std::cerr << "Invalid argument: "; + I18n(APER_I18N_DATA, "apertium").error("APER1131", {}, {}, false); for ( Arguments::const_iterator it=begin(); it!=end(); ++it ) { @@ -199,6 +200,6 @@ void Arguments::checkEmptyArgs() const } std::cerr << std::endl; - throw "argument error"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1124"); } } diff --git a/apertium/tmx_builder.cc b/apertium/tmx_builder.cc index c62204d..3682615 100644 --- a/apertium/tmx_builder.cc +++ b/apertium/tmx_builder.cc @@ -29,6 +29,7 @@ #include #include "apertium_config.h" #include +#include #ifdef _MSC_VER #include @@ -133,18 +134,18 @@ TMXBuilder::check(string const &file1, string const &file2, bool lazy) bool bf2 = f2.open(file2.c_str()); if(!bf1 && !bf2) { - cerr << "Error: Cannot access files '" << file1; - cerr << "' and '" << file2 << "'" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {file1.c_str()}, false); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {file2.c_str()}, false); return false; } else if(!bf1) { - cerr << "Error: Cannot access file '" << file1 << "'" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {file1.c_str()}, false); return false; } else if(!bf2) { - cerr << "Error: Cannot access file '" << file2 << "'" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {file2.c_str()}, false); return false; } @@ -328,9 +329,7 @@ TMXBuilder::generate(string const &file1, string const &file2, output = u_fopen(outfile.c_str(), "w", NULL, NULL); if(!output) { - cerr << "Error: file '" << outfile; - cerr << "' cannot be opened for writing" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {outfile.c_str()}, true); } } @@ -926,8 +925,7 @@ TMXBuilder::setTranslation(string const &filename) freference = fopen(filename.c_str(), "r"); if(!freference) { - cerr << "Error: file '" << filename; - cerr << "' cannot be opened for reading" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {filename.c_str()}, false); freference = NULL; } diff --git a/apertium/tmx_dic_tree.h b/apertium/tmx_dic_tree.h index 957de53..4fb0efa 100644 --- a/apertium/tmx_dic_tree.h +++ b/apertium/tmx_dic_tree.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace TMXAligner { @@ -165,7 +166,7 @@ void SubsetLookup::add( const Atoms& words, const Identifier& else { if (DicTree::WarnOnConflict) - std::cerr << "warning: conflict in tree" << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1132", {}, {}, false); } } diff --git a/apertium/tmx_dictionary.cc b/apertium/tmx_dictionary.cc index 70944ea..148d702 100644 --- a/apertium/tmx_dictionary.cc +++ b/apertium/tmx_dictionary.cc @@ -21,6 +21,7 @@ #include #include +#include #define massert(e) if (!(e)) { std::cerr << #e << " failed" << std::endl; throw "assert"; } @@ -151,8 +152,9 @@ void readBicorpus( std::istream& is, SentenceList& huSentenceList, SentenceList& split( line, halfs ); if (halfs.size()!=2) { - std::cerr << "Incorrect bicorpus file: " << halfs.size() << " records in line " << huSentenceList.size() << std::endl; - throw "data error"; + I18n(APER_I18N_DATA, "apertium").error("APER1133", {"records", "line"}, + {std::to_string(halfs.size()).c_str(), std::to_string(huSentenceList.size()).c_str()}, false); + throw I18n(APER_I18N_DATA, "apertium").format("APER1122"); } { @@ -260,17 +262,17 @@ void DictionaryItems::read( std::istream& is ) void Dictionary::read( const char* dictionaryFile ) { - throw "unimplemented"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1123"); } void Dictionary::build( const DictionaryItems& dictionaryItems ) { - throw "unimplemented"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1123"); } void Dictionary::reverse( const Dictionary& dic ) { - throw "unimplemented"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1123"); } bool Dictionary::lookupWord( const Word& word, DictionaryItems& results ) const @@ -642,7 +644,7 @@ void IBMModelOne::build( const SentenceList& huSentenceList, const SentenceList& void IBMModelOne::reestimate( const SentenceList& huSentenceList, const SentenceList& enSentenceList ) { - throw "unimplemented"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1123"); } // @@ -665,7 +667,7 @@ double IBMModelOne::distance( const Phrase& hu, const Phrase& en ) const val -= log(sum); } - throw "unimplemented"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1123"); } } // namespace TMXAligner diff --git a/apertium/trans-header.sh b/apertium/trans-header.sh index 57a395c..733caae 100644 --- a/apertium/trans-header.sh +++ b/apertium/trans-header.sh @@ -23,12 +23,7 @@ case $# in SALIDA=$5 ;; *) - echo "USAGE: $(basename $0) [format [infile [outfile]]]" - echo " datadir Directory of linguistic data" - echo " translation LANG1-LANG2" - echo " format one of: txt (default), txtu, html, htmlu, rtf, rtfu" - echo " infile input file (stdin by default)" - echo " outfile output file (stdout by default)" + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "trans_desc" "basename" "$(basename "$0")" exit 1; esac diff --git a/apertium/transfer.cc b/apertium/transfer.cc index 5950637..472dc9d 100644 --- a/apertium/transfer.cc +++ b/apertium/transfer.cc @@ -20,6 +20,7 @@ #include #include +#include using namespace std; @@ -32,8 +33,7 @@ Transfer::readBil(string const &fstfile) FILE *in = fopen(fstfile.c_str(), "rb"); if(!in) { - cerr << "Error: Could not open file '" << fstfile << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {fstfile.c_str()}, true); } fstp.load(in); fstp.initBiltrans(); @@ -46,8 +46,7 @@ Transfer::setExtendedDictionary(string const &fstfile) FILE *in = fopen(fstfile.c_str(), "rb"); if(!in) { - cerr << "Error: Could not open extended dictionary file '" << fstfile << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {fstfile.c_str()}, true); } extended.load(in); extended.initBiltrans(); @@ -75,16 +74,19 @@ Transfer::checkIndex(xmlNode *element, int index, int limit) { if(index >= limit) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": index >= limit" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1047", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } if(index < 0) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": index < 0" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1048", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } if(word[index] == 0) { - cerr << "Error in " << (char *) doc->URL << ": line " << element->line << ": Null access at word[index]" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1049", {"file_name", "line_number"}, + {(char *) doc->URL, element->line}, false); return false; } return true; @@ -380,8 +382,7 @@ Transfer::processMlu(xmlNode* element) void Transfer::processLuCount(xmlNode* element) { - cerr << "Error: unexpected expression: '" << element->name << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1050", {"expression"}, {(char*)element->name}, true); } void @@ -445,8 +446,7 @@ Transfer::processChunk(xmlNode *localroot) } else { - cerr << "Error: you must specify either 'name' or 'namefrom' for the 'chunk' element" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1135", {}, {}, true); } } else @@ -461,8 +461,7 @@ Transfer::processChunk(xmlNode *localroot) } else { - cerr << "Error: you must specify either 'name' or 'namefrom' for the 'chunk' element" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1135", {}, {}, true); } } @@ -534,7 +533,8 @@ Transfer::processLet(xmlNode *localroot) bool match = word[ti.getPos()]->setSource(attr_items[ti.getContent()], evalString(rightSide), ti.getCondition()); if (!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } } return; @@ -544,7 +544,8 @@ Transfer::processLet(xmlNode *localroot) bool match = word[ti.getPos()]->setTarget(attr_items[ti.getContent()], evalString(rightSide), ti.getCondition()); if (!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } } return; @@ -554,7 +555,8 @@ Transfer::processLet(xmlNode *localroot) bool match = word[ti.getPos()]->setReference(attr_items[ti.getContent()], evalString(rightSide), ti.getCondition()); if (!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } } return; @@ -612,11 +614,11 @@ Transfer::processLet(xmlNode *localroot) } if (pos >= lword) { - cerr << "Error: Transfer::processLet() bad access on pos >= lword" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1137", {}, {}, false); return; } if (word[pos] == 0) { - cerr << "Error: Transfer::processLet() null access on word[pos]" << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1138", {}, {}, false); return; } @@ -625,7 +627,8 @@ Transfer::processLet(xmlNode *localroot) bool match = word[pos]->setTarget(attr_items[part], evalString(rightSide), queue); if(!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } evalStringCache[leftSide] = TransferInstr(ti_clip_tl, part, pos, NULL, queue); } @@ -634,7 +637,8 @@ Transfer::processLet(xmlNode *localroot) bool match = word[pos]->setReference(attr_items[part], evalString(rightSide), queue); if(!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } evalStringCache[leftSide] = TransferInstr(ti_clip_ref, part, pos, NULL, queue); } @@ -643,7 +647,8 @@ Transfer::processLet(xmlNode *localroot) bool match = word[pos]->setSource(attr_items[part], evalString(rightSide), queue); if(!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } evalStringCache[leftSide] = TransferInstr(ti_clip_sl, part, pos, NULL, queue); } @@ -706,7 +711,8 @@ Transfer::processModifyCase(xmlNode *localroot) bool match = word[pos]->setSource(attr_items[part], result); if(!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } } else if(!xmlStrcmp(side, (const xmlChar *) "ref")) @@ -716,7 +722,8 @@ Transfer::processModifyCase(xmlNode *localroot) bool match = word[pos]->setReference(attr_items[part], result); if(!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } } else @@ -726,7 +733,8 @@ Transfer::processModifyCase(xmlNode *localroot) bool match = word[pos]->setTarget(attr_items[part], result); if(!match && trace) { - cerr << "apertium-transfer warning: on line " << localroot->line << " sometimes discards its value." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1136", {"tag", "line"}, + {"", localroot->line}, false); } } } @@ -764,7 +772,7 @@ Transfer::processCallMacro(xmlNode *localroot) std::fill(myword, myword+npar, (TransferWord *)(0)); for (auto i : children(localroot)) { if (idx >= npar) { - cerr << "Error: processCallMacro() number of arguments >= npar at line " << i->line << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1139", {"line"}, {i->line}, false); return; } int pos = atoi((const char *) i->properties->children->content)-1; @@ -1228,7 +1236,7 @@ Transfer::transfer(InputFile& in, UFILE* out) break; default: - cerr << "Error: Unknown input token." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1051", {}, {}, false); return; } } diff --git a/apertium/transfer_base.cc b/apertium/transfer_base.cc index 9f85293..174200f 100644 --- a/apertium/transfer_base.cc +++ b/apertium/transfer_base.cc @@ -3,6 +3,7 @@ #include #include #include +#include using namespace std; @@ -26,8 +27,7 @@ TransferBase::read(const char* transferfile, const char* datafile) { doc = xmlReadFile(transferfile, NULL, 0); if (doc == NULL) { - cerr << "Error: Could not parse file '" << transferfile << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {transferfile}, true); } root_element = xmlDocGetRootElement(doc); @@ -42,8 +42,7 @@ TransferBase::read(const char* transferfile, const char* datafile) FILE* in = fopen(datafile, "rb"); if (!in) { - cerr << "Error: Could not open file '" << datafile << "' for reading." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {datafile}, true); } alphabet.read(in); @@ -203,7 +202,7 @@ UString TransferBase::evalString(xmlNode* element) { if (!element) { - throw "evalString() was called on a NULL element"; + throw I18n(APER_I18N_DATA, "apertium").format("APER1134"); } if (evalStringCache.find(element) != evalStringCache.end()) { return evalCachedString(element); @@ -243,8 +242,7 @@ TransferBase::evalString(xmlNode* element) } else if (!xmlStrcmp(element->name, (const xmlChar*) "chunk")) { return processChunk(element); } else { - cerr << "Error: unexpected expression: '" << element->name << "'" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1050", {"expression"}, {(char*)element->name}, true); } return evalCachedString(element); } diff --git a/apertium/transfer_mult.cc b/apertium/transfer_mult.cc index b28c4f0..4a43812 100644 --- a/apertium/transfer_mult.cc +++ b/apertium/transfer_mult.cc @@ -23,6 +23,7 @@ #include #include #include +#include using namespace std; @@ -120,8 +121,7 @@ TransferMult::readBil(string const &fstfile) FILE *in = fopen(fstfile.c_str(), "r"); if(!in) { - cerr << "Error: Could not open file '" << fstfile << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {fstfile.c_str()}, true); } fstp.load(in); fstp.initBiltrans(); @@ -135,8 +135,7 @@ TransferMult::read(string const &datafile, string const &fstfile) FILE *in = fopen(datafile.c_str(), "r"); if(!in) { - cerr << "Error: Could not open file '" << datafile << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {datafile.c_str()}, true); } readData(in); fclose(in); diff --git a/apertium/transformdic-header.sh b/apertium/transformdic-header.sh index cfcae11..c14fa0d 100644 --- a/apertium/transformdic-header.sh +++ b/apertium/transformdic-header.sh @@ -7,7 +7,7 @@ FILE1=$2; FILE2=$3; if [ ! -e $2 ] -then echo "ERROR: '$1' file not found"; + then echo icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$2"; exit 1; fi @@ -16,5 +16,5 @@ then xsltproc $XSLTPROC_OPTIONS_LR $STYLESHEET $FILE1 >$FILE2 elif [ $1 = "rl" ] then xsltproc $XSLTPROC_OPTIONS_RL $STYLESHEET $FILE1 >$FILE2 else - echo "ERROR: $1 option invalid"; + then echo icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1108" "opt" "$1"; fi diff --git a/apertium/transformdicbil-header.sh b/apertium/transformdicbil-header.sh index a476e15..90c2266 100644 --- a/apertium/transformdicbil-header.sh +++ b/apertium/transformdicbil-header.sh @@ -7,7 +7,7 @@ FILE1=$1; FILE2=$2; if [ ! -e $1 ] -then echo "ERROR: '$1' file not found"; +then echo icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$1"; exit 1; fi diff --git a/apertium/trx_reader.cc b/apertium/trx_reader.cc index 3ceaf39..ae70e96 100644 --- a/apertium/trx_reader.cc +++ b/apertium/trx_reader.cc @@ -22,6 +22,7 @@ #include #include #include +#include UString const TRXReader::ANY_TAG = ""_u; UString const TRXReader::ANY_CHAR = ""_u; @@ -172,9 +173,13 @@ TRXReader::checkClip() UString part = attrib("part"_u); auto& attrs = td.getAttrItems(); if (part.empty()) { - parseError(" missing attribute part"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1140", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } else if (attrs.find(part) == attrs.end()) { - parseError("Undefined attr-item "_u + part); + I18n(APER_I18N_DATA, "apertium").error("APER1072", {"line", "column", "part"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(part.data())}, true); } } @@ -233,7 +238,9 @@ TRXReader::procRules() if(range.first == range.second) { - parseError("Undefined cat-item '"_u + attrib("n"_u)); + I18n(APER_I18N_DATA, "apertium").error("APER1072", {"line", "column", "attrib"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(attrib("n"_u).data())}, true); } // new code @@ -279,8 +286,7 @@ TRXReader::procRules() if(name == "clip"_u) { checkClip(); if (attrib("side"_u) == "sl"_u) { - cerr << "Warning (" << lineno; - cerr << "): assignment to 'sl' side has no effect." << endl; + I18n(APER_I18N_DATA, "apertium").error("APER1143", {"line"}, {lineno}, false); } } break; @@ -300,9 +306,7 @@ TRXReader::write(string const &filename) FILE *out = fopen(filename.c_str(), "wb"); if(!out) { - cerr << "Error: cannot open '" << filename; - cerr << "' for writing" << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {filename.c_str()}, true); } td.write(out); @@ -485,7 +489,9 @@ TRXReader::createMacro(UString const &name, int const value) { if(td.getMacros().find(name) != td.getMacros().end()) { - parseError("Macro '"_u + name + "' defined at least twice"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1144", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } td.getMacros()[name] = value; } diff --git a/apertium/tsx_reader.cc b/apertium/tsx_reader.cc index ef20298..95b2784 100644 --- a/apertium/tsx_reader.cc +++ b/apertium/tsx_reader.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,9 @@ TSXReader::newTagIndex(UString const &tag) { if(tag_index->find("TAG_"_u + tag) != tag_index->end()) { - parseError("'"_u + tag + "' already defined"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1145", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(tag.data())}, true); } array_tags->push_back("TAG_"_u + tag); @@ -141,7 +144,9 @@ TSXReader::procDiscardOnAmbiguity() } else { - parseError("Unexpected 'discard-on-ambiguity' open tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), "discard-on-ambiguity"}, true); } } else @@ -328,7 +333,9 @@ TSXReader::procLabelSequence() } if(name != "label-item"_u) { - parseError(" tag expected"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1147", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } forbid_rule.tagi = (*tag_index)["TAG_"_u + attrib("label"_u)]; @@ -340,7 +347,9 @@ TSXReader::procLabelSequence() } if(name != "label-item"_u) { - parseError(" tag expected"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1147", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } forbid_rule.tagj = (*tag_index)["TAG_"_u + attrib("label"_u)]; @@ -376,12 +385,16 @@ TSXReader::procForbid() } else { - parseError("Unexpected '"_u + name + "' open tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(name.data())}, true); } } else { - parseError("Unexpected '"_u + name + "' tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(name.data())}, true); } } } @@ -432,12 +445,16 @@ TSXReader::procEnforce() } else { - parseError("Unexpected 'enforce-rules' open tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), "enforce-rules"}, true); } } else { - parseError("Unexpected '"_u + name + "' tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(name.data())}, true); } } } @@ -472,12 +489,16 @@ TSXReader::procPreferences() } else { - parseError("Unexpected 'preferences' open tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), "preferences"}, true); } } else { - parseError("Unexpected '"_u + name + "' tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(name.data())}, true); } } } diff --git a/apertium/unigram_tagger.cc b/apertium/unigram_tagger.cc index 8fb543b..ee877e8 100644 --- a/apertium/unigram_tagger.cc +++ b/apertium/unigram_tagger.cc @@ -25,6 +25,7 @@ #include #include #include +#include namespace Apertium { @@ -64,7 +65,7 @@ UnigramTagger::serialise(std::ostream& o) const break; default: throw Exception::apertium_tagger::InvalidArgument( - "can't serialise without first selecting a model"); + I18n(APER_I18N_DATA, "apertium").format("APER1148")); } } @@ -86,7 +87,7 @@ UnigramTagger::deserialise(std::istream& s) break; default: throw Exception::apertium_tagger::InvalidArgument( - "can't read tagger without first selecting a model"); + I18n(APER_I18N_DATA, "apertium").format("APER1149")); } } @@ -146,7 +147,7 @@ UnigramTagger::score(const Analysis& Analysis_) { break; default: throw Exception::apertium_tagger::InvalidArgument( - "can't score analysis without first selecting a model"); + I18n(APER_I18N_DATA, "apertium").format("APER1150")); } } @@ -331,7 +332,7 @@ UnigramTagger::train_Analysis(const Analysis &Analysis_, const std::size_t &Coef break; default: throw Exception::apertium_tagger::InvalidArgument( - "can't train model without first selecting a model"); + I18n(APER_I18N_DATA, "apertium").format("APER1151")); } } @@ -382,7 +383,7 @@ UnigramTagger::multiplyModel(const std::size_t &OccurrenceCoefficientMultiplier) break; default: throw Exception::apertium_tagger::InvalidArgument( - "can't multiplyModel() without first selecting a model"); + I18n(APER_I18N_DATA, "apertium").format("APER1152")); } } @@ -396,7 +397,7 @@ UnigramTagger::train(Stream &TaggedCorpus) { if (StreamedType_.TheLexicalUnit->TheAnalyses.empty()) throw Exception::LexicalUnit::TheAnalyses_empty( - "can't train LexicalUnit comprising empty Analysis std::vector"); + I18n(APER_I18N_DATA, "apertium").format("APER1153")); std::size_t analysis_count = StreamedType_.TheLexicalUnit->TheAnalyses.size(); diff --git a/apertium/validate-header.sh b/apertium/validate-header.sh index 2fbbb39..10ad127 100644 --- a/apertium/validate-header.sh +++ b/apertium/validate-header.sh @@ -6,7 +6,7 @@ fi FILE1=$1 if [[ ! -e $FILE1 ]]; then - echo "ERROR: '$1' file not found" + icuformat "$APERTIUM_DATADIR"/apertium.dat "apertium" "APER1000" "file_name" "$1"; exit 1 fi diff --git a/apertium/wblank-attach.cc b/apertium/wblank-attach.cc index e379ad9..b8ed4c2 100644 --- a/apertium/wblank-attach.cc +++ b/apertium/wblank-attach.cc @@ -21,6 +21,8 @@ #include #include #include +#include +#include void trim_wb(std::string& wb) { while (!wb.empty() && (wb.back() == ';' || wb.back() == ' ')) { @@ -35,9 +37,7 @@ void trim_wb(std::string& wb) { int main(int argc, char* argv[]) { // Ignore -z, but anything else just show what this tool does if (argc > 1 && argv[1][1] != 'z') { - std::cout << "Distributes word-bound blanks across all tokens they encompass, turning [[A]]^...$^...$[[/]] into [[A]]^...$[[A]]^...$\n"; - std::cout << "Also merges word-bound blanks, turning [[A]][[B]]^...$^...$[[/]][[/]] into [[A; B]]^...$\n"; - std::cout << "Word-bound blanks will be deduplicated, but order will be preserved amongst unique elements.\n"; + std::cout << I18n(APER_I18N_DATA, "wblank_attach_desc").format("APER1047"); return 0; } @@ -80,7 +80,7 @@ int main(int argc, char* argv[]) { if (c == '\0') { in_token = in_blank = false; if (!wbs.empty()) { - std::cerr << "tf-apertium-spread warning: Null-flush found, but had open word-bound blanks on line " << line << ":"; + I18n(APER_I18N_DATA, "apertium").error("APER1154", {"line"}, {std::to_string(line).c_str()}, false); for (auto& wb : wbs) { std::cerr << ' ' << wb; } @@ -88,7 +88,7 @@ int main(int argc, char* argv[]) { wbs.clear(); } if (!blank.empty()) { - std::cerr << "tf-apertium-spread warning: Null-flush found, but had an open blank on line " << line << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1154", {"line"}, {std::to_string(line).c_str()}, false); std::cout << blank; blank.clear(); unesc.clear(); @@ -142,7 +142,7 @@ int main(int argc, char* argv[]) { in_blank = false; if (blank[0] == '[' && blank[1] == '[' && blank[2] == '/' && blank[3] == ']' && blank[4] == ']') { if (wb_stack.empty()) { - std::cerr << "tf-apertium-spread warning: Too many [[/]] on line " << line << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1155", {"line"}, {std::to_string(line).c_str()}, false); } else { for (size_t i = 0 ; i < wb_stack.back() ; ++i) { @@ -177,14 +177,14 @@ int main(int argc, char* argv[]) { } if (!wbs.empty()) { - std::cerr << "tf-apertium-spread warning: End of input reached, but had open word-bound blanks:"; + I18n(APER_I18N_DATA, "apertium").error("APER1154", {"line"}, {"NULL"}, false); for (auto& wb : wbs) { std::cerr << ' ' << wb; } std::cerr << std::endl; } if (!blank.empty()) { - std::cerr << "tf-apertium-spread warning: End of input reached, but had an open blank." << std::endl; + I18n(APER_I18N_DATA, "apertium").error("APER1156", {}, {}, false); std::cout << blank; } } diff --git a/apertium/wblank-detach.cc b/apertium/wblank-detach.cc index ab22d5a..263c79e 100644 --- a/apertium/wblank-detach.cc +++ b/apertium/wblank-detach.cc @@ -19,12 +19,13 @@ #include #include #include +#include +#include int main(int argc, char* argv[]) { // Ignore -z, but anything else just show what this tool does if (argc > 1 && argv[1][1] != 'z') { - std::cout << "Closes all word-bound blanks, turning [[...]]^...$ into [[...]]^...$[[/]]\n"; - std::cout << "This tool does not merge across whitespace or do any other heuristics wrt. which word-bound blanks should have their spans combined.\n"; + std::cout << I18n(APER_I18N_DATA, "apertium").format("wblank_detach_desc"); return 0; } diff --git a/apertium/xml_reader.cc b/apertium/xml_reader.cc index 86639ff..cd6b335 100644 --- a/apertium/xml_reader.cc +++ b/apertium/xml_reader.cc @@ -1,4 +1,5 @@ #include +#include XMLReader::XmlTextReaderResource::XmlTextReaderResource( @@ -7,8 +8,7 @@ XMLReader::XmlTextReaderResource::XmlTextReaderResource( { reader = xmlReaderForFile(filename.c_str(), NULL, 0); if (reader == NULL) { - cerr << "Error: Cannot open '" << filename << "'." << endl; - exit(EXIT_FAILURE); + I18n(APER_I18N_DATA, "apertium").error("APER1000", {"file_name"}, {filename.c_str()}, true); } } @@ -36,7 +36,9 @@ XMLReader::step() int retval = xmlTextReaderRead(reader); if (retval != 1) { - parseError("unexpected EOF"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1157", {"line", "column"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader)}, true); } name = XMLParseUtil::readName(reader); type = xmlTextReaderNodeType(reader); @@ -103,7 +105,9 @@ XMLReader::warnAtLoc() void XMLReader::unexpectedTag() { - parseError("unexpected '<"_u + name + ">' tag"_u); + I18n(APER_I18N_DATA, "apertium").error("APER1146", {"line", "column", "tag"}, + {xmlTextReaderGetParserLineNumber(reader), + xmlTextReaderGetParserColumnNumber(reader), icu::UnicodeString(name.data())}, true); } void diff --git a/configure.ac b/configure.ac index e932c02..dd0821c 100644 --- a/configure.ac +++ b/configure.ac @@ -71,6 +71,7 @@ AC_CHECK_FUNCS(strcasecmp) PKG_CHECK_MODULES(LTTOOLBOX, [lttoolbox >= 3.7.2], CPPFLAGS="$CPPFLAGS $LTTOOLBOX_CFLAGS"; LIBS="$LIBS $LTTOOLBOX_LIBS") PKG_CHECK_MODULES(LIBXML2, [libxml-2.0 >= 2.6.17], CPPFLAGS="$CPPFLAGS $LIBXML2_CFLAGS"; LIBS="$LIBS $LIBXML2_LIBS") PKG_CHECK_MODULES(ICU, [icu-i18n, icu-io, icu-uc], CPPFLAGS="$CPPFLAGS $ICU_CFLAGS"; LIBS="$LIBS $ICU_LIBS") +PKG_CHECK_MODULES(I18N, [i18n], CPPFLAGS="$CPPFLAGS $I18N_CFLAGS"; LIBS="$LIBS $I18N_LIBS") AC_C_BIGENDIAN @@ -136,4 +137,5 @@ AC_OUTPUT([ scripts/Makefile tests/Makefile tests/tagger/Makefile python/Makefile + locales/Makefile ]) diff --git a/locales/Makefile.am b/locales/Makefile.am new file mode 100644 index 0000000..4d18604 --- /dev/null +++ b/locales/Makefile.am @@ -0,0 +1,7 @@ +apertium.dat: root.txt en.txt + genrb -d . root.txt en.txt + echo root.res en.res > package_list.txt + pkgdata -p apertium --mode archive -d . package_list.txt + +localesdir = $(LOCALES_DIR) +dist_locales_DATA = apertium.dat diff --git a/locales/en.txt b/locales/en.txt new file mode 100644 index 0000000..0bd10e4 --- /dev/null +++ b/locales/en.txt @@ -0,0 +1,2 @@ +en{ +} \ No newline at end of file diff --git a/locales/package_list.txt b/locales/package_list.txt new file mode 100644 index 0000000..d5134dd --- /dev/null +++ b/locales/package_list.txt @@ -0,0 +1 @@ +root.res en.res diff --git a/locales/root.txt b/locales/root.txt new file mode 100644 index 0000000..f1c459b --- /dev/null +++ b/locales/root.txt @@ -0,0 +1,451 @@ +root{ + adapt_docx_desc{"makes some changes to .xml files from .docx components\n" + "- moves word boundaries to 'legal' positions\n" + "Gets input file name from stdin (or from -f), writes to stdout"} + usage{"USAGE"} + options{"Options"} + arguments{"ARGUMENTS"} + name_desc{"writes \"< file name=\"filename\">\" to output"} + file_desc{"gets file name as parameter"} + pretty_desc{"outputs xml with a pretty format"} + paragraphs_found{"paragraphs found"} + file_name{"file name"} + + compile_caps_desc{"compile capitalization restoration rules"} + help_desc{"print this message and exit"} + + deshtml_desc{"html format processor."}; + + extract_caps_desc{"Transfer capitalization information to word-bound blanks"} + surface_desc{"keep surface forms"} + null_flush_desc{"flush output on the null character"} + + interchunck_desc{"process stream with interchunker"} + trace_desc{"trace mode (show rule numbers and patterns matched)"} + dictionary_case_desc{"ignore capitalization manipulation instructions"} + chunck_epilog{"FILES:\n" + " t2x t2x rules file\n" + " preproc result of preprocess trules file\n" + " input input file, standard input by default\n" + " output output file, standard output by default"} + + macro_definitions{"Macro definitions"} + spec{"Spec"} + perceptron_trace_desc{"Run with one of:\n" + "{program_name} model \n" + "Output features and weights from a model file.\n" + "{program_name} mtx \n" + "Output macros and features from an mtx file.\n" + "{program_name} path \n" + "Trace a particular path through giving which features fire " + "and the resulting score. Useful for interactively " + "designing feature sets.\n"} + postchunck_desc{"process stream with postchunker"} + + no_surface_forms_desc{"assume no surface forms"} + compounds_desc{"treat ~ as compound separator"} + + restore_caps_desc{"compile capitalization restoration rules"} + keep_desc{"retain all wblanks"} + + tagger_apply_new_rules_desc{"Forbid and enforce rules are applied to the given HMM parameters"} + hmm_filein_desc{"To specify the file with the HMM parameter to process"} + hmm_fileout_desc{"To specify the file to which the HMM will be written"} + hmm_tsxfile_desc{"File containing the rules to apply"} + tagger_apply_new_rules_note{"NOTE: Parameters are read from and written to the files provided"} + + reading_from_file{"Reading from file \"{file_name}\" ... "} + writing_to_file{"Writing to file \"{file_name}\" ... "} + done{"done."} + readed_words{"{number_of_words} were readed."} + + probfile_desc{"Specify a tagger parameter file"} + clength_desc{"Specify the length of the corpus to process"} + locale{"LOCALE"} + command_line{"Command line"} + tagger_note{"Try \"apertium-tagger --help\" for more information."} + percent_desc{"number 0 < n <= 1 to set margin of confidence of TU's \n" + " (0.85 by default) in length terms."} + edit_desc{"number 0 < n <= 1 to set margin of confidence of TU's \n" + " (0.30 by default) in edit distance terms"} + low_limit_desc{"ignore percent if the segment is less than lowlimit \n" + " (15 by default)"} + max_edit_desc{"characters to be taken into account when aligning \n" + " sentences (50 by default)"} + diagonal_desc{"diagonal width for using edit distance, 10 by default"} + window_desc{"window size of the edit distance with sentences \n" + " (100 sentences by default)"} + step_desc{"step for moving the window during the alingment \n" + " (75 sentences by default)"} + tmxbuild_note{"Other parameters:\n" + " code1, code2 codes of the languages (i.e. ISO-631 ones)\n" + " doc1, doc2 unformatted docs to build the TMX file\n" + " output_file if not specified, the result will be printed to stdout"} + trace_att_desc{"trace, for apertium-transfer-tools (also sets -t)"} + from_bilingual_desc{"input from lexical transfer"} + no_bilingual_desc{"don't use bilingual dictionary"} + extended_desc{"extended mode with user dictionary"} + case_sensitive_desc{"case-sensitiveness while accessing bilingual dictionary"} + trules_desc{"transfer rules file"} + preproc_desc{"result of preprocess trules file"} + biltrans_desc{"bilingual letter transducer file"} + input_desc{"input file, standard input by default"} + output_desc{"output file, standard output by default"} + + apertium_desc{"USAGE: {basename} [-d datadir] [-f format] [-u] [in [out]]\n" + " -d datadir directory of linguistic data\n" + " -f format one of: txt (default), html, rtf, odt, odp, docx, wxml, xlsx, pptx,\n" + " xpresstag, html-noent, html-alt, latex, latex-raw, line\n" + " -a display ambiguity\n" + " -u don't display marks '*' for unknown words\n" + " -n don't insert period before possible sentence-ends\n" + " -m memory.tmx use a translation memory to recycle translations\n" + " -o direction translation direction using the translation memory,\n" + " by default 'direction' is used instead\n" + " -l lists the available translation directions and exits\n" + " -V print Apertium version\n" + " -z force null-flush mode on all parts of the pipe\n" + " direction typically, LANG1-LANG2, but see modes.xml in language data\n" + " in input file (stdin by default)\n" + " out output file (stdout by default)"} + + gen_modes_desc{"Generate mode command files from XML"} + full_desc{"expect absolute installation path"} + local_desc{"output to current directory rather than directory of modes.xml"} + verbose_desc{"print more detailed messages"} + num_of_states_and_ambiguity_classes{"{states} states and {classes} ambiguity classes."} + + interchunk_rule_line{"apertium-interchunk: Rule {value} line {line}"} + postchunk_rule_line{"apertium-postchunk: Rule {value} line {line}"} + + tagger_cc_note{"Mandatory arguments to long options are mandatory for short options too."} + tagger_debug_desc{"with -g, print error messages about the input"} + tagger_first_desc{"with -g, reorder each lexical unit's analyses so that the chosen one is first"} + tagger_mark_desc{"with -g, mark disambiguated lexical units"} + tagger_show_superficial_desc{"with -g, output each lexical unit's surface form"} + tagger_null_flush_desc{"with -g, flush output on the null character"} + tagger_unigram_desc{"use unigram algorithm MODEL from "} + tagger_sliding_window_desc{"use the Light Sliding Window algorithm"} + tagger_perceptron_desc{"use the averaged perceptron algorithm"} + tagger_skip_on_error_desc{"with -xs, ignore certain types of errors with the training corpus"} + tagger_desc{"disambiguate the input"} + tagger_retrain_desc{"with -u: exit;\notherwise: retrain the tagger with ITERATIONS unsupervised iterations"} + tagger_supervised_desc{"with -u: train the tagger with a hand-tagged corpus;\nwith -w: exit;\notherwise: initialise the tagger with a hand-tagged corpus and retrain it with ITERATIONS tagger_unsupervised iterations"} + tagger_train_desc{"with -u: exit;\notherwise: train the tagger with ITERATIONS unsupervised iterations"} + apertium_tagger_desc{" -d, --debug with -g, print error messages about the input\ + -f, --first with -g, reorder each lexical unit's analyses so that\ + the chosen one is first\ + -m, --mark with -g, mark disambiguated lexical units\ + -p, --show-superficial with -g, output each lexical unit's surface form\ + -z, --null-flush with -g, flush the output after getting each null\ + character\ +\ + -u, --unigram=MODEL use unigram algorithm MODEL from\ + \ +\ + -w, --sliding-window use the Light Sliding Window algorithm\ + -x, --perceptron use the averaged perceptron algorithm\ + -e, --skip-on-error with -xs, ignore certain types of errors with the\ + training corpus\ +\ + -g, --tagger disambiguate the input\ +\ + -r, --retrain=ITERATIONS with -u: exit;\ + otherwise: retrain the tagger with ITERATIONS\ + unsupervised iterations\ + -s, --supervised=ITERATIONS with -u: train the tagger with a hand-tagged\ + corpus;\ + with -w: exit;\ + otherwise: initialise the tagger with a\ + hand-tagged corpus and retrain it with\ + ITERATIONS unsupervised iterations\ + -t, --train=ITERATIONS with -u: exit;\ + otherwise: train the tagger with ITERATIONS\ + unsupervised iterations\ +"} + tmx_aligner_tool_desc{"Usage (either):\n\ + alignerTool [ common_arguments ] [ -hand=hand_align_file ] dictionary_file source_text target_text\n\ +\n\ +or:\n\ + alignerTool [ common_arguments ] -batch dictionary_file batch_file\n\ +\n\ +where\n\ +common_arguments ::= [ -text ] [ -bisent ] [ -utf ] [ -cautious ] [ -realign [ -autodict=filename ] ]\n\ + [ -thresh=n ] [ -ppthresh=n ] [ -headerthresh=n ] [ -topothresh=n ]\n\ +\n\ +Arguments:\n\ +\n\ +-text\n\ + The output should be in text format, rather than the default (numeric) ladder format.\n\ +\n\ +-bisent\n\ + Only bisentences (one-to-one alignment segments) are printed. In non-text mode, their\n\ + starting rung is printed.\n\ +\n\ +-cautious\n\ + In -bisent mode, only bisentences for which both the preceding and the following\n\ + segments are one-to-one are printed. In the default non-bisent mode, only rungs\n\ + for which both the preceding and the following segments are one-to-one are printed.\n\ +\n\ +-hand=file\n\ + When this argument is given, the precision and recall of the alignment is calculated\n\ + based on the manually built ladder file. Information like the following is written\n\ + on the standard error: \n\ + 53 misaligned out of 6446 correct items, 6035 bets.\n\ + Precision: 0.991218, Recall: 0.928017\n\ + \n\ + Note that by default, 'item' means rung. The switch -bisent also changes the semantics\n\ + of the scoring from rung-based to bisentence-based and in this case 'item' means bisentences.\n\ + See File formats about the format of this input align file.\n\ +\n\ +-autodict=filename\n\ + The dictionary built during realign is saved to this file. By default, it is not saved.\n\ +\n\ +-utf\n\ + The system uses the character counts of the sentences as information for the\n\ + pairing of sentences. By default, it assumes one-byte character encoding such\n\ + as ISO Latin-1 when calculating these counts. If our text is in UTF-8 format,\n\ + byte counts and character counts are different, and we must use the -utf switch\n\ + to force the system to properly calculate character counts.\n\ + Note: UTF-16 input is not supported.\n\ +\n\ +Postfiltering options:\n\ +There are various postprocessors which remove implausible rungs based on various heuristics.\n\ +\n\ +-thresh=n\n\ + Don't print out segments with score lower than n/100.\n\ +\n\ +-ppthresh=n\n\ + Filter rungs with less than n/100 average score in their vicinity.\n\ +\n\ +-headerthresh=n\n\ + Filter all rungs at the start and end of texts until finding a reliably\n\ + plausible region.\n\ +\n\ +-topothresh=n\n\ + Filter rungs with less than n percent of one-to-one segments in their vicinity.\n\ +\n\ +"} + wblank_attach_desc{ + "Distributes word-bound blanks across all tokens they encompass, turning [[A]]^...$^...$[[/]] into [[A]]^...$[[A]]^...$\n" + "Also merges word-bound blanks, turning [[A]][[B]]^...$^...$[[/]][[/]] into [[A; B]]^...$\n" + "Word-bound blanks will be deduplicated, but order will be preserved amongst unique elements.\n"} + wblank_detach_desc{ + "Closes all word-bound blanks, turning [[...]]^...$ into [[...]]^...$[[/]]\n" + "This tool does not merge across whitespace or do any other heuristics wrt. which word-bound blanks should have their spans combined.\n"} + + deformat_desc{"USAGE: {first_line}\n" + " -a: apertium standard mode\n" + " -A: apertium optimized mode (default mode)\n" + " -m: matxin standard mode\n" + " -M: matxin optimized mode"} + trans_desc{"USAGE: [format [infile [outfile]]]\n" + " datadir Directory of linguistic data\n" + " translation LANG1-LANG2\n" + " format one of: txt (default), txtu, html, htmlu, rtf, rtfu\n" + " infile input file (stdin by default)\n" + " outfile output file (stdout by default)"} + some_failed_assertion{"some failed assertion: {what}"} + APER1000{"ERROR APER1000: Unable to access \"{file_name}\"."} + APER1001{"ERROR APER1001: Unescaped \"^\": {buf}^"} + APER1002{"ERROR APER1002: Stray \"$\""} + APER1003{"ERROR APER1003: Illegal regular expression for escape characters."} + APER1004{"ERROR APER1004: Illegal regular expression for tag-names."} + APER1005{"ERROR APER1005: Input in flex scanner failed."} + APER1006{"ERROR APER1006: Fatal flex scanner internal error--no action found."} + APER1007{"ERROR APER1007: Fatal flex scanner internal error--end of buffer missed."} + APER1008{"ERROR APER1008: Fatal error - scanner input buffer overflow."} + APER1009{"ERROR APER1009: Out of dynamic memory in {function}."} + APER1010{"ERROR APER1010: Bad buffer in {function}."} + APER1011{"ERROR APER1011: Out of memory expanding start-condition stack."} + APER1012{"ERROR APER1012: Start-condition stack underflow."} + APER1013{"ERROR APER1013: Can't convert const Analysis & comprising empty Morpheme std::vector to {letter}."} + APER1014{"ERROR APER1014: Can't convert const Analysis & comprising Morpheme comprising empty Tag std::vector to {letter}."} + APER1015{"ERROR APER1015: Can't convert Analysis comprising empty Morpheme std::vector to UString."} + APER1016{"ERROR APER1016: Unterminated lexical unit."} + APER1017{"ERROR APER1017: Reading regexp."} + APER1018{"ERROR APER1018: Unable to compile regular expression \"{exp}\".\n" + "Error code: {error}"} + APER1019{"ERROR APER1019: Cannot write empty regexp."} + APER1020{"ERROR APER1020: Unable to apply regexp.\n" + "Error code: {error}"} + APER1021{"ERROR APER1021: Unable to extract substring from regexp match.\n" + "Error code: {error}"} + APER1022{"ERROR APER1022: You did not provide an input file (.prob). Use --filein to do that."} + APER1023{"ERROR APER1023: You did not provide an output file (.prob). Use --fileout to do that."} + APER1024{"ERROR APER1024: You did not provide a tagger definition file (.tsx). Use --filetsx to do that."} + APER1025{"ERROR APER1025: Ambiguity class number out of range: {number}\n" + "Word: {word}\n" + "Ambiguity class: : {class}"} + APER1026{"ERROR APER1026: Corpus length provided with --clength must be a positive integer."} + APER1027{"ERROR APER1027: You have provided neither a tagger specification file (.tsx) nor a tagger probability file (.prob). Use --tsxfile or --probfile to provide one of them."} + APER1028{"ERROR APER1028: You provided a tagger specification file and a tagger probability file. Only one of them can be provided, not both."} + APER1029{"ERROR APER1029: In {file_name} on line {line_number}: Attribute lemma conflicts with attribute trglem."} + APER1030{"ERROR APER1030: In {file_name} on line {line_number}: Attribute surface conflicts with attribute trgsurf."} + APER1031{"ERROR APER1031: In {file_name} on line {line_number}: Unknown select value \"{select}\"."} + APER1032{"ERROR APER1032: In {file_name} on line {line_number}: Number of repetitions cannot be negative."} + APER1033{"ERROR APER1033: In {file_name} on line {line_number}: Lower bound on number of repetitions cannot be larger than upper bound."} + APER1034{"WARNING APER1034: There is not coarse tag for the fine tag \"{substr}\" of \"{str}\"\n" + " This is because of an incomplete tagset definition or a dictionary error"} + APER1035{"WARNING APER1035: kIGNORE was returned while reading a word.\n" + " Word being read: {word}\n" + " Debug: {str}"} + APER1036{"WARNING APER1036: Debug mode name {debug_name} generated multiple times, disregarding result from {mode_name} step {step_num}."} + APER1037{"ERROR APER1037: {program}:Installation prefix is the same directory as modes.xml; give a different INSTALLDIR."} + APER1038{"ERROR APER1038: Tagged text (.tagged) and analyzed text (.untagged) streams are not aligned.\n" + "Take a look at tagged text (.tagged).\n" + "Perhaps this is caused by a multiword unit that is not a multiword unit in one of the two files.\n" + "{word_tagged} -- {word_untagged}"} + APER1039{"ERROR APER1039: word_untagged==NULL"} + APER1040{"ERROR APER1040: Error in tagged text. An ambiguous word was found: {word}"} + APER1041{"WARNING APER1041: The last tag is not the end-of-sentence-tag but rather {tag}. Line: {line}. Pending: {pending}. Tags: "} + APER1042{"WARNING APER1042: gamma[{index}]=0"} + APER1043{"WARNING APER1043: Problem with word \"{word}\" {tags}"} + APER1044{"WARNING APER1044: The text to disambiguate has finished, but there are ambiguous words that has not been disambiguated.\n" + "This message should never appears. If you are reading this ..... these are very bad news."} + APER1045{"ERROR APER1045: Can't convert const Morpheme & comprising empty Tag std::vector to {letter}."} + APER1046{"ERROR APER1046: Can't convert const Analysis & comprising Morpheme comprising empty Tag std::vector to {letter}."} + APER1047{"ERROR APER1047: In {file_name} on line {line_number}: index >= limit"} + APER1048{"ERROR APER1048: In {file_name} on line {line_number}: index < 0"} + APER1049{"ERROR APER1049: In {file_name} on line {line_number}: Null access at word[index]"} + APER1050{"ERROR APER1050: Unexpected expression: \"{expression}\""} + APER1051{"ERROR APER1051: Unknown input token."} + APER1052{"WARNING APER1052: apertium-interchunck: on line {line_number}: sometimes discards its value."} + APER1053{"WARNING APER1053: apertium-interchunck: on line {line_number}: {tag} sometimes discards its value."} + APER1054{"ERROR APER1054: Can't convert const Analysis & comprising Morpheme comprising empty Lemma UString to Lemma."} + APER1055{"ERROR APER1055: Can't convert const Morpheme & comprising empty Lemma UString to Lemma."} + APER1056{"ERROR APER1056: Can't convert Morpheme comprising empty Tag std::vector to UString."} + APER1057{"ERROR APER1057: Can't convert Morpheme comprising empty TheLemma UString to UString."} + APER1058{"ERROR APER1058: Unterminted lexical unit."} + APER1059{"ERROR APER1059: empty lemma."} + APER1060{"ERROR APER1060: invalid tag <>."} + APER1061{"ERROR APER1061: morpheme has no tags."} + APER1062{"ERROR APER1062: trailing backslash."} + APER1063{"ERROR APER1063: unexpected < after lemma queue."} + APER1064{"ERROR APER1064: On line {line}, column {column}: Expected set-member."} + APER1065{"ERROR APER1065: On line {line}, column {column}: Expected an integer expression."} + APER1066{"ERROR APER1066: On line {line}, column {column}: Expected a string list expression."} + APER1067{"ERROR APER1067: On line {line}, column {column}: No such argument {var}."} + APER1068{"ERROR APER1068: On line {line}, column {column}: Variable {var} has the wrong type."} + APER1069{"ERROR APER1069: On line {line}, column {column}: Variable {var} has not been set."} + APER1070{"ERROR APER1070: On line {line}, column {column}: No such macro {var}."} + APER1071{"ERROR APER1071: On line {line}, column {column}: Macro {var} returns the wrong type."} + APER1072{"ERROR APER1072: On line {line}, column {column}: Expected a string expression."} + APER1073{"ERROR APER1073: On line {line}, column {column}: Expected an address expression."} + APER1074{"ERROR APER1074: On line {line}, column {column}: Expected a wordoid array expression."} + APER1075{"ERROR APER1075: On line {line}, column {column}: Expected a wordoid expression."} + APER1076{"ERROR APER1076: On line {line}, column {column}: Set required."} + APER1077{"ERROR APER1077: On line {line}, column {column}: String required."} + APER1078{"ERROR APER1078: On line {line}, column {column}: No {what} named {name}."} + APER1079{"ERROR APER1079: On line {line}, column {column}: {what} required."} + APER1080{"ERROR APER1080: On line {line}, column {column}: Opcodes can have at most one operand."} + APER1081{"ERROR APER1081: On line {line}, column {column}: Expected a string, bool or int expression."} + APER1082{"ERROR APER1082: On line {line}, column {column}: \"as\" attribute required for for-each."} + APER1083{"ERROR APER1083: On line {line}, column {column}: Expected a string array or wordoid array expression."} + APER1084{"ERROR APER1084: On line {line}, column {column}: Expected a void expression."} + APER1085{"ERROR APER1085: On line {line}, column {column}: \"as\" attribute required for def-macro."} + APER1086{"ERROR APER1086: On line {line}, column {column}: Expected a non-void expression."} + APER1087{"ERROR APER1087: On line {line}, column {column}: expected tag."} + APER1088{"ERROR APER1088: Unimplemented opcode: {opstr} at {feature} #{feat_idx} address #{bytecode_idx}"} + APER1089{"ERROR APER1089: Tagged analysis unavailable in untagged/ambigous input.\n" + "Available:\n" + "{available}" + "Required: {required}\n" + "Rerun with --skip-on-error to skip this sentence.\n"} + APER1090{"ERROR APER1090: Skipped {skipped} sentences due to token misalignment and {avail_skipped} sentences due to tagged token being unavailable in untagged file out of {total} total sentences."} + APER1091{"ERROR APER1091: In {file_name} on line {line_number}: index > limit"} + APER1092{"WARNING APER1092: apertium-postchunk: on line {line_number}: {tag} sometimes discards its value."} + APER1093{"ERROR APER1093: Postchunk::processCallMacro() assumes npar > 0, but got npar <= 0"} + APER1094{"WARNING APER1094: Not calling macro \"{macro}\" from line {line} (empty word?)"} + APER1095{"ERROR APER1095: Unexpected EOF"} + APER1096{"ERROR APER1096: Wordbound blank isn't immediately followed by the Lexical Unit."} + APER1097{"WARNING APER1097: Streams diverged at line {tagged_line}\n" + "Untagged token: {untagged_token}\n" + "Tagged token: {tagged_token}\n" + "Rerun with --skip-on-error to skip this sentence."} + APER1098{"ERROR APER1098: One stream has ended prematurely.\n" + "Please check if they are aligned.\n"} + APER1099{"ERROR APER1099: Expected one of this file arguments {expected}, got {actual}"} + APER1100{"ERROR APER1100: Failed operation in {metavar} file \"{filename}\""} + APER1101{"ERROR APER1101: lexical unit has no analyses"} + APER1102{"ERROR APER1102: unexpected /, surface form is empty"} + APER1103{"ERROR APER1103: unterminated lexical unit"} + APER1104{"ERROR APER1104: A new ambiguity class was found. I cannot continue.\n" + "Word \"{word}\" not found in the dictionary.\n" + "New ambiguity class: {class}\n" + "Line Number: {line}\n" + "Take a look at the dictionary, then retrain."} + APER1105{"WARNING APER1105: A new ambiguity class was found. \n" + "Retraining the tagger is necessary so as to take it into account.\n" + "Word \"{word}\".\n" + "New ambiguity class: {class}"} + APER1106{"ERROR APER1106: reading map"} + APER1107{"ERROR APER1107: invalid argument \"{optarg}\" for \"--unigram\"\n" + "Valid arguments are:\n" + " - '1'\n" + " - '2'\n" + " - '3'"} + APER1108{"ERROR APER1108: invalid option -- \"{opt}\""} + APER1109{"ERROR APER1109: unexpected \"{opt1}\" following \"{opt2}\""} + APER1110{"ERROR APER1110: invalid argument \"{arg}\" for \"{opt}\""} + APER1111{"ERROR APER1111: can't convert {metavar} \"{val}\" to unsigned long"} + APER1112{"ERROR APER1112: can't convert {metavar} of size 1 to unsigned long"} + APER1113{"ERROR APER1113: can't convert {metavar} \"{val}\" to unsigned long, not in unsigned long range"} + APER1114{"ERROR APER1114: can't deserialise SERIALISED_TAGGER file \"{file}\" Reason: {what}"} + APER1115{"ERROR APER1115: no space in line"} + APER1116{"ERROR APER1116: too much data in line"} + APER1117{"ERROR APER1117: Batch mode requires exactly two file arguments."} + APER1118{"ERROR APER1118: -batch and -{arg} are incompatible switches."} + APER1119{"ERROR APER1119: -{arg} switch requires a filename value."} + APER1120{"ERROR APER1120: Nonbatch mode requires exactly three file arguments."} + APER1121{"ERROR APER1121: Batch file has incorrect format."} + APER1122{"ERROR APER1122: data error."} + APER1123{"ERROR APER1123: unimplemented."} + APER1124{"ERROR APER1124: argument error."} + APER1125{"ERROR APER1125: hopelessly bad trail."} + APER1126{"ERROR APER1126: unable to parse argument \"p\"."} + APER1127{"ERROR APER1127: Empty argument"} + APER1128{"ERROR APER1128: Argument -{arg}: integer expected."} + APER1129{"ERROR APER1129: Argument -{arg}: value is not allowed."} + APER1130{"ERROR APER1130: No value is allowed for argument -{arg}."} + APER1131{"ERROR APER1131: Invalid argument: "} + APER1132{"WARNING APER1132: conflict in tree"} + APER1133{"ERROR APER1133: Incorrect bicorpus file: {records} records in line {line}"} + APER1134{"ERROR APER1134: evalString() was called on a NULL element"} + APER1135{"ERROR APER1135: You must specify either 'name' or 'namefrom' for the 'chunk' element"} + APER1136{"WARNING APER1136: apertium-transfer: on line {line_number}: {tag} sometimes discards its value."} + APER1137{"ERROR APER1137: Transfer::processLet() bad access on pos >= lword"} + APER1138{"ERROR APER1138: Transfer::processLet() null access on word[pos]"} + APER1139{"ERROR APER1139: On line {line}: processCallMacro() number of arguments >= npar"} + APER1140{"ERROR APER1140: On line {line}, column {column}: missing attribute part."} + APER1141{"ERROR APER1141: On line {line}, column {column}: Undefined attr-item {part}."} + APER1142{"ERROR APER1142: On line {line}, column {column}: Undefined cat-item {attrib}."} + APER1143{"WARNING APER1143: On line {line}: assignment to 'sl' side has no effect."} + APER1144{"ERROR APER1144: On line {line}, column {column}: Macro \"{macro}\" defined at least twice"} + APER1145{"ERROR APER1145: On line {line}, column {column}: \"{tag}\" already defined."} + APER1146{"ERROR APER1146: On line {line}, column {column}: Unexpected \"{tag}\" open tag."} + APER1147{"ERROR APER1147: On line {line}, column {column}: tag expected."} + APER1148{"ERROR APER1148: can't serialise without first selecting a model."} + APER1149{"ERROR APER1149: can't read tagger without first selecting a model."} + APER1150{"ERROR APER1150: can't score analysis without first selecting a model."} + APER1151{"ERROR APER1151: can't train model without first selecting a model."} + APER1152{"ERROR APER1152: can't multiplyModel() without first selecting a model."} + APER1153{"ERROR APER1153: can't train LexicalUnit comprising empty Analysis std::vector."} + APER1154{"WARNING APER1154: tf-apertium-spread: Null-flush found, but had open word-bound blanks on line {line}:"} + APER1155{"WARNING APER1155: tf-apertium-spread: Too many [[/]] on line {line}:"} + APER1156{"WARNING APER1156: tf-apertium-spread: End of input reached, but had an open blank."} + APER1157{"ERROR APER1157: On line {line}, column {column}: unexpected EOF."} + APER1158{"ERROR APER1158: Install an UTF-8 locale in your system."} + APER1159{"ERROR APER1159: Input seems to be non-UTF-8, please convert to UTF-8 (e.g. with \"iconv -f {encoding} -t utf-8\")."} + APER1160{"ERROR APER1160: APERTIUM_TRANSFUSE={APERTIUM_TRANSFUSE} but couldn't find Transfuse's tf-extract in PATH."} + APER1161{"ERROR APER1161: Install \"{command}\" command in your system."} + APER1162{"ERROR APER1162: {opt} requires an argument."} + APER1163{"ERROR APER1163: Cannot compile TM {file}\n" + " hint: use -o parameter"} + APER1164{"ERROR APER1164: Directory \"{directory}\" does not exist."} + APER1165{"ERROR APER1165: Mode {mode} does not exist."} + APER1166{"ERROR APER1166: Install a ISO-8859-1 compatible locale in your system."} + APER1167{"WARNING APER1167: {arg}: Unknown format {format}, treating as \"txt\"."} + APER1168{"ERROR APER1168: some unknown failed assertion..."} + APER1169{"ERROR APER1169: Align failed for {file}"} +}