commit 29ed063f0119ecacd9a15bf22d4cf12af7a9a9b5 Author: Ahmed Siam Date: Mon Jul 10 18:52:56 2023 +0300 i18n of lttoolbox patch 2 diff --git a/locales/root.txt b/locales/root.txt index eb2bf09..3631776 100644 --- a/locales/root.txt +++ b/locales/root.txt @@ -29,6 +29,55 @@ root{ usage{"USAGE: "} version{" version "} + + lt_append_desc{"add sections to a compiled transducer"} + keep_desc{"in case of section name conflicts, keep the one from the first transducer"} + single_desc{"treat input transducers as one-sided"} + + lt_apply_acx_desc{"apply an ACX file to a compiled transducer"} + + lt_comp_desc{"build a letter transducer from a dictionary"} + debug_desc{"insert line numbers before each entry"} + keep_boundaries_desc{"keep morpheme boundaries"} + var_desc{"set language variant"} + alt_desc{"set alternative (monodix)"} + var_left_desc{"set left language variant (bidix)"} + var_right_desc{"set right language variant (bidix)"} + expect_hfst_desc{"expect HFST symbols"} + no_split_desc{"don't attempt to split into word and punctuation sections"} + jobs_desc{"use one cpu core per section when minimising, new section after 50k entries"} + verbose_desc{"compile verbosely"} + + lt_compose_desc{"compose transducer1 with transducer2"} + inverted_desc{"run composition right-to-left on transducer1"} + anywhere_desc{"don't require anchored matches, let transducer2 optionally compose at any sub-path"} + + lt_expand{"expand the contents of a dictionary file"} + lt_invert_desc{"reverse the direction of a compiled transducer"} + + lt_paradigm_desc{"generate listings from a compiled transducer"} + analyser_desc{"FST is an analyser (tags on the right)"} + exclude_desc{"disregard paths containing TAG"} + sort_desc{"alphabetize the paths for each pattern"} + + lt_print_desc{"dump a transducer to text in ATT format"} + alpha_desc{"print transducer alphabet"} + use_hfst_desc{"use HFST-compatible character escapes"} + + lt_restrict_desc{"remove paths from a transducer"} + minimise_desc{"minimise transducers after deleting paths"} + + lt_tmxcomp_desc{"build a letter transducer from a TMX translation memory"} + origin_code_desc{"the language code to be taken as lang1"} + meta_code_desc{"the language code to be taken as lang2"} + input_language{"input language"} + output_language{"output language"} + + lt_tmxproc_desc{"process a stream with a letter transducer"} + + lt_trim_desc{"trim a transducer to another transducer"} + match_section_desc{"A section with this name (id@type) will only be trimmed against a section with the same name. This argument may be used multiple times."} + LTTB1000{"ERROR LTTB1000: Invalid or no argument for {option}"} LTTB1001{"ERROR LTTB1001: In {node_doc_url} on line {line_number}: Missing value attribute."} LTTB1002{"ERROR LTTB1002: In {node_doc_url} on line {line_number}: Expected a single character in value attribute, but found {value_size}."} @@ -50,7 +99,7 @@ root{ LTTB1018{"ERROR LTTB1018: On line {line_number}: Invalid specification of element \"<{name}>\" in this context."} LTTB1019{"ERROR LTTB1019: On line {line_number}: Invalid construction."} LTTB1020{"ERROR LTTB1020: On line {line_number}: Expected \"<{slash_element}>\"."} - LTTB1021{"ERROR LTTB1021: On line {line_number}: Entry begins with space."} + LTTB1021{"WARNING LTTB1021: On line {line_number}: Entry begins with space."} LTTB1022{"ERROR LTTB1022: On line {line_number}: Paradigm refers to itself \"{paradigm_name}\"."} LTTB1023{"ERROR LTTB1023: On line {line_number}: Undefined paradigm \"{paradigm_name}\"."} LTTB1024{"ERROR LTTB1024: On line {line_number}: Invalid entry token."} @@ -58,4 +107,39 @@ root{ LTTB1026{"ERROR LTTB1026: On line {line_number}: Parse error."} LTTB1027{"ERROR LTTB1027: On line {line_number}: Invalid inclusion of \"<{element_name}>\" into \"<{compiler_entry_element}>\"."} LTTB1028{"ERROR LTTB1028: On line {line_number}: Invalid node \"<{element_name}>\"."} + LTTB1029{"ERROR LTTB1029: I/O Error writing."} + LTTB1030{"ERROR LTTB1030: Out of range: {value}."} + LTTB1031{"ERROR LTTB1031: Can't access file {file_name}."} + LTTB1032{"WARNING LTTB1032: Matching case-sensitively since processor state size >= {max_case_insensitive_state_size}"} + LTTB1033{"ERROR LTTB1033: Unsupported transducer type for \"{transducer_first}\"."} + LTTB1034{"WARNING LTTB1034: CompoundAnalysis's MAX_COMBINATIONS exceeded for \"{input_word}\"\n" + " gave up at char {index} \"{char}\"."} + LTTB1035{"WARNING LTTB1035: Decomposition symbol {symbol} not found."} + LTTB1036{"ERROR LTTB1036: Unable to rewind file."} + LTTB1037{"ERROR LTTB1037: Unexpected trailing backslash."} + LTTB1038{"WARNING LTTB1038: section \"{section}\" appears in both transducers and will be overwritten!"} + LTTB1039{"ERROR LTTB1039: -l specified, but mode is lr."} + LTTB1040{"ERROR LTTB1040: -r specified, but mode is rl."} + LTTB1041{"WARNING LTTB1041: section {section_name} is empty! Skipping it..."} + LTTB1042{"WARNING LTTB1042: section {section_name} had no final state after composing! Skipping it..."} + LTTB1043{"ERROR LTTB1043: Composition gave empty transducer!"} + LTTB1044{"WARNING LTTB1044: unsupported locale, fallback to \"C\""} + LTTB1045{"WARNING LTTB1045: section {section_name} was not found in both transducers! Skipping if in just one..."} + LTTB1046{"ERROR LTTB1046: Trimming gave empty transducer!\n" + "Hint: There are no words in bilingual dictionary that match words in both monolingual dictionaries?"} + LTTB1047{"ERROR LTTB1047: Opening an unended sequence."} + LTTB1048{"ERROR LTTB1048: Ending an unopened sequence."} + LTTB1049{"ERROR LTTB1049: Using labels outside of a sequence."} + LTTB1050{"ERROR LTTB1050: Parsing regexp."} + LTTB1051{"ERROR LTTB1051: Unable to lowercase string \"{string}\".\n" + "Error code: {error_name}"} + LTTB1052{"ERROR LTTB1052: Unable to uppercase string \"{string}\".\n" + "Error code: {error_name}"} + LTTB1053{"ERROR LTTB1053: Unable to titlecase string \"{string}\".\n" + "Error code: {error_name}"} + LTTB1054{"ERROR LTTB1054: Caseless string comparison failed on \"{string_a}\" and \"{string_b}\".\n" + "Error code: {error_name}"} + LTTB1055{"ERROR LTTB1055: Trying to link nonexistent states ({source}, {target}, {tag})."} + LTTB1056{"ERROR LTTB1056: Empty set of final states."} + LTTB1057{"ERROR LTTB1057: Couldn't find {f_src}, {g_src} in state map."} } diff --git a/lttoolbox/acx.cc b/lttoolbox/acx.cc index 4a46834..60c4f28 100644 --- a/lttoolbox/acx.cc +++ b/lttoolbox/acx.cc @@ -29,18 +29,14 @@ int32_t get_val(xmlNode* node) I18n i18n {LOCALES_DATA}; UString s = getattr(node, VALUE_ATTR); if (s.empty()) { - //error_and_die(node, i18n.format("LTTB1001")); - std::cerr << i18n.format("LTTB1001", {"node_doc_url", "line_number"}, - {(char*)node->doc->URL, node->line}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1001", {"node_doc_url", "line_number"}, + {(char*)node->doc->URL, node->line}, true); } std::vector v; ustring_to_vec32(s, v); if (v.size() > 1) { - //error_and_die(node, i18n.format("LTTB1002"), v.size()); - std::cerr << i18n.format("LTTB1002", {"node_doc_url", "line_number", "value_size"}, - {(char*)node->doc->URL, node->line, std::to_string(v.size()).c_str()}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1002", {"node_doc_url", "line_number", "value_size"}, + {(char*)node->doc->URL, node->line, std::to_string(v.size()).c_str()}, true); } return v[0]; } @@ -52,23 +48,15 @@ std::map> readACX(const char* file) xmlNode* top_node = load_xml(file); for (auto char_node : children(top_node)) { if (!xmlStrEqual(char_node->name, CHAR_NODE)) { - //error_and_die(char_node, i18n.format("LTTB1003"), - // (const char*)char_node->name); - std::cerr << i18n.format("LTTB1003", {"node_doc_url", "line_number", "node_name"}, - {(char*)char_node->doc->URL, char_node->line, (const char*)char_node->name}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1003", {"node_doc_url", "line_number", "node_name"}, + {(char*)char_node->doc->URL, char_node->line, (const char*)char_node->name}, true); } int32_t key = get_val(char_node); sorted_vector vec; for (auto equiv_node : children(char_node)) { if (!xmlStrEqual(equiv_node->name, EQUIV_NODE)) { - //error_and_die(char_node, i18n.format("LTTB1004"), - // (const char*)equiv_node->name); - std::cerr << i18n.format("LTTB1004", {"node_doc_url", "line_number", "node_name"}, - {(char*)char_node->doc->URL, char_node->line, (const char*)equiv_node->name}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1004", {"node_doc_url", "line_number", "node_name"}, + {(char*)char_node->doc->URL, char_node->line, (const char*)equiv_node->name}, true); } vec.insert(get_val(equiv_node)); } diff --git a/lttoolbox/att_compiler.cc b/lttoolbox/att_compiler.cc index 02643ec..de786ab 100644 --- a/lttoolbox/att_compiler.cc +++ b/lttoolbox/att_compiler.cc @@ -150,7 +150,7 @@ AttCompiler::parse(std::string const &file_name, bool read_rl) UFILE* infile = u_fopen(file_name.c_str(), "r", NULL, NULL); if (infile == NULL) { - std::cerr << i18n.format("LTTB1005", {"file_name"}, {file_name.c_str()}) << std::endl; + i18n.error("LTTB1005", {"file_name"}, {file_name.c_str()}, false); } std::vector tokens; bool first_line_in_fst = true; // First line -- see below @@ -187,15 +187,14 @@ AttCompiler::parse(std::string const &file_name, bool read_rl) if (first_line_in_fst && tokens.size() == 1) { - std::cerr << i18n.format("LTTB1006", {"file_name", "line_number"}, {file_name.c_str(), line_number}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1006", {"file_name", "line_number"}, {file_name.c_str(), line_number}, true); } if (tokens[0].find('-') == 0) { if (state_id_offset == 1) { // this is the first split we've seen - std::cerr << i18n.format("LTTB1007", {"file_name"}, {file_name.c_str()}) << std::endl; + i18n.error("LTTB1007", {"file_name"}, {file_name.c_str()}, false); multiple_transducers = true; } // Update the offset for the new FST @@ -423,8 +422,7 @@ TransducerType AttCompiler::classify_backwards(int state, std::set& path) { if(finals.find(state) != finals.end()) { - std::cerr << i18n.format("LTTB1008") << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1008", {}, {}, true); } AttNode* node = get_node(state); TransducerType type = UNDECIDED; @@ -432,8 +430,7 @@ AttCompiler::classify_backwards(int state, std::set& path) if(t1.type != UNDECIDED) { type |= t1.type; } else if(path.find(t1.to) != path.end()) { - std::cerr << i18n.format("LTTB1009") << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1009", {}, {}, true); } else { path.insert(t1.to); t1.type = classify_backwards(t1.to, path); diff --git a/lttoolbox/buffer.h b/lttoolbox/buffer.h index 5a6c46b..be1e0c6 100644 --- a/lttoolbox/buffer.h +++ b/lttoolbox/buffer.h @@ -75,8 +75,7 @@ public: I18n i18n {LOCALES_DATA}; if(buf_size == 0) { - std::cerr << i18n.format("LTTB1010") << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1010", {}, {}, true); } buf = new T[buf_size]; size = buf_size; diff --git a/lttoolbox/compiler.cc b/lttoolbox/compiler.cc index f2f1515..c78423a 100644 --- a/lttoolbox/compiler.cc +++ b/lttoolbox/compiler.cc @@ -63,7 +63,7 @@ Compiler::parse(std::string const &file, UStringView dir) if(ret != 0) { - std::cerr << i18n.format("LTTB1011") << std::endl; + i18n.error("LTTB1011", {}, {}, true); } xmlFreeTextReader(reader); @@ -121,11 +121,11 @@ Compiler::valid(UStringView dir) const auto initial = fst.getInitial(); for(const auto i : fst.closure(initial, epsilonSymbols)) { if (finals.count(i)) { - std::cerr << i18n.format("LTTB1012", {"side"}, {side}) << std::endl; + i18n.error("LTTB1012", {"side"}, {side}, false); return false; } if(fst.closure(i, spaceSymbols).size() > 1) { // >1 since closure always includes self - std::cerr << i18n.format("LTTB1013", {"side"}, {side}) << std::endl; + i18n.error("LTTB1013", {"side"}, {side}, false); return false; } } @@ -160,8 +160,7 @@ Compiler::procAlphabet() } else { - std::cerr << i18n.format("LTTB1014", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1014", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } } } @@ -275,7 +274,7 @@ Compiler::matchTransduction(std::vector const &pi, // rl compilation of a badly written rule // having an epsilon with wildcard output will produce // garbage output -- see https://github.com/apertium/apertium-separable/issues/8 - std::cerr << i18n.format("LTTB1015") << std::endl; + i18n.error("LTTB1015", {}, {}, false); } else if (tag == alphabet(any_tag, any_tag) || tag == alphabet(any_char, any_char) || tag == alphabet(any_tag, 0) || @@ -304,9 +303,8 @@ Compiler::requireEmptyError(UStringView name) { if(!xmlTextReaderIsEmptyElement(reader)) { - std::cerr << i18n.format("LTTB1016", {"line_number", "name"}, {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1016", {"line_number", "name"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}, true); } } @@ -361,10 +359,8 @@ Compiler::readString(std::vector &result, UStringView name) if(!alphabet.isSymbolDefined(symbol)) { - std::cerr << i18n.format("LTTB1017", {"line_number", "symbol"}, - {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(symbol.data())}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1017", {"line_number", "symbol"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(symbol.data())}, true); } result.push_back(alphabet(symbol)); @@ -390,9 +386,8 @@ Compiler::readString(std::vector &result, UStringView name) } else { - std::cerr << i18n.format("LTTB1018", {"line_number", "name"}, {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1018", {"line_number", "name"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}, true); } } @@ -405,9 +400,7 @@ Compiler::skipBlanks(UString &name) { if(!allBlanks()) { - std::cerr << i18n.format("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } } @@ -434,9 +427,7 @@ Compiler::skip(UString &name, UStringView elem, bool open) { if(!allBlanks()) { - std::cerr << i18n.format("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } } xmlTextReaderRead(reader); @@ -445,11 +436,9 @@ Compiler::skip(UString &name, UStringView elem, bool open) if(name != elem) { - std::cerr << i18n.format("LTTB1020", {"line_number", "slash_element"}, - {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(slash.data()) + - icu::UnicodeString(elem.data())}) - << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1020", {"line_number", "slash_element"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(slash.data()) + + icu::UnicodeString(elem.data())}, true); } } @@ -476,8 +465,7 @@ Compiler::procIdentity(double const entry_weight, bool ig) if(verbose && first_element && (both_sides.front() == (int)' ')) { - std::cerr << i18n.format("LTTB1021", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) - << std::endl; + i18n.error("LTTB1021", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, false); } first_element = false; EntryToken e; @@ -520,7 +508,7 @@ Compiler::procTransduction(double const entry_weight) if(verbose && first_element && (lhs.front() == (int)' ')) { - std::cerr << i18n.format("LTTB1021", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) << std::endl; + i18n.error("LTTB1021", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, false); } first_element = false; @@ -563,20 +551,16 @@ Compiler::procPar() if(!current_paradigm.empty() && paradigm_name == current_paradigm) { - std::cerr << i18n.format("LTTB1022", {"line_number", "paradigm_name"}, + i18n.error("LTTB1022", {"line_number", "paradigm_name"}, {xmlTextReaderGetParserLineNumber(reader), - icu::UnicodeString(paradigm_name.data())}) - << std::endl; - exit(EXIT_FAILURE); + icu::UnicodeString(paradigm_name.data())}, true); } if(paradigms.find(paradigm_name) == paradigms.end()) { - std::cerr << i18n.format("LTTB1023", {"line_number", "paradigm_name"}, + i18n.error("LTTB1023", {"line_number", "paradigm_name"}, {xmlTextReaderGetParserLineNumber(reader), - icu::UnicodeString(paradigm_name.data())}) - << std::endl; - exit(EXIT_FAILURE); + icu::UnicodeString(paradigm_name.data())}, true); } e.setParadigm(paradigm_name); return e; @@ -611,8 +595,7 @@ Compiler::insertEntryTokens(std::vector const &elements) } else { - std::cerr << i18n.format("LTTB1024", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1024", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } } t.setFinal(e, default_weight); @@ -685,12 +668,10 @@ Compiler::requireAttribute(UStringView value, UStringView attrname, UStringView { if(value.empty()) { - std::cerr << i18n.format("LTTB1025", {"line_number", "element_name", "attr_name"}, + i18n.error("LTTB1025", {"line_number", "element_name", "attr_name"}, {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(elemname.data()), - icu::UnicodeString(attrname.data())}) - << std::endl; - exit(EXIT_FAILURE); + icu::UnicodeString(attrname.data())}, true); } } @@ -876,8 +857,7 @@ Compiler::procEntry() int ret = xmlTextReaderRead(reader); if(ret != 1) { - std::cerr << i18n.format("LTTB1026", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1026", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } UString name = XMLParseUtil::readName(reader); skipBlanks(name); @@ -915,11 +895,9 @@ Compiler::procEntry() auto it = paradigms.find(p); if(it == paradigms.end()) { - std::cerr << i18n.format("LTTB1023", {"line_number", "paradigm_name"}, + i18n.error("LTTB1023", {"line_number", "paradigm_name"}, {xmlTextReaderGetParserLineNumber(reader), - icu::UnicodeString(p.data())}) - << std::endl; - exit(EXIT_FAILURE); + icu::UnicodeString(p.data())}, true); } // discard entries with empty paradigms (by the directions, normally) if(it->second.isEmpty()) @@ -944,12 +922,10 @@ Compiler::procEntry() } else { - std::cerr << i18n.format("LTTB1027", {"line_number", "element_name", "compiler_entry_element"}, + i18n.error("LTTB1027", {"line_number", "element_name", "compiler_entry_element"}, {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data()), - icu::UnicodeString(COMPILER_ENTRY_ELEM.data())}) - << std::endl; - exit(EXIT_FAILURE); + icu::UnicodeString(COMPILER_ENTRY_ELEM.data())}, true); } } } @@ -1023,11 +999,9 @@ Compiler::procNode() } else { - std::cerr << i18n.format("LTTB1028", {"line_number", "element_name"}, + i18n.error("LTTB1028", {"line_number", "element_name"}, {xmlTextReaderGetParserLineNumber(reader), - icu::UnicodeString(name.data())}) - << std::endl; - exit(EXIT_FAILURE); + icu::UnicodeString(name.data())}, true); } } diff --git a/lttoolbox/compression.cc b/lttoolbox/compression.cc index 79970e6..70ce074 100644 --- a/lttoolbox/compression.cc +++ b/lttoolbox/compression.cc @@ -22,14 +22,16 @@ #include #include #include +#include +#include +#include void Compression::writeByte(unsigned char byte, FILE *output) { if(fwrite_unlocked(&byte, 1, 1, output) != 1) { - std::cerr << "I/O Error writing" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1029", {}, {}, true); } } @@ -40,8 +42,7 @@ Compression::readByte(FILE *input) if(fread_unlocked(&value, 1, 1, input) != 1) { // Not uncomment this code since -// std::cerr << "I/O Error reading" << std::endl; -// exit(EXIT_FAILURE); +// I18n(LOCALES_DATA).error("LTTB1029", {}, {}, true); } return value; @@ -87,8 +88,7 @@ Compression::multibyte_write(unsigned int value, FILE *output) } else { - std::cerr << "Out of range: " << value << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1030", {"value"}, {std::to_string(value).c_str()}, true); } } @@ -134,8 +134,7 @@ Compression::multibyte_write(unsigned int value, std::ostream &output) } else { - std::cerr << "Out of range: " << value << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1030", {"value"}, {std::to_string(value).c_str()}, true); } } diff --git a/lttoolbox/expander.cc b/lttoolbox/expander.cc index 3ead68c..9c75ded 100644 --- a/lttoolbox/expander.cc +++ b/lttoolbox/expander.cc @@ -22,6 +22,7 @@ #include #include #include +#include Expander::Expander() @@ -46,7 +47,7 @@ Expander::expand(std::string const &file, UFILE* output) if(ret != 0) { - std::cerr << "Error: Parse error at the end of input." << std::endl; + I18n(LOCALES_DATA).error("LTTB1011", {}, {}, false); } xmlFreeTextReader(reader); @@ -73,9 +74,8 @@ Expander::requireEmptyError(UStringView name) { if(!xmlTextReaderIsEmptyElement(reader)) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Non-empty element '<" << name << ">' should be empty." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1016", {"line_number", "name"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}, true); } } @@ -149,10 +149,8 @@ Expander::readString(UString &result, UStringView name) } else { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid specification of element '<" << name; - std::cerr << ">' in this context." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1018", {"line_number", "name"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}, true); } } @@ -163,9 +161,7 @@ Expander::skipBlanks(UString &name) { if(!allBlanks()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid construction." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } xmlTextReaderRead(reader); name = XMLParseUtil::readName(reader); @@ -182,9 +178,7 @@ Expander::skip(UString &name, UStringView elem) { if(!allBlanks()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid construction." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } xmlTextReaderRead(reader); name = XMLParseUtil::readName(reader); @@ -192,9 +186,8 @@ Expander::skip(UString &name, UStringView elem) if(name != elem) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Expected '<" << elem << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1020", {"line_number", "slash_element"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(elem.data())}, true); } } @@ -315,11 +308,10 @@ Expander::requireAttribute(UStringView value, UStringView attrname, UStringView { if(value.empty()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): '<" << elemname; - std::cerr << "' element must specify non-void '"; - std::cerr<< attrname << "' attribute." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1025", {"line_number", "element_name", "attr_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(elemname.data()), + icu::UnicodeString(attrname.data())}, true); } } @@ -347,9 +339,7 @@ Expander::procEntry(UFILE* output) int ret = xmlTextReaderRead(reader); if(ret != 1) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Parse error." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1026", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } myname = XMLParseUtil::readName(reader); } @@ -379,9 +369,7 @@ Expander::procEntry(UFILE* output) int ret = xmlTextReaderRead(reader); if(ret != 1) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Parse error." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1026", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } UString name = XMLParseUtil::readName(reader); skipBlanks(name); @@ -424,9 +412,9 @@ Expander::procEntry(UFILE* output) paradigm_lr.find(p) == paradigm_lr.end() && paradigm_rl.find(p) == paradigm_rl.end()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Undefined paradigm '" << p << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1023", {"line_number", "paradigm_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(p.data())}, true); } if(attribute == Compiler::COMPILER_RESTRICTION_LR_VAL) @@ -506,10 +494,10 @@ Expander::procEntry(UFILE* output) } else { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid inclusion of '<" << name << ">' into '<" << Compiler::COMPILER_ENTRY_ELEM; - std::cerr << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1027", {"line_number", "element_name", "compiler_entry_element"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(name.data()), + icu::UnicodeString(Compiler::COMPILER_ENTRY_ELEM.data())}, true); } } } @@ -563,9 +551,9 @@ Expander::procNode(UFILE *output) } else { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid node '<" << name << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1028", {"line_number", "element_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(name.data())}, true); } } diff --git a/lttoolbox/file_utils.cc b/lttoolbox/file_utils.cc index 2a6907c..b618360 100644 --- a/lttoolbox/file_utils.cc +++ b/lttoolbox/file_utils.cc @@ -19,6 +19,8 @@ #include #include +#include +#include UFILE* openOutTextFile(const std::string& fname) @@ -28,8 +30,7 @@ openOutTextFile(const std::string& fname) } else { UFILE* ret = u_fopen(fname.c_str(), "wb", NULL, NULL); if (!ret) { - std::cerr << "Error: Cannot open file '" << fname << "' for writing." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1031", {"file_name"}, {fname.c_str()}, true); } return ret; } @@ -43,8 +44,7 @@ openOutBinFile(const std::string& fname) } else { FILE* ret = fopen(fname.c_str(), "wb"); if (!ret) { - std::cerr << "Error: Cannot open file '" << fname << "' for writing." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1031", {"file_name"}, {fname.c_str()}, true); } return ret; } @@ -58,8 +58,7 @@ openInBinFile(const std::string& fname) } else { FILE* ret = fopen(fname.c_str(), "rb"); if (!ret) { - std::cerr << "Error: Cannot open file '" << fname << "' for reading." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1031", {"file_name"}, {fname.c_str()}, true); } return ret; } diff --git a/lttoolbox/fst_processor.cc b/lttoolbox/fst_processor.cc index 198d2be..38248b9 100644 --- a/lttoolbox/fst_processor.cc +++ b/lttoolbox/fst_processor.cc @@ -62,8 +62,7 @@ FSTProcessor::parseICX(std::string const &file) reader = xmlReaderForFile(file.c_str(), NULL, 0); if(reader == NULL) { - std::cerr << "Error: cannot open '" << file << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1031", {"file_name"}, {icu::UnicodeString(file.c_str())}, true); } int ret = xmlTextReaderRead(reader); while(ret == 1) @@ -87,8 +86,7 @@ FSTProcessor::parseRCX(std::string const &file) reader = xmlReaderForFile(file.c_str(), NULL, 0); if(reader == NULL) { - std::cerr << "Error: cannot open '" << file << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1031", {"file_name"}, {icu::UnicodeString(file.c_str())}, true); } int ret = xmlTextReaderRead(reader); while(ret == 1) @@ -121,9 +119,9 @@ FSTProcessor::procNodeICX() } else { - std::cerr << "Error in ICX file (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid node '<" << name << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1028", {"line_number", "element_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(name.data())}, true); } } @@ -159,9 +157,9 @@ FSTProcessor::procNodeRCX() } else { - std::cerr << "Error in RCX file (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid node '<" << name << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1028", {"line_number", "element_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(name.data())}, true); } } @@ -667,9 +665,7 @@ FSTProcessor::classifyFinals() } else { - std::cerr << "Error: Unsupported transducer type for '"; - std::cerr << it.first << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1033", {"transducer_first"}, {icu::UnicodeString(it.first.data())}, true); } } } @@ -908,8 +904,9 @@ FSTProcessor::compoundAnalysis(UString input_word) if(current_state.size() > MAX_COMBINATIONS) { - std::cerr << "Warning: compoundAnalysis's MAX_COMBINATIONS exceeded for '" << input_word << "'" << std::endl; - std::cerr << " gave up at char " << i << " '" << val << "'." << std::endl; + I18n(LOCALES_DATA).error("LTTB1034", {"input_word", "index", "char"}, + {icu::UnicodeString(input_word.data()), + (int)i, val}, false); UString nullString; return nullString; @@ -942,7 +939,7 @@ FSTProcessor::initDecompositionSymbols() && (compoundOnlyLSymbol=alphabet(u"<@compound:only-L>")) == 0 && (compoundOnlyLSymbol=alphabet(u"")) == 0) { - std::cerr << "Warning: Decomposition symbol <:compound:only-L> not found" << std::endl; + I18n(LOCALES_DATA).error("LTTB1035", {"symbol"}, {"<:compound:only-L>"}, false); } else if(!showControlSymbols) { @@ -955,7 +952,7 @@ FSTProcessor::initDecompositionSymbols() && (compoundRSymbol=alphabet(u"<@compound:R>")) == 0 && (compoundRSymbol=alphabet(u"")) == 0) { - std::cerr << "Warning: Decomposition symbol <:compound:R> not found" << std::endl; + I18n(LOCALES_DATA).error("LTTB1035", {"symbol"}, {"<:compound:R>"}, false); } else if(!showControlSymbols) { @@ -2327,7 +2324,7 @@ FSTProcessor::valid() const { if(initial_state.isFinal(all_finals)) { - std::cerr << "Error: Invalid dictionary (hint: the left side of an entry is empty)" << std::endl; + I18n(LOCALES_DATA).error("LTTB1012", {"side"}, {"left"}, false); return false; } else @@ -2336,7 +2333,7 @@ FSTProcessor::valid() const s.step(' '); if(s.size() != 0) { - std::cerr << "Error: Invalid dictionary (hint: entry beginning with whitespace)" << std::endl; + I18n(LOCALES_DATA).error("LTTB1013", {"side"}, {"left"}, false); return false; } } diff --git a/lttoolbox/fst_processor.h b/lttoolbox/fst_processor.h index f9476c1..16dcde8 100644 --- a/lttoolbox/fst_processor.h +++ b/lttoolbox/fst_processor.h @@ -34,6 +34,7 @@ #include #include #include +#include /** * Kind of output of the generator module @@ -460,8 +461,8 @@ private: else { if(!max_case_insensitive_state_size_warned) { max_case_insensitive_state_size_warned = true; // only warn once - UFILE* err_out = u_finit(stderr, NULL, NULL); - u_fprintf(err_out, "Warning: matching case-sensitively since processor state size >= %d\n", max_case_insensitive_state_size); + I18n(LOCALES_DATA).error("LTTB1032", {"max_case_insensitive_state_size"}, + {std::to_string(max_case_insensitive_state_size).c_str()}, false); } return true; } diff --git a/lttoolbox/input_file.cc b/lttoolbox/input_file.cc index cddb810..c95300b 100644 --- a/lttoolbox/input_file.cc +++ b/lttoolbox/input_file.cc @@ -22,6 +22,7 @@ #include #include #include +#include InputFile::InputFile() : infile(stdin), buffer_size(0) @@ -48,8 +49,7 @@ void InputFile::open_or_exit(const char* fname) { if (!open(fname)) { - std::cerr << "Error: Unable to open '" << fname << "' for reading." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1031", {"file_name"}, {fname}, true); } } @@ -150,8 +150,7 @@ InputFile::rewind() { if (infile != nullptr) { if (std::fseek(infile, 0, SEEK_SET) != 0) { - std::cerr << "Error: Unable to rewind file" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1036", {}, {}, true); } } } @@ -226,8 +225,7 @@ InputFile::readBlank(bool readwblank) ret += c; if (c == '\\') { if (eof() || peek() == '\0') { - std::cerr << "Unexpected trailing backslash" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1037", {}, {}, true); } ret += get(); } diff --git a/lttoolbox/lt_append.cc b/lttoolbox/lt_append.cc index a8358fb..ecd239a 100644 --- a/lttoolbox/lt_append.cc +++ b/lttoolbox/lt_append.cc @@ -19,14 +19,16 @@ #include #include #include +#include int main(int argc, char *argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("add sections to a compiled transducer", PACKAGE_VERSION); - cli.add_bool_arg('k', "keep", "in case of section name conflicts, keep the one from the first transducer"); - cli.add_bool_arg('s', "single", "treat input transducers as one-sided"); - cli.add_bool_arg('h', "help", "print this message and exit"); + CLI cli(i18n.format("lt_append_desc"), PACKAGE_VERSION); + cli.add_bool_arg('k', "keep", i18n.format("keep_desc")); + cli.add_bool_arg('s', "single", i18n.format("single_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.add_file_arg("bin_file1", false); cli.add_file_arg("bin_file2"); cli.add_file_arg("output_file"); @@ -56,7 +58,7 @@ int main(int argc, char *argv[]) if (keep) { continue; } else { - std::cerr << "WARNING: section '" << it.first << "' appears in both transducers and will be overwritten!" << std::endl; + i18n.error("LTTB1038", {"section"}, {icu::UnicodeString(it.first.data())}, false); } } it.second.updateAlphabet(alpha2, alpha1, pairs); diff --git a/lttoolbox/lt_apply_acx.cc b/lttoolbox/lt_apply_acx.cc index fa5d079..a1a2c99 100644 --- a/lttoolbox/lt_apply_acx.cc +++ b/lttoolbox/lt_apply_acx.cc @@ -20,11 +20,12 @@ #include #include #include +#include int main(int argc, char* argv[]) { LtLocale::tryToSetLocale(); - CLI cli("apply an ACX file to a compiled transducer", PACKAGE_VERSION); + CLI cli(I18n(LOCALES_DATA).format("lt_apply_acx_desc"), PACKAGE_VERSION); cli.add_file_arg("input_file", false); cli.add_file_arg("acx_file"); cli.add_file_arg("output_file"); diff --git a/lttoolbox/lt_comp.cc b/lttoolbox/lt_comp.cc index b9b9ed0..cad6b8b 100644 --- a/lttoolbox/lt_comp.cc +++ b/lttoolbox/lt_comp.cc @@ -21,6 +21,7 @@ #include #include +#include /* * Error function that does nothing so that when we fallback from @@ -34,19 +35,20 @@ void errorFunc(void *ctx, const char *msg, ...) int main(int argc, char *argv[]) { + I18n i18n(LOCALES_DATA); LtLocale::tryToSetLocale(); - CLI cli("build a letter transducer from a dictionary", PACKAGE_VERSION); - cli.add_bool_arg('d', "debug", "insert line numbers before each entry"); - cli.add_bool_arg('m', "keep-boundaries", "keep morpheme boundaries"); - cli.add_str_arg('v', "var", "set language variant", "VAR"); - cli.add_str_arg('a', "alt", "set alternative (monodix)", "ALT"); - cli.add_str_arg('l', "var-left", "set left language variant (bidix)", "VAR"); - cli.add_str_arg('r', "var-right", "set right language variant (bidix)", "VAR"); - cli.add_bool_arg('H', "hfst", "expect HFST symbols"); - cli.add_bool_arg('S', "no-split", "don't attempt to split into word and punctuation sections"); - cli.add_bool_arg('j', "jobs", "use one cpu core per section when minimising, new section after 50k entries"); - cli.add_bool_arg('V', "verbose", "compile verbosely"); - cli.add_bool_arg('h', "help", "print this message and exit"); + CLI cli(i18n.format("lt_comp_desc"), PACKAGE_VERSION); + cli.add_bool_arg('d', "debug", i18n.format("debug_desc")); + cli.add_bool_arg('m', "keep-boundaries", i18n.format("keep_boundaries_desc")); + cli.add_str_arg('v', "var", i18n.format("var_desc"), "VAR"); + cli.add_str_arg('a', "alt", i18n.format("alt_desc"), "ALT"); + cli.add_str_arg('l', "var-left", i18n.format("var_left_desc"), "VAR"); + cli.add_str_arg('r', "var-right", i18n.format("var_right_desc"), "VAR"); + cli.add_bool_arg('H', "hfst", i18n.format("expect_hfst_desc")); + cli.add_bool_arg('S', "no-split", i18n.format("no_split_desc")); + cli.add_bool_arg('j', "jobs", i18n.format("jobs_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("lr | rl | u", false); cli.add_file_arg("dictionary_file", false); cli.add_file_arg("output_file", false); @@ -116,8 +118,7 @@ int main(int argc, char *argv[]) } else { - std::cerr << "Error: Cannot not open file '" << infile << "'." << std::endl << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1031", {"file_name"}, {infile.c_str()}, true); } initGenericErrorDefaultFunc(NULL); @@ -125,7 +126,7 @@ int main(int argc, char *argv[]) if(opc == "lr") { if (have_vl) { - std::cerr << "Error: -l specified, but mode is lr" << std::endl; + i18n.error("LTTB1039", {}, {}, false); cli.print_usage(); } if(ttype == 'a') @@ -144,7 +145,7 @@ int main(int argc, char *argv[]) else if(opc == "rl") { if (have_vr) { - std::cerr << "Error: -r specified, but mode is rl" << std::endl; + i18n.error("LTTB1040", {}, {}, false); cli.print_usage(); } if(ttype == 'a') diff --git a/lttoolbox/lt_compose.cc b/lttoolbox/lt_compose.cc index 6ec365d..3e23fc9 100644 --- a/lttoolbox/lt_compose.cc +++ b/lttoolbox/lt_compose.cc @@ -21,10 +21,12 @@ #include #include #include +#include void compose(FILE* file_f, FILE* file_g, FILE* file_gf, bool f_inverted, bool g_anywhere, bool jobs) { + I18n i18n(LOCALES_DATA); Alphabet alph_f; std::set letters_f; std::map trans_f; @@ -49,7 +51,7 @@ compose(FILE* file_f, FILE* file_g, FILE* file_gf, bool f_inverted, bool g_anywh std::vector>> compositions; for (auto& it : trans_f) { if (it.second.numberOfTransitions() == 0) { - std::cerr << "Warning: section " << it.first << " is empty! Skipping it..." << std::endl; + i18n.error("LTTB1041", {"section_name"}, {icu::UnicodeString(it.first.data())}, false); continue; } if(jobs) { @@ -58,10 +60,7 @@ compose(FILE* file_f, FILE* file_g, FILE* file_gf, bool f_inverted, bool g_anywh bool f_inverted, bool g_anywhere, UString name) { Transducer gf = f.compose(g, alph_f, alph_g, f_inverted, g_anywhere); if (gf.hasNoFinals()) { - std::cerr << "Warning: section " << name - << " had no final state after composing! Skipping it..." - << std::endl; - ; + I18n(LOCALES_DATA).error("LTTB1042", {"section_name"}, {icu::UnicodeString(name.data())}, false); } else { gf.minimize(); } @@ -72,9 +71,7 @@ compose(FILE* file_f, FILE* file_g, FILE* file_gf, bool f_inverted, bool g_anywh } else { Transducer gf = it.second.compose(union_g, alph_f, alph_g, f_inverted, g_anywhere); if (gf.hasNoFinals()) { - std::cerr << "Warning: section " << it.first - << " had no final state after composing! Skipping it..." - << std::endl; + i18n.error("LTTB1042", {"section_name"}, {icu::UnicodeString(it.first.data())}, false); continue; } gf.minimize(); @@ -89,8 +86,7 @@ compose(FILE* file_f, FILE* file_g, FILE* file_gf, bool f_inverted, bool g_anywh } if (trans_gf.empty()) { - std::cerr << "Error: Composition gave empty transducer!" << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1043", {}, {}, true); } writeTransducerSet(file_gf, letters_f, alph_f, trans_gf); @@ -99,10 +95,11 @@ compose(FILE* file_f, FILE* file_g, FILE* file_gf, bool f_inverted, bool g_anywh int main(int argc, char *argv[]) { + I18n i18n(LOCALES_DATA); LtLocale::tryToSetLocale(); - CLI cli("compose transducer1 with transducer2", PACKAGE_VERSION); - cli.add_bool_arg('i', "inverted", "run composition right-to-left on transducer1"); - cli.add_bool_arg('a', "anywhere", "don't require anchored matches, let transducer2 optionally compose at any sub-path"); + CLI cli(i18n.format("lt_compose_desc"), PACKAGE_VERSION); + cli.add_bool_arg('i', "inverted", i18n.format("inverted_desc")); + cli.add_bool_arg('a', "anywhere", i18n.format("anywhere_desc")); cli.add_file_arg("transducer1_bin_file", false); cli.add_file_arg("transducer2_bin_file"); cli.add_file_arg("trimmed_bin_file"); diff --git a/lttoolbox/lt_expand.cc b/lttoolbox/lt_expand.cc index c472b77..5ef4666 100644 --- a/lttoolbox/lt_expand.cc +++ b/lttoolbox/lt_expand.cc @@ -19,16 +19,18 @@ #include #include #include +#include int main(int argc, char *argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("expand the contents of a dictionary file", PACKAGE_VERSION); - cli.add_bool_arg('m', "keep-boundaries", "keep morpheme boundaries"); - cli.add_str_arg('v', "var", "set language variant", "VAR"); - cli.add_str_arg('a', "alt", "set alternative (monodix)", "ALT"); - cli.add_str_arg('l', "var-left", "set left language variant (bidix)", "VAR"); - cli.add_str_arg('r', "var-right", "set right language variant (bidix)", "VAR"); + CLI cli(i18n.format("lt_expand"), PACKAGE_VERSION); + cli.add_bool_arg('m', "keep-boundaries", i18n.format("keep_boundaries_desc")); + cli.add_str_arg('v', "var", i18n.format("var_desc"), "VAR"); + cli.add_str_arg('a', "alt", i18n.format("alt_desc"), "ALT"); + cli.add_str_arg('l', "var-left", i18n.format("var_left_desc"), "VAR"); + cli.add_str_arg('r', "var-right", i18n.format("var_right_desc"), "VAR"); cli.add_file_arg("dictionary_file", false); cli.add_file_arg("output_file"); cli.parse_args(argc, argv); diff --git a/lttoolbox/lt_invert.cc b/lttoolbox/lt_invert.cc index bbe5584..03ddae9 100644 --- a/lttoolbox/lt_invert.cc +++ b/lttoolbox/lt_invert.cc @@ -18,13 +18,15 @@ #include #include #include +#include int main(int argc, char* argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("reverse the direction of a compiled transducer", PACKAGE_VERSION); - cli.add_bool_arg('h', "help", "print this message and exit"); + CLI cli(i18n.format("lt_invert_desc"), PACKAGE_VERSION); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.add_file_arg("in_bin"); cli.add_file_arg("out_bin"); cli.parse_args(argc, argv); diff --git a/lttoolbox/lt_locale.cc b/lttoolbox/lt_locale.cc index 9ee16ad..886972e 100644 --- a/lttoolbox/lt_locale.cc +++ b/lttoolbox/lt_locale.cc @@ -24,6 +24,7 @@ #include #endif +#include void LtLocale::tryToSetLocale() @@ -45,8 +46,7 @@ LtLocale::tryToSetLocale() return; } - std::cerr << "Warning: unsupported locale, fallback to \"C\"" << std::endl; - + I18n(LOCALES_DATA).error("LTTB1044", {}, {}, false); setlocale(LC_ALL, "C"); #endif #ifdef __CYGWIN__ diff --git a/lttoolbox/lt_paradigm.cc b/lttoolbox/lt_paradigm.cc index 3639c29..7d5499e 100644 --- a/lttoolbox/lt_paradigm.cc +++ b/lttoolbox/lt_paradigm.cc @@ -26,6 +26,8 @@ #include +#include + void expand(Transducer& inter, int state, const std::set& past_states, const std::vector& syms, const Alphabet& alpha, UFILE* out, std::set>& outset) @@ -142,13 +144,14 @@ void process(UStringView pattern, std::map& trans, int main(int argc, char* argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("generate listings from a compiled transducer", PACKAGE_VERSION); - cli.add_bool_arg('a', "analyser", "FST is an analyser (tags on the right)"); - cli.add_str_arg('e', "exclude", "disregard paths containing TAG", "TAG"); - cli.add_bool_arg('s', "sort", "alphabetize the paths for each pattern"); - cli.add_bool_arg('z', "null-flush", "flush output on \\0"); - cli.add_bool_arg('h', "help", "show this help and exit"); + CLI cli(i18n.format("lt_paradigm_desc"), PACKAGE_VERSION); + cli.add_bool_arg('a', "analyser", i18n.format("analyser_desc")); + cli.add_str_arg('e', "exclude", i18n.format("exclude_desc"), "TAG"); + cli.add_bool_arg('s', "sort", i18n.format("sort_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("FST", false); cli.add_file_arg("input"); cli.add_file_arg("output"); diff --git a/lttoolbox/lt_print.cc b/lttoolbox/lt_print.cc index 6619530..2ec02a2 100644 --- a/lttoolbox/lt_print.cc +++ b/lttoolbox/lt_print.cc @@ -18,14 +18,16 @@ #include #include #include +#include int main(int argc, char *argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("dump a transducer to text in ATT format", PACKAGE_VERSION); - cli.add_bool_arg('a', "alpha", "print transducer alphabet"); - cli.add_bool_arg('H', "hfst", "use HFST-compatible character escapes"); - cli.add_bool_arg('h', "help", "print this message and exit"); + CLI cli(i18n.format("lt_print_desc"), PACKAGE_VERSION); + cli.add_bool_arg('a', "alpha", i18n.format("alpha_desc")); + cli.add_bool_arg('H', "hfst", i18n.format("use_hfst_desc")); + cli.add_bool_arg('h', "help", i18n.format("help_desc")); cli.add_file_arg("bin_file"); cli.add_file_arg("output_file"); cli.parse_args(argc, argv); diff --git a/lttoolbox/lt_proc.cc b/lttoolbox/lt_proc.cc index c064f83..33844ec 100644 --- a/lttoolbox/lt_proc.cc +++ b/lttoolbox/lt_proc.cc @@ -147,24 +147,21 @@ int main(int argc, char *argv[]) if (strs.find("analyses") != strs.end()) { int n = atoi(strs["analyses"].back().c_str()); if (n < 1) { - std::cerr << i18n.format("LTTB1000", {"option"}, {"analyses"}) << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1000", {"option"}, {"analyses"}, true); } fstp.setMaxAnalysesValue(n); } if (strs.find("weight-classes") != strs.end()) { int n = atoi(strs["weight-classes"].back().c_str()); if (n < 1) { - std::cerr << i18n.format("LTTB1000", {"option"}, {"weight-classes"})<< std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1000", {"option"}, {"weight-classes"}, true); } fstp.setMaxWeightClassesValue(n); } if (strs.find("compound-max-elements") != strs.end()) { // Test int n = atoi(strs["compound-max-elements"].back().c_str()); if (n < 1) { - std::cerr << i18n.format("LTTB1000", {"option"}, {"compound-max-elements"})<< std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1000", {"option"}, {"compound-max-elements"}, true); } fstp.setCompoundMaxElements(n); } diff --git a/lttoolbox/lt_restrict.cc b/lttoolbox/lt_restrict.cc index 0aef3b4..48b42eb 100644 --- a/lttoolbox/lt_restrict.cc +++ b/lttoolbox/lt_restrict.cc @@ -19,6 +19,7 @@ #include #include #include +#include void get_symbol(const std::string& s, Alphabet& alpha, const char* prefix, sorted_vector& vec) @@ -36,13 +37,15 @@ void get_symbol(const std::string& s, Alphabet& alpha, const char* prefix, int main(int argc, char* argv[]) { + I18n i18n {LOCALES_DATA}; + LtLocale::tryToSetLocale(); - CLI cli("remove paths from a transducer", PACKAGE_VERSION); - cli.add_bool_arg('m', "minimise", "minimise transducers after deleting paths"); - cli.add_str_arg('v', "var", "set language variant", "VAR"); - cli.add_str_arg('a', "alt", "set alternative (monodix)", "ALT"); - cli.add_str_arg('l', "var-left", "set left language variant (bidix)", "VAR"); - cli.add_str_arg('r', "var-right", "set right language variant (bidix)", "VAR"); + CLI cli(i18n.format("lt_restrict_desc"), PACKAGE_VERSION); + cli.add_bool_arg('m', "minimise", i18n.format("minimise_desc")); + cli.add_str_arg('v', "var", i18n.format("var_desc"), "VAR"); + cli.add_str_arg('a', "alt", i18n.format("alt_desc"), "ALT"); + cli.add_str_arg('l', "var-left", i18n.format("var_left_desc"), "VAR"); + cli.add_str_arg('r', "var-right", i18n.format("var_right_desc"), "VAR"); cli.add_file_arg("lr | rl", false); cli.add_file_arg("input_file"); cli.add_file_arg("output_file"); diff --git a/lttoolbox/lt_tmxcomp.cc b/lttoolbox/lt_tmxcomp.cc index 914f30a..dbdbfb2 100644 --- a/lttoolbox/lt_tmxcomp.cc +++ b/lttoolbox/lt_tmxcomp.cc @@ -21,24 +21,27 @@ #include #include #include +#include +#include void endProgram(char *name) { + I18n i18n {LOCALES_DATA}; if(name != NULL) { - std::cout << basename(name) << " v" << PACKAGE_VERSION <<": build a letter transducer from a TMX translation memory" << std::endl; + std::cout << basename(name) << " v" << PACKAGE_VERSION << ": " << i18n.format("lt_tmxcomp_desc") << std::endl; std::cout << "USAGE: " << basename(name) << " [OPTIONS] lang1-lang2 tmx_file output_file" << std::endl; std::cout << "Modes:" << std::endl; - std::cout << " lang1: input language" << std::endl; - std::cout << " lang2: output language" << std::endl; + std::cout << " lang1: " << i18n.format("input_language") << std::endl; + std::cout << " lang2: " << i18n.format("output_language") << std::endl; std::cout << "Options:" << std::endl; #if HAVE_GETOPT_LONG - std::cout << " -o, --origin-code code the language code to be taken as lang1" << std::endl; - std::cout << " -m, --meta-code code the language code to be taken as lang2" << std::endl; + std::cout << " -o, --origin-code code " << i18n.format("origin_code_desc") << std::endl; + std::cout << " -m, --meta-code code " << i18n.format("meta_code_desc") << std::endl; #else - std::cout << " -o code the language code to be taken as lang1" << std::endl; - std::cout << " -m code the language code to be taken as lang2" << std::endl; + std::cout << " -o code " << i18n.format("origin_code_desc") << std::endl; + std::cout << " -m code " << i18n.format("meta_code_desc") << std::endl; #endif } exit(EXIT_FAILURE); @@ -107,8 +110,7 @@ int main(int argc, char *argv[]) FILE *output = fopen(argv[argc-1], "wb"); if(!output) { - std::cerr << "Error: Cannot open file '" << argv[2] << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1005", {"file_name"}, {argv[2]}, true); } c.write(output); fclose(output); diff --git a/lttoolbox/lt_tmxproc.cc b/lttoolbox/lt_tmxproc.cc index 6347e3b..1055e8a 100644 --- a/lttoolbox/lt_tmxproc.cc +++ b/lttoolbox/lt_tmxproc.cc @@ -18,11 +18,13 @@ #include #include #include +#include int main(int argc, char *argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("process a stream with a letter transducer"); + CLI cli(i18n.format("lt_tmxproc_desc")); cli.add_file_arg("fst_file", false); cli.add_file_arg("input_file"); cli.add_file_arg("output_file"); diff --git a/lttoolbox/lt_trim.cc b/lttoolbox/lt_trim.cc index 2a18584..09e14d6 100644 --- a/lttoolbox/lt_trim.cc +++ b/lttoolbox/lt_trim.cc @@ -19,10 +19,13 @@ #include #include #include +#include +#include void trim(FILE* file_mono, FILE* file_bi, FILE* file_out, std::set match_sections) { + I18n i18n {LOCALES_DATA}; Alphabet alph_mono; std::set letters_mono; std::map trans_mono; @@ -66,7 +69,7 @@ trim(FILE* file_mono, FILE* file_bi, FILE* file_out, std::set match_sec for (auto& it : trans_mono) { if (it.second.numberOfTransitions() == 0) { - std::cerr << "Warning: section " << it.first << " is empty! Skipping it..." << std::endl; + i18n.error("LTTB1041", {"section_name"}, {icu::UnicodeString(it.first.data())}, false); continue; } if (moved_bi_transducers.count(it.first)) { @@ -79,21 +82,18 @@ trim(FILE* file_mono, FILE* file_bi, FILE* file_out, std::set match_sec alph_mono, alph_prefix); if (trimmed.hasNoFinals()) { - std::cerr << "Warning: section " << it.first << " had no final state after trimming! Skipping it..." << std::endl; + i18n.error("LTTB1042", {"section_name"}, {icu::UnicodeString(it.first.data())}, false); continue; } trimmed.minimize(); trans_trim[it.first] = trimmed; } for (const auto &name : sections_unmatched) { - std::cerr << "Warning: section " << name << " was not found in both transducers! Skipping if in just one..." << std::endl; + i18n.error("LTTB1045", {"section_name"}, {icu::UnicodeString(name.data())}, false); } if (trans_trim.empty()) { - std::cerr << "Error: Trimming gave empty transducer!" << std::endl; - std::cerr << "Hint: There are no words in bilingual dictionary that match " - "words in both monolingual dictionaries?" << std::endl; - exit(EXIT_FAILURE); + i18n.error("LTTB1046", {}, {}, true); } writeTransducerSet(file_out, letters_mono, alph_mono, trans_trim); @@ -102,12 +102,13 @@ trim(FILE* file_mono, FILE* file_bi, FILE* file_out, std::set match_sec int main(int argc, char *argv[]) { + I18n i18n {LOCALES_DATA}; LtLocale::tryToSetLocale(); - CLI cli("trim a transducer to another transducer", PACKAGE_VERSION); + CLI cli(i18n.format("lt_trim_desc"), PACKAGE_VERSION); cli.add_file_arg("analyser_bin_file", false); cli.add_file_arg("bidix_bin_file"); cli.add_file_arg("trimmed_bin_file"); - cli.add_str_arg('s', "match-section", "A section with this name (id@type) will only be trimmed against a section with the same name. This argument may be used multiple times.", "section_name"); + cli.add_str_arg('s', "match-section", i18n.format("match_section_desc"), "section_name"); cli.parse_args(argc, argv); auto strs = cli.get_strs(); diff --git a/lttoolbox/pattern_list.cc b/lttoolbox/pattern_list.cc index b476de3..6a007f4 100644 --- a/lttoolbox/pattern_list.cc +++ b/lttoolbox/pattern_list.cc @@ -21,6 +21,7 @@ #include #include +#include void PatternList::copy(PatternList const &o) @@ -76,8 +77,7 @@ PatternList::beginSequence() { if(sequence) { - std::cerr << "Error: opening an unended sequence" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1047", {}, {}, true); } sequence = true; sequence_data.clear(); @@ -88,8 +88,7 @@ PatternList::endSequence() { if(!sequence) { - std::cerr << "Error: ending an unopened sequence" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1048", {}, {}, true); } sequence = false; @@ -191,8 +190,7 @@ PatternList::insert(int id, int otherid) { if(!sequence) { - std::cerr << "Error: using labels outside of a sequence" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1049", {}, {}, true); } sequence_id = id; diff --git a/lttoolbox/regexp_compiler.cc b/lttoolbox/regexp_compiler.cc index 18c7bee..ecd385e 100644 --- a/lttoolbox/regexp_compiler.cc +++ b/lttoolbox/regexp_compiler.cc @@ -19,6 +19,7 @@ #include #include #include +#include #define FIN_FICHERO INT_MAX @@ -87,15 +88,13 @@ RegexpCompiler::isReserved(int const t) void RegexpCompiler::error() { - std::cerr << "Error parsing regexp" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1050", {}, {}, true); } void RegexpCompiler::errorConsuming(int const t) { - std::cerr << "Error parsing regexp" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1050", {}, {}, true); } void diff --git a/lttoolbox/string_utils.cc b/lttoolbox/string_utils.cc index 2635674..99f85db 100644 --- a/lttoolbox/string_utils.cc +++ b/lttoolbox/string_utils.cc @@ -5,6 +5,8 @@ #include #include #include +#include +#include UStringView StringUtils::trim(UStringView str) @@ -177,9 +179,8 @@ StringUtils::tolower(UStringView str) UErrorCode err = U_ZERO_ERROR; u_strToLower(buf, str.size()*2, str.data(), str.size(), NULL, &err); if (U_FAILURE(err)) { - std::cerr << "Error: unable to lowercase string '" << str << "'.\n"; - std::cerr << "error code: " << u_errorName(err) << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1051", {"string", "errer_name"}, + {icu::UnicodeString(str.data()), u_errorName(err)}, true); } return buf; } @@ -191,9 +192,8 @@ StringUtils::toupper(UStringView str) UErrorCode err = U_ZERO_ERROR; u_strToUpper(buf, str.size()*2, str.data(), str.size(), NULL, &err); if (U_FAILURE(err)) { - std::cerr << "Error: unable to uppercase string '" << str << "'.\n"; - std::cerr << "error code: " << u_errorName(err) << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1052", {"string", "errer_name"}, + {icu::UnicodeString(str.data()), u_errorName(err)}, true); } return buf; } @@ -205,9 +205,8 @@ StringUtils::totitle(UStringView str) UErrorCode err = U_ZERO_ERROR; u_strToTitle(buf, str.size()*2, str.data(), str.size(), NULL, NULL, &err); if (U_FAILURE(err)) { - std::cerr << "Error: unable to titlecase string '" << str << "'.\n"; - std::cerr << "error code: " << u_errorName(err) << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1053", {"string", "errer_name"}, + {icu::UnicodeString(str.data()), u_errorName(err)}, true); } return buf; } @@ -272,10 +271,9 @@ StringUtils::caseequal(UStringView a, UStringView b) UErrorCode err = U_ZERO_ERROR; int cmp = u_strCaseCompare(a.data(), a.size(), b.data(), b.size(), 0, &err); if (U_FAILURE(err)) { - std::cerr << "Error: caseless string comparison failed on '"; - std::cerr << a << "' and '" << b << "'" << std::endl; - std::cerr << "error code: " << u_errorName(err) << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1054", {"string_a", "string_b", "errer_name"}, + {icu::UnicodeString(a.data()), + icu::UnicodeString(b.data()), u_errorName(err)}, true); } return (cmp == 0); } diff --git a/lttoolbox/tmx_compiler.cc b/lttoolbox/tmx_compiler.cc index dee2fe1..49420d7 100644 --- a/lttoolbox/tmx_compiler.cc +++ b/lttoolbox/tmx_compiler.cc @@ -23,6 +23,7 @@ #include #include #include +#include TMXCompiler::TMXCompiler() : @@ -48,8 +49,7 @@ TMXCompiler::parse(std::string const &file, UStringView lo, UStringView lm) reader = xmlReaderForFile(file.c_str(), NULL, 0); if(reader == NULL) { - std::cerr << "Error: Cannot open '" << file << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1005", {"file_name"}, {file.c_str()}, true); } int ret = xmlTextReaderRead(reader); @@ -61,7 +61,7 @@ TMXCompiler::parse(std::string const &file, UStringView lo, UStringView lm) if(ret != 0) { - std::cerr << "Error: Parse error at the end of input." << std::endl; + I18n(LOCALES_DATA).error("LTTB1011", {}, {}, false); } xmlFreeTextReader(reader); @@ -76,9 +76,8 @@ TMXCompiler::requireEmptyError(UStringView name) { if(!xmlTextReaderIsEmptyElement(reader)) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Non-empty element '<" << name << ">' should be empty." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1016", {"line_number", "name"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(name.data())}, true); } } @@ -105,9 +104,7 @@ TMXCompiler::skipBlanks(UString &name) { if(!allBlanks()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid construction." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } } @@ -128,9 +125,7 @@ TMXCompiler::skip(UString &name, UStringView elem) { if(!allBlanks()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid construction." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1019", {"line_number"}, {xmlTextReaderGetParserLineNumber(reader)}, true); } } xmlTextReaderRead(reader); @@ -139,9 +134,8 @@ TMXCompiler::skip(UString &name, UStringView elem) if(name != elem) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Expected '<" << elem << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1020", {"line_number", "slash_element"}, + {xmlTextReaderGetParserLineNumber(reader), icu::UnicodeString(elem.data())}, true); } } @@ -156,11 +150,10 @@ TMXCompiler::requireAttribute(UStringView value, UStringView attrname, UStringVi { if(value.empty()) { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): '<" << elemname; - std::cerr << "' element must specify non-void '"; - std::cerr << attrname << "' attribute." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1025", {"line_number", "element_name", "attr_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(elemname.data()), + icu::UnicodeString(attrname.data())}, true); } } @@ -406,9 +399,9 @@ TMXCompiler::procNode() } else { - std::cerr << "Error (" << xmlTextReaderGetParserLineNumber(reader); - std::cerr << "): Invalid node '<" << name << ">'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1028", {"line_number", "element_name"}, + {xmlTextReaderGetParserLineNumber(reader), + icu::UnicodeString(name.data())}, true); } } diff --git a/lttoolbox/transducer.cc b/lttoolbox/transducer.cc index a7fe0cf..bd96389 100644 --- a/lttoolbox/transducer.cc +++ b/lttoolbox/transducer.cc @@ -25,6 +25,7 @@ #include #include #include +#include int @@ -169,9 +170,7 @@ Transducer::linkStates(int const source, int const target, } else { - std::cerr << "Error: Trying to link nonexistent states (" << source; - std::cerr << ", " << target << ", " << tag << ")" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1055", {"source", "target", "tag"}, {source, target, tag}, true); } } @@ -294,8 +293,7 @@ Transducer::joinFinals(int const epsilon_tag) } else if(finals.size() == 0) { - std::cerr << "Error: empty set of final states" << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1056",{}, {}, true); } } @@ -1094,8 +1092,7 @@ Transducer::trim(Transducer &trimmer, trimmer_preplus_next = trimmer_preplus; if(states_this_trimmed.find(current) == states_this_trimmed.end()) { - std::cerr <<"Error: couldn't find "< #include #include +#include xmlTextReaderPtr XMLParseUtil::open_or_exit(const char* fname) { xmlTextReaderPtr reader = xmlReaderForFile(fname, NULL, 0); if (reader == NULL) { - std::cerr << "Error: cannot open '" << fname << "' for reading." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1005", {"file_name"}, {fname}, true); } return reader; } diff --git a/lttoolbox/xml_walk_util.cc b/lttoolbox/xml_walk_util.cc index e4afe73..85c0a67 100644 --- a/lttoolbox/xml_walk_util.cc +++ b/lttoolbox/xml_walk_util.cc @@ -1,5 +1,6 @@ #include #include +#include children::children(xmlNode* node_) : node(node_), cur(node->children) @@ -59,8 +60,7 @@ load_xml(const char* fname) { xmlDoc* doc = xmlReadFile(fname, NULL, 0); if (doc == nullptr) { - std::cerr << "Error: Could not parse file '" << fname << "'." << std::endl; - exit(EXIT_FAILURE); + I18n(LOCALES_DATA).error("LTTB1005", {"file_name"}, {fname}, true); } return xmlDocGetRootElement(doc); }