diff --git a/.gitattributes b/.gitattributes index a4294f9dd..2cc693049 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,6 @@ *.jpeg filter=lfs diff=lfs merge=lfs -text *.svg filter=lfs diff=lfs merge=lfs -text + +# Steppable translations +res/translations/*.stp_strings linguist-generated=true linguist-language=Bash +res/translations/**/*.stp_localized linguist-generated=true linguist-language=Bash diff --git a/.vscode/settings.json b/.vscode/settings.json index 00e8426cb..c3f9896f5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "files.associations": { + ".cmake-format": "python", "array": "cpp", "string_view": "cpp", "any": "cpp", @@ -57,7 +58,8 @@ "streambuf": "cpp", "typeinfo": "cpp", "variant": "cpp", - "fstream": "cpp" + "fstream": "cpp", + "__node_handle": "cpp" }, "copyrightInserter.holder": "NWSOFT", "copyrightInserter.license": "mit", @@ -68,7 +70,6 @@ "editor.cursorBlinking": "smooth", "editor.cursorSmoothCaretAnimation": "on", "editor.cursorStyle": "line", - "clangd.path": "/usr/bin/clangd", "C_Cpp.clang_format_path": "clang-format-17", "C_Cpp.codeAnalysis.clangTidy.path": "clang-tidy-17", "files.exclude": { diff --git a/CMakeLists.txt b/CMakeLists.txt index 47810c83f..ea29d067e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ COMPONENTS Development Interpreter REQUIRED) SET(CMAKE_CXX_STANDARD 20) +SET(CMAKE_C_STANDARD 20) SET(CMAKE_CXX_EXTENSIONS OFF) SET(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -104,7 +105,7 @@ SET(COMPONENTS # NEW_COMPONENT: PATCH Do NOT remove the previous comment. SET(TARGETS ${COMPONENTS} util) -SET(TEST_TARGETS_TEMP util fraction number factors ${COMPONENTS}) +SET(TEST_TARGETS_TEMP util fraction number factors format ${COMPONENTS}) FOREACH(TEST_TARGET IN LISTS TEST_TARGETS_TEMP) SET(TARGET_NAME "test") diff --git a/doxygen-awesome-css b/doxygen-awesome-css index 5b27b3a74..40e9b25b6 160000 --- a/doxygen-awesome-css +++ b/doxygen-awesome-css @@ -1 +1 @@ -Subproject commit 5b27b3a747ca1e559fa54149762cca0bad6036fb +Subproject commit 40e9b25b6174dd3b472d8868f63323a870dfeeb8 diff --git a/include/argParse.hpp b/include/argParse.hpp index df6192392..50bbcf39a 100644 --- a/include/argParse.hpp +++ b/include/argParse.hpp @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include @@ -50,15 +50,15 @@ namespace steppable::__internals::utils { /// @brief This is the type of the positional arguments. It is equivalent to a vector of string_views. - using PosArgs = std::vector; + using PosArgs = std::vector; /// @brief This is the correct format of a keyword argument. // language=RegExp - [[maybe_unused]] const std::regex KEYWORD_ARG_REGEX(R"(^-([a-zA-Z]*):(-?[0-9]+)$)"); + [[maybe_unused]] const std::regex KEYWORD_ARG_REGEX(R"(^-([a-zA-Z]*):(-?[0-9]+)$)"); // NOLINT(cert-err58-cpp) /// @brief This is the correct format of a switch. // language=RegExp - [[maybe_unused]] const std::regex SWITCH_REGEX(R"(^([-+])([a-zA-Z]*)$)"); + [[maybe_unused]] const std::regex SWITCH_REGEX(R"(^([-+])([a-zA-Z]*)$)"); // NOLINT(cert-err58-cpp) /** * @class ProgramArgs @@ -82,14 +82,14 @@ namespace steppable::__internals::utils /** @brief This map is used to store the information of all switches specified. Keys are switch names, and * values are whether the switch is enabled. */ - std::unordered_map switches; + std::unordered_map switches; /// @brief This map is used to store the descriptions of all switches specified. - std::map switchDescriptions; + std::map switchDescriptions; /// @brief This vector is used to store the values of all positional arguments specified. - std::vector posArgs; // Names are used for error messages only. + std::vector posArgs; // Names are used for error messages only. /// @brief This map is used to store the descriptions of all positional arguments specified. - std::map posArgDescriptions; + std::map posArgDescriptions; /// @brief This map stores whether the positional arguments are required to be numbers. std::vector posArgIsNumber; @@ -97,18 +97,18 @@ namespace steppable::__internals::utils * @brief This map is used to store the values of all keyword arguments specified. Keys are keyword argument * names and values are the values of the keyword arguments. */ - std::unordered_map keywordArgs; + std::unordered_map keywordArgs; /// @brief This map is used to store the descriptions of all keyword arguments specified. - std::map keywordArgDescriptions; + std::map keywordArgDescriptions; /// @brief This stores the number of arguments passed to the program. int argc; /// @brief This stores the arguments passed to the program. - std::vector argv; + std::vector argv; /// @brief This stores the name of the program. - std::string_view programName; + std::string programName; public: /** @@ -133,7 +133,7 @@ namespace steppable::__internals::utils * @param[in] defaultValue The default value of the switch. True = enabled, False = disabled. * @param[in] description The description of the switch. */ - void addSwitch(const std::string_view& name, bool defaultValue, const std::string_view& description = ""); + void addSwitch(const std::string& name, bool defaultValue, const std::string& description = ""); /** * @brief This function is used to add a positional argument to the class. @@ -145,7 +145,7 @@ namespace steppable::__internals::utils * @note the command-line arguments. */ void addPosArg(char name, - const std::string_view& description = "", + const std::string& description = "", bool requiresNumber = true); // Positional arguments are always required and ordered /** @@ -154,7 +154,7 @@ namespace steppable::__internals::utils * @param[in] defaultValue The default value of the keyword argument. The value is stored as an integer. * @param[in] description The description of the keyword argument. */ - void addKeywordArg(const std::string_view& name, int defaultValue, std::string_view description = ""); + void addKeywordArg(const std::string& name, int defaultValue, const std::string& description = ""); /** * @brief This function is used to get the value of a positional argument. @@ -164,7 +164,7 @@ namespace steppable::__internals::utils * @note If the positional argument is not specified, the function will print an error message and exit the * program. */ - [[nodiscard]] std::string_view getPosArg(size_t index) const; + [[nodiscard]] std::string getPosArg(size_t index) const; /** * @brief This function is used to get the value of a keyword argument. @@ -174,7 +174,7 @@ namespace steppable::__internals::utils * @note If the keyword argument is not specified, the function will print an error message and exit the * program. */ - int getKeywordArgument(const std::string_view& name); + int getKeywordArgument(const std::string& name); /** * @brief This function is used to get the value of a switch. @@ -183,7 +183,7 @@ namespace steppable::__internals::utils * * @note If the switch is not specified, the function will print an error message and exit the program. */ - bool getSwitch(const std::string_view& name); + bool getSwitch(const std::string& name); /** * @brief This function is used to print the possible command-line arguments. Usually called when the user @@ -193,6 +193,6 @@ namespace steppable::__internals::utils * * @note The function will print the usage of the program and exit the program. */ - void printUsage(const std::string_view& reason = "") const; + void printUsage(const std::string& reason = "") const; }; } // namespace steppable::__internals::utils diff --git a/include/fn/basicArithm.hpp b/include/fn/basicArithm.hpp index a1e23de1f..9bd20ba79 100644 --- a/include/fn/basicArithm.hpp +++ b/include/fn/basicArithm.hpp @@ -39,7 +39,6 @@ #include "output.hpp" #include -#include using namespace std::literals; @@ -65,7 +64,7 @@ namespace steppable::__internals::arithmetic * @param[in] steps The number of steps to perform the calculation. * @return The absolute value of the number as a string. */ - std::string abs(const std::string_view& _number, int steps); + std::string abs(const std::string& _number, int steps); /** * @brief Adds two string representations of numbers, and performs with the column method. @@ -78,8 +77,8 @@ namespace steppable::__internals::arithmetic * @param[in] properlyFormat Flag indicating whether to properly format the output. Default true. * @return The sum of the two numbers as a string. */ - std::string add(const std::string_view& a, - const std::string_view& b, + std::string add(const std::string& a, + const std::string& b, int steps = 2, bool negative = false, bool properlyFormat = true); @@ -95,7 +94,7 @@ namespace steppable::__internals::arithmetic * "1" if a is greater than b, * "0" if a is less than b. */ - std::string compare(const std::string_view& _a, const std::string_view& _b, int steps = 2); + std::string compare(const std::string& _a, const std::string& _b, int steps = 2); /** * @brief Converts a string representation of a number from any base to decimal. @@ -105,7 +104,7 @@ namespace steppable::__internals::arithmetic * @param[in] steps The number of steps to perform the conversion. * @return The converted number as a string. */ - std::string decimalConvert(const std::string_view& _inputString, const std::string_view& baseString, int steps = 2); + std::string decimalConvert(const std::string& _inputString, const std::string& baseString, int steps = 2); /** * @brief Converts a string representation of a number from decimal to another one. @@ -115,7 +114,7 @@ namespace steppable::__internals::arithmetic * @param[in] steps The number of steps to perform the conversion. * @return The converted number as a string. */ - std::string baseConvert(const std::string_view& _number, const std::string_view& baseStr, int steps = 2); + std::string baseConvert(const std::string& _number, const std::string& baseStr, int steps = 2); /** * @brief Divides a string representation of a number by another string representation of a number. @@ -126,10 +125,7 @@ namespace steppable::__internals::arithmetic * @param[in] decimals The number of decimal places in the result. * @return The quotient of the division as a string. */ - std::string divide(const std::string_view& number, - const std::string_view& divisor, - int steps = 2, - int decimals = 5); + std::string divide(const std::string& number, const std::string& divisor, int steps = 2, int decimals = 5); /** * Calculates the quotient and remainder of dividing the current remainder by the divisor. @@ -148,7 +144,7 @@ namespace steppable::__internals::arithmetic * * @return The greatest common divisor of the two numbers. */ - std::string getGCD(const std::string_view& _a, const std::string_view& _b); + std::string getGCD(const std::string& _a, const std::string& _b); /** * @brief Multiplies two string representations of numbers. @@ -158,7 +154,7 @@ namespace steppable::__internals::arithmetic * @param[in] steps The number of steps to perform the multiplication. * @return The product of the two numbers as a string. */ - std::string multiply(const std::string_view& a, const std::string_view& b, int steps = 2); + std::string multiply(const std::string& a, const std::string& b, int steps = 2); /** * @brief Raises a string representation of a number to a power. @@ -168,7 +164,7 @@ namespace steppable::__internals::arithmetic * @param[in] steps The number of steps to perform the power operation. * @return The result of the power operation as a string. */ - std::string power(std::string_view _number, const std::string_view& raiseTo, int steps = 2); + std::string power(const std::string& _number, const std::string& raiseTo, int steps = 2); /** * @brief Subtracts one string representation of a number from another string representation of a number. @@ -179,7 +175,7 @@ namespace steppable::__internals::arithmetic * @param[in] noMinus Flag indicating whether to display a minus sign or not. * @return The difference between the two numbers as a string. */ - std::string subtract(const std::string_view& a, const std::string_view& b, int steps = 2, bool noMinus = false); + std::string subtract(const std::string& a, const std::string& b, int steps = 2, bool noMinus = false); /** * @brief Takes the n-th root of a numer. @@ -191,7 +187,7 @@ namespace steppable::__internals::arithmetic * * @return The result of the root operation. */ - std::string root(const std::string& _number, const std::string& base, size_t decimals = 8); + std::string root(const std::string& _number, const std::string& base, size_t decimals = 8, int steps = 0); /** * @brief Converts a root operation into a surd. @@ -540,7 +536,7 @@ namespace steppable::__internals::arithmetic * @param[in] predicate The predicate function to execute. */ template - void loop(const std::string_view& times, Pred predicate) + void loop(const std::string& times, Pred predicate) { // We're done already! if (times == "0") @@ -560,7 +556,7 @@ namespace steppable::__internals::arithmetic catch (std::exception& e) { output::error("loop", "Exception occurred in predicate."s); - output::error("loop", "Exception message: %s"s, e.what()); + output::error("loop", "Exception message: {0}"s, { e.what() }); } current = add(current, "1", 0); result = compare(current, times, 0); diff --git a/include/format.hpp b/include/format.hpp index bc2de6d3f..217b3da74 100644 --- a/include/format.hpp +++ b/include/format.hpp @@ -39,7 +39,6 @@ #pragma once -#include #include #include @@ -49,72 +48,5 @@ */ namespace steppable::__internals::format { - // https://stackoverflow.com/a/49812356/14868780 - /** - * @brief Formats a string using a variable number of arguments. - * - * This function takes a format string and a variable number of arguments, - * and returns a formatted string. It uses the same format specifiers as - * the standard library's `printf` function. - * - * @tparam CharT The character type of the string. - * @param[in] sFormat The format string. - * @param[in] ... The variable arguments. - * @return The formatted string. - */ - template - std::basic_string vFormat(const std::basic_string sFormat, ...) - { - const CharT* const zcFormat = sFormat.c_str(); - - // Initialize a variable argument array - va_list vaArgs; // NOLINT(cppcoreguidelines-init-variables) - va_start(vaArgs, sFormat); - - // Reliably acquire the size from a copy of the variable argument array - // and a functionally reliable call to mock the formatting - va_list vaCopy; // NOLINT(cppcoreguidelines-init-variables) - va_copy(vaCopy, vaArgs); - const int iLen = std::vsnprintf(nullptr, 0, zcFormat, vaCopy); - va_end(vaCopy); - - // Return a formatted string without risking memory mismanagement - // and without assuming any compiler or platform specific behavior - std::vector formatted(iLen + 1); - (void)std::vsnprintf(formatted.data(), formatted.size(), zcFormat, vaArgs); - va_end(vaArgs); - return std::string(formatted.data(), formatted.size()); - } - - /** - * @brief Formats a string using a format specifier and variable arguments. - * - * This function takes a format specifier and variable arguments, similar to the printf function, - * and returns a formatted string. The format specifier is a string that may contain placeholders - * for the variable arguments. The function uses the vsnprintf function to perform the formatting. - * - * @tparam CharT The character type of the string. - * @param[in] sFormat The format specifier string. - * @param[in] ... The variable arguments. - * @return The formatted string. - */ - template - std::basic_string vFormat(const CharT* sFormat, ...) - { - const CharT* const zcFormat = sFormat; - - va_list vaArgs; // NOLINT(cppcoreguidelines-init-variables) - va_start(vaArgs, sFormat); - - va_list vaCopy; // NOLINT(cppcoreguidelines-init-variables) - va_copy(vaCopy, vaArgs); - const int iLen = std::vsnprintf(nullptr, 0, zcFormat, vaCopy); // NOLINT(clang-diagnostic-format-nonliteral) - va_end(vaCopy); - - std::vector formatted(iLen + 1); - static_cast(std::vsnprintf( - formatted.data(), formatted.size(), zcFormat, vaArgs)); // NOLINT(clang-diagnostic-format-nonliteral) - va_end(vaArgs); - return std::string(formatted.data(), formatted.size()); - } + std::string format(const std::string& format, const std::vector& args); } // namespace steppable::__internals::format diff --git a/include/getString.hpp b/include/getString.hpp new file mode 100644 index 000000000..36e448980 --- /dev/null +++ b/include/getString.hpp @@ -0,0 +1,54 @@ +/************************************************************************************************** + * Copyright (c) 2023-2024 NWSOFT * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **************************************************************************************************/ + +#pragma once + +#include +#include + +namespace steppable::localization +{ + /** + * @brief Gets a string from origin, and by the key. + * @details The origin is the name of the file, and the key is the GUID of the string. + * + * @param origin The name of the file, without the extension. + * @param key The GUID key of the string. + * + * @return The string in its localized form. + */ + std::string $(const std::string& origin, const std::string& key); + + /** + * @brief Gets a string from origin, and by the key. Formats it with the format strings. + * @details The origin is the name of the file, and the key is the GUID of the string. This method also + * enables you to format the string with the format strings. + * + * @param origin The name of the file, without the extension. + * @param formatKey The GUID key of the format string. + * @param formatStrings The format strings to format the string with. + * @return The formatted string in its localized form, formatted with the format strings. + */ + std::string $(const std::string& origin, + const std::string& formatKey, + const std::vector& formatStrings); +} // namespace steppable::localization diff --git a/include/output.hpp b/include/output.hpp index 7a08245e7..4c545f37f 100644 --- a/include/output.hpp +++ b/include/output.hpp @@ -72,16 +72,15 @@ namespace steppable::output * It is intended to tell the user that something is going wrong and cannot be handled. * * @tparam T The character type of the message. - * @tparam Args The types of the additional arguments. * @param[in] name The name of the error. * @param[in] msg The error message. * @param[in] args Additional arguments for formatting the message. */ - template - void error(const std::string& name, std::basic_string msg, Args... args) + template + void error(const std::string& name, const std::basic_string& msg, const std::vector& args = {}) { - auto formattedMsg = format::vFormat(std::string(msg), args...); - std::cerr << colors::red << formats::bold << LARGE_DOT << " Error: " << reset << colors::red; + auto formattedMsg = format::format(msg, args); + std::cerr << colors::red << formats::bold << LARGE_DOT << name << " - ERROR: " << reset << colors::red; std::cerr << formattedMsg << reset << '\n'; // Write to the log file @@ -89,31 +88,6 @@ namespace steppable::output logger.error(formattedMsg); } - /** - * @brief Prints an error message. - * - * This function prints an error message with the given name and message. - * Additional arguments can be provided to format the message using the - * `std::basic_string` format syntax. - * - * The message is printed in red color, and is also written to the log file. - * It is intended to tell the user that something is going wrong and cannot be handled. - * - * @tparam CharT The character type of the message. - * @param[in] name The name of the error. - * @param[in] msg The error message. - */ - template - void error(const std::string& name, std::basic_string msg) - { - std::cerr << colors::red << formats::bold << LARGE_DOT << " Error: " << reset << colors::red; - std::cerr << msg << reset << '\n'; - - // Write to the log file - auto logger = logging::Logger(name, "steppable.log"); - logger.error(msg); - } - /** * @brief Prints a warning message. * @@ -125,15 +99,17 @@ namespace steppable::output * It is intended to tell the user that something is going wrong but can be handled. * * @tparam T The character type of the message. - * @tparam Args The types of the additional arguments. + * @param[in] name The name of the warning * @param[in] msg The error message. * @param[in] args Additional arguments for formatting the message. */ - template - [[maybe_unused]] void warning(T msg, Args... args) + template + void warning(const std::basic_string& name, + const std::basic_string& msg, + const std::vector& args = {}) { - std::cout << colors::yellow << formats::bold << LARGE_DOT << " Warning: " << reset << colors::yellow; - std::cout << format::vFormat(msg, args...) << reset << '\n'; + std::cout << colors::yellow << formats::bold << LARGE_DOT << name << " - WARNING: " << reset << colors::yellow; + std::cout << format::format(msg, args) << reset << '\n'; } /** @@ -147,14 +123,17 @@ namespace steppable::output * It is intended to tell the user that something is going right, or to provide some information. * * @tparam T The character type of the message. - * @tparam Args The types of the additional arguments. + * @param[in] name The name of the info message. * @param[in] msg The info message. * @param[in] args Additional arguments for formatting the message. */ - template - void info(T msg, Args... args) + template + void info(const std::basic_string& name, + const std::basic_string& msg, + const std::vector& args = {}) { - std::cout << colors::brightGreen << formats::bold << LARGE_DOT << " Info: " << reset << colors::brightGreen; - std::cout << format::vFormat(msg, args...) << reset << '\n'; + std::cout << colors::brightGreen << formats::bold << LARGE_DOT << name << " - INFO: " << reset + << colors::brightGreen; + std::cout << format::format(msg, args) << reset << '\n'; } } // namespace steppable::output diff --git a/include/platform.hpp b/include/platform.hpp index dc06bee8d..f370714fd 100644 --- a/include/platform.hpp +++ b/include/platform.hpp @@ -32,10 +32,11 @@ */ #pragma once - #include #include -#include +#include + +using namespace std::literals; /** * @namespace steppable::__internals::utils @@ -76,4 +77,8 @@ namespace steppable::__internals::utils #endif return bt; } + + std::filesystem::path getHomeDirectory(); + + std::filesystem::path getConfDirectory(); } // namespace steppable::__internals::utils diff --git a/include/testing.hpp b/include/testing.hpp index 79320dcd0..1cc1f16c2 100644 --- a/include/testing.hpp +++ b/include/testing.hpp @@ -30,7 +30,7 @@ #pragma once -#include +#include using namespace std::literals; @@ -73,14 +73,14 @@ using namespace std::literals; /// @brief This macro ends the main function and prints the number of errors encountered. // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define TEST_END() \ - if (errors) \ - error("TEST_END", "Not all tests passed. There are %i errors."s, errors); \ - else \ - info("All tests passed."); \ - std::cout << colors::brightBlue << std::setw(80) << std::setfill('=') << reset << '\n'; \ - if (errors) \ - return 1; \ +#define TEST_END() \ + if (errors) \ + error("TEST_END"s, "Not all tests passed. There are {0} errors."s, { std::to_string(errors) }); \ + else \ + info("TEST_END"s, "All tests passed."s); \ + std::cout << colors::brightBlue << std::setw(80) << std::setfill('=') << reset << '\n'; \ + if (errors) \ + return 1; \ } /** @@ -103,7 +103,7 @@ namespace steppable::testing */ void assert(bool condition, const std::string& conditionName); - std::string_view testCaseName; + std::string testCaseName; public: int errorCount = 0; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) diff --git a/include/util.hpp b/include/util.hpp index 0f216112f..981004a6b 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -87,7 +87,6 @@ namespace steppable::__internals::utils #include #endif - void initLocale(); #ifdef WINDOWS #include #include @@ -150,7 +149,6 @@ namespace steppable::__internals::utils */ Utf8CodePage() : oldCodePage(GetConsoleOutputCP()) { - initLocale(); SetConsoleOutputCP(CP_UTF8); dwModeOrig = enableVtMode(); } @@ -182,7 +180,7 @@ namespace steppable::__internals::utils class Utf8CodePage { public: - Utf8CodePage() { initLocale(); } + Utf8CodePage() { ; } }; #endif } // namespace steppable::__internals::utils @@ -215,14 +213,14 @@ namespace steppable::__internals::numUtils * @param[in] string The input string to be simplified. * @return A simplified string with standard polarity. */ - std::string simplifyZeroPolarity(const std::string_view& string); + std::string simplifyZeroPolarity(const std::string& string); /** * @brief Simplifies a string with non-standard polarity (e.g., --1, ---1, etc.). * @param[in] _string A string to simplify. * @return A simplified string with correct polarity. */ - std::string simplifyPolarity(const std::string_view& _string); + std::string simplifyPolarity(const std::string& _string); /** * @brief Standardizes a number string. @@ -230,10 +228,10 @@ namespace steppable::__internals::numUtils * @param[in] _number The number string to standardize. * @return The standardized number string. */ - std::string standardizeNumber(const std::string_view& _number); + std::string standardizeNumber(const std::string& _number); /** - * @fn constexpr bool isZeroString(const std::string_view& string) + * @fn constexpr bool isZeroString(const std::string& string) * @brief Checks if a given string is a zero string. * * A zero string is defined as a string that contains only the character '0'. @@ -241,7 +239,7 @@ namespace steppable::__internals::numUtils * @param[in] string The string to check. * @return True if the string is a zero string, false otherwise. */ - constexpr bool isZeroString(const std::string_view& string) + constexpr bool isZeroString(const std::string& string) { return std::ranges::all_of(string, [](const char c) { return c == '0' or c == '.' or c == '-'; }); } @@ -252,7 +250,7 @@ namespace steppable::__internals::numUtils * @param[in] s The string to be checked. * @return True if the string is a valid number, false otherwise. */ - bool isNumber(const std::string_view& s); + bool isNumber(const std::string& s); /** * Splits two numbers represented as strings and returns the result. @@ -266,8 +264,8 @@ namespace steppable::__internals::numUtils * * @see SplitNumberResult */ - SplitNumberResult splitNumber(const std::string_view& a, - const std::string_view& b, + SplitNumberResult splitNumber(const std::string& a, + const std::string& b, bool padInteger = true, bool padDecimal = true, bool properlyFormat = true, @@ -319,7 +317,7 @@ namespace steppable::__internals::numUtils * @param[in] number The number to be processed. * @return The scale of the number */ - long long determineScale(const std::string_view& number); + long long determineScale(const std::string& number); /** * @brief Determines whether the number is an integer or not. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5a3000ebc..29229660a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -20,25 +20,27 @@ # SOFTWARE. # ##################################################################################################### -set(Python_EXECUTABLE ${Python3_EXECUTABLE}) +if(NOT ${STP_NO_BINDINGS}) # Only create the bindings if needed + set(Python_EXECUTABLE ${Python3_EXECUTABLE}) -# Detect the installed nanobind package and import it into CMake -execute_process( - COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE NB_DIR) -message(TRACE "Found nanobind: ${NB_DIR}") -list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}") -find_package(nanobind CONFIG REQUIRED) + # Detect the installed nanobind package and import it into CMake + execute_process( + COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE NB_DIR) + message(TRACE "Found nanobind: ${NB_DIR}") + list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}") + find_package(nanobind CONFIG REQUIRED) -# Python bindings for Steppable. -set(Python_INTERPRETER_ID ${Python3_INTERPRETER_ID} CACHE INTERNAL "Compatibility for nanobind") -nanobind_add_module(steppyble STABLE_ABI NB_STATIC LTO bindings.cpp) + # Python bindings for Steppable. + set(Python_INTERPRETER_ID ${Python3_INTERPRETER_ID} CACHE INTERNAL "Compatibility for nanobind") + nanobind_add_module(steppyble STABLE_ABI NB_STATIC LTO bindings.cpp) -if(NOT ${WINDOWS}) - target_link_options(steppyble PRIVATE -Bsymbolic) -endif() -set_target_properties(steppyble PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_link_libraries(steppyble PRIVATE calc steppable) -target_compile_definitions(steppyble PRIVATE NO_MAIN) -target_include_directories(steppyble PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include) + if(NOT ${WINDOWS}) + target_link_options(steppyble PRIVATE -Bsymbolic) + endif() + set_target_properties(steppyble PROPERTIES POSITION_INDEPENDENT_CODE ON) + target_link_libraries(steppyble PRIVATE calc steppable) + target_compile_definitions(steppyble PRIVATE NO_MAIN) + target_include_directories(steppyble PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include) +endif() \ No newline at end of file diff --git a/lib/getch.py b/lib/getch.py new file mode 100644 index 000000000..4f858a155 --- /dev/null +++ b/lib/getch.py @@ -0,0 +1,79 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +import sys + + +class _Getch: + """Gets a single character from standard input. Does not echo to the + screen.""" + + def __init__(self): + if not hasattr(sys.stdin, "fileno"): + self.impl = input + return + try: + self.impl = _GetchWindows() + except ImportError: + self.impl = _GetchUnix() + + def __call__(self): + return self.impl() + + +class _GetchUnix: + def __init__(self): + import tty # pyright: ignore + + def __call__(self) -> str: + import termios + import tty + + fd = sys.stdin.fileno() + error = False + try: + old_settings = termios.tcgetattr(fd) + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + error = False + except termios.error: + ch = input() + error = True + finally: + if not error: + termios.tcsetattr( + fd, termios.TCSADRAIN, old_settings # pyright: ignore + ) + return ch + + +class _GetchWindows: + def __init__(self): + import msvcrt # pyright: ignore + + def __call__(self) -> str: + import msvcrt + + return msvcrt.getch() # pyright: ignore + + +getch = _Getch() diff --git a/lib/paths.py b/lib/paths.py index 438b54f66..aa4128633 100644 --- a/lib/paths.py +++ b/lib/paths.py @@ -25,6 +25,7 @@ """ from pathlib import Path +from lib.constants import WINDOWS # section Project paths PROJECT = "Steppable" @@ -39,3 +40,13 @@ BIN_DIR = BUILD_DIR / "bin" LIB_DIR = BUILD_DIR / "lib" # endsection + +# section Configuration paths +if not WINDOWS: + CONFIG_DIR = Path().home() / ".config" / "steppable" +else: + CONFIG_DIR = Path().home() / "AppData" / "Roaming" / "steppable" + +DEFAULT_CONFIG_DIR = PROJECT_PATH / "res" + +# endsection diff --git a/lib/printing.py b/lib/printing.py index e9f2694b5..4d89a0dfd 100644 --- a/lib/printing.py +++ b/lib/printing.py @@ -27,6 +27,11 @@ def green() -> str: + """ + Sets the terminal output color to green. + + :return: The escape sequence to set the terminal output color to green. + """ if WINDOWS: return "" if sys.stdout.isatty(): @@ -35,6 +40,11 @@ def green() -> str: def red() -> str: + """ + Sets the terminal output color to red. + + :return: The escape sequence to set the terminal output color to red. + """ if WINDOWS: return "" if sys.stdout.isatty(): @@ -43,6 +53,11 @@ def red() -> str: def yellow() -> str: + """ + Sets the terminal output color to yellow. + + :return: The escape sequence to set the terminal output color to yellow. + """ if WINDOWS: return "" if sys.stdout.isatty(): @@ -51,6 +66,11 @@ def yellow() -> str: def blue() -> str: + """ + Sets the terminal output color to blue. + + :return: The escape sequence to set the terminal output color to blue. + """ if WINDOWS: return "" if sys.stdout.isatty(): @@ -58,7 +78,13 @@ def blue() -> str: return "" -def erase_line() -> str: +def erase_line(lines: int = 1) -> str: + """ + Erases the specified number of lines in the terminal. + + :param lines: Number of lines to erase. + :return: The escape sequence to erase the lines. + """ if WINDOWS: return "" if sys.stdout.isatty(): @@ -82,6 +108,15 @@ def bold() -> str: return "" +def print_error(line: str, pos: int, message: str) -> None: + """ + Prints an error message with an arrow pointing to the position of the error. + """ + print(f"ERROR: {message}") + print(line) + print(" " * pos + "^") + + def print_progressbar( iteration: int, total: int, diff --git a/pyproject.toml b/pyproject.toml index de8c6e8c2..e2728bbd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,8 @@ dependencies = [ "black >= 24.4.2", "isort >= 5.13.2", "setuptools >= 61.0", - "nanobind >= 1.9.2" + "nanobind >= 1.9.2", + "pyyaml >= 6.0.1", ] [build-system] diff --git a/res/translations/abs.stp_strings b/res/translations/abs.stp_strings new file mode 100644 index 000000000..87e590792 --- /dev/null +++ b/res/translations/abs.stp_strings @@ -0,0 +1,35 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +ca70a6a7-d1d8-4e43-a94e-014d8f9839c9 >> "Number" +3860a4ae-1073-4a6d-a75e-f64426291573 >> "Amount of steps while taking the absolute value. 0 = No steps, 2 = All steps." +5d7bddda-e33f-4f9c-81b2-d30baad2ec5c >> "profiling the program" +be63279d-b251-4785-8f12-df12a729419f >> "Taking absolute value :" +f39c432d-9031-423a-a12f-1efcd3e113b2 >> "Since " +5c8a89a7-4cb1-40d8-b926-6ae84fc3a3ef >> " is negative, " +8fd01dbe-c921-4f22-a0ab-d1348967e4b0 >> " The absolute value of {0}" +7066c6e7-6b80-4671-bc61-6c0322204c87 >> " is " +b119f705-751b-425e-a758-47d755307700 >> " is positive, " diff --git a/res/translations/add.stp_strings b/res/translations/add.stp_strings new file mode 100644 index 000000000..8acc9f578 --- /dev/null +++ b/res/translations/add.stp_strings @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +ca3f0783-02d8-4006-8bbe-2311ffd708fa >> ", the result is " +547d6d96-de8d-4f2e-af3b-2da475d8d161 >> "Subtracting {0} from {1} since {2} is negative." +6e1121d2-75a4-4173-a54b-0b6c2f98abfc >> "Number 1" +852e4cdb-cb19-4717-95b3-eaec08777ebc >> "Number 2" +c935c960-609c-4ecd-97f5-d4f36d3bbc9f >> "Amount of steps while adding. 0 = No steps, 2 = All steps." +6959b967-151d-44b0-a250-464f871d6dc1 >> "profiling the program" +0c7e9691-2777-4cb8-8ae6-e21206859c5d >> "Column Method Addition :" diff --git a/res/translations/argParse.stp_strings b/res/translations/argParse.stp_strings new file mode 100644 index 000000000..8e885338e --- /dev/null +++ b/res/translations/argParse.stp_strings @@ -0,0 +1,38 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +91408f1e-6627-41e5-9707-d8a660c2b86b >> "Usage: " +38f61169-17f1-4a49-870b-814745cdf4c6 >> "[switches] " +4f332974-1fd1-43eb-bbbc-8d32071ed735 >> "[keywordArguments] " +5d482eea-c4e4-4c4d-89f0-6b33fcc9618c >> "Available positional arguments:" +10b1c33b-070f-4dfb-be12-a1a4349e76bc >> "Available switches:" +227375c6-6ec8-479e-ad39-59f975272c6b >> " Enables/Disables {0}" +be2d8c84-0dfc-4f52-b450-e34d1cf20c91 >> "Available keyword arguments:" +fd67fddb-ca42-4a79-b852-c0bc71aa9969 >> "(*) Requires a number" +b782de55-513d-4eda-b068-98d2d6210603 >> "Missing positional argument: " +aa26a7f2-0949-454e-b987-42b40348e104 >> "Missing keyword argument: " +2b854b9f-da27-483e-a016-0eb0d26eb9e9 >> "Missing switch: " +34782921-b560-4706-a2c9-d5c326af2cff >> "Invalid argument: {0}" diff --git a/res/translations/baseConvert.stp_strings b/res/translations/baseConvert.stp_strings new file mode 100644 index 000000000..cc34a35f3 --- /dev/null +++ b/res/translations/baseConvert.stp_strings @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +4e5a4863-4e4a-44f1-a782-e74de6b93469 >> "It is impossilbe to represent a number in base greater than 36" +783e7915-f4a3-4973-9747-2d8de3de5545 >> "Conversion to base 0 or 1 is not possible" +f3211410-9b0d-49f6-8797-c4756b2fee28 >> "Number to convert" +61826029-8d77-4133-8bc7-7f03365bd9a3 >> "Base of the number" +f988a0b2-decd-4d0c-a2e2-dd4127c1e83b >> "Amount of steps while converting. 0 = No steps, 2 = All steps." +0826ae41-c7f6-4e1f-a932-2f6c00930a05 >> "profiling the program" +74dd79f5-7c24-4b39-bf66-59a3570e4a03 >> "Base conversion :" +8a0b5c6d-b1a8-49b4-99fd-b1710744f4bf >> " The number {0} in base {1} is " diff --git a/res/translations/comparison.stp_strings b/res/translations/comparison.stp_strings new file mode 100644 index 000000000..72e93d434 --- /dev/null +++ b/res/translations/comparison.stp_strings @@ -0,0 +1,40 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +0095d521-ccba-4c5b-b33f-9d9f2b3d18e3 >> "Comparing the integer part of {0} and {1}" +07ff2704-10c1-4eea-bba2-bd63116ca34b >> "Amount of steps while comparing" +1d411edd-f7a6-4ad5-8a0a-cc8b5eea01b1 >> "Number 1" +0972be2d-ce73-4226-82d8-778fb5293894 >> "Number 2" +09a9b12d-7b58-4626-b7c8-62a16933bfce >> "Comparing the polarities of {0} and {1}" +1b7ea6d8-9909-4589-8d59-b3eb7121cdee >> " The integer part of {0} is greater than that of {1}" +ab1363eb-bfdb-44a9-89ee-b125a8d60cbd >> " At digit {0}, {1} is greater than {2}" +b930c709-22e7-46f8-9cdf-5ed193469964 >> "profiling the program" +bd4f865a-ce08-4825-ac74-f824e4da2fed >> " {0} is identical to {1}, " +c49d968f-31df-4654-b13b-0f16212f4591 >> "Equal" +eb150ad5-09a5-4be6-8400-988e6f0eb252 >> " {0} is positive and {1} is negative " +237615f7-6c35-4ca2-a791-43d8ccc925dd >> " {0} is negative and {1} is positive " +ec120274-c8f2-4a41-9e64-b7b0d011d20e >> " {0} is less than {1}" +aaad3a6a-1257-478a-b3d1-245c4dc0e6fb >> " {0} is greater than {1}" diff --git a/res/translations/decimalConvert.stp_strings b/res/translations/decimalConvert.stp_strings new file mode 100644 index 000000000..38fb03f0c --- /dev/null +++ b/res/translations/decimalConvert.stp_strings @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +cbb9ed62-1127-4e1d-95ef-e75cc7fb2837 >> "The base is larger than 36, which means that it is impossible to represent the number." +e97b6539-8f69-4ccb-a50e-82a66aff2898 >> "The digit {0} is larger than the base {1}" +53053bf2-84ba-4b63-9f27-d334dc38b60d >> "Number in the base" +b771e8bc-9b66-4b4d-b9ff-fd4111111cf4 >> "Base number" +b461a3e5-12c3-48ea-aaba-2b4e234f3234 >> "Amount of steps while converting the number. 0 = No steps, 2 = All steps." +d14e05b6-cb8e-43a5-9ab2-11f960f4e199 >> "profiling the program" +d1536a73-2eb9-4bf9-8b25-00ff88038dab >> "Decimal Conversion :" diff --git a/res/translations/division.stp_strings b/res/translations/division.stp_strings new file mode 100644 index 000000000..c7f57bf0c --- /dev/null +++ b/res/translations/division.stp_strings @@ -0,0 +1,36 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +e8ad759d-fcb8-4280-a7a8-a637ae834ffc >> "Imagine that you have zero cookies and you split them evenly among zero friends. How many cookies does each person get? See? It doesn't make sense. And Cookie Monster is sad that there are no cookies, and your friends are sad because they don't exist. Oh wow this escalated quickly." +977f3c9f-01c3-49e4-bf4a-94d7c58bbe82 >> "Division of {0} by zero leads to infinity." +b4cace82-0076-40f3-85de-92aa1a81df44 >> "Since {0} is equal to {1} the result is 1" +d38c283c-e75d-4cc2-a634-bf1b3361d489 >> "The result is inaccurate, as the decimals you specified is not enough to display the result." +e7bbfa43-684d-498a-b10f-d8a76a371583 >> "Number 1" +9e6d7430-7006-4c77-ad4a-00955080765c >> "Number 2" +797de85c-787c-4c05-bc42-763da058f9e0 >> "Amount of steps while dividing. 0 = No steps, 2 = All steps." +e10fcce8-4bb3-4b3b-9820-33571065a8ee >> "Decimals to output" +98a3f915-5e93-4417-942a-071b2d9a13b3 >> "profiling the program" +bc2c8ff9-2d67-45e9-8824-2bc971e21cc9 >> "Column Method Division :" diff --git a/res/translations/en-US/abs.stp_localized b/res/translations/en-US/abs.stp_localized new file mode 100644 index 000000000..a5260aaeb --- /dev/null +++ b/res/translations/en-US/abs.stp_localized @@ -0,0 +1,35 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +ca70a6a7-d1d8-4e43-a94e-014d8f9839c9 >> "Number" +3860a4ae-1073-4a6d-a75e-f64426291573 >> "Amount of steps while taking the absolute value. 0 = No steps, 2 = All steps." +5d7bddda-e33f-4f9c-81b2-d30baad2ec5c >> "profiling the program" +be63279d-b251-4785-8f12-df12a729419f >> "Taking absolute value :" +f39c432d-9031-423a-a12f-1efcd3e113b2 >> "Since " +5c8a89a7-4cb1-40d8-b926-6ae84fc3a3ef >> " is negative, " +8fd01dbe-c921-4f22-a0ab-d1348967e4b0 >> " The absolute value of {0}" +7066c6e7-6b80-4671-bc61-6c0322204c87 >> " is " +b119f705-751b-425e-a758-47d755307700 >> " is positive, " \ No newline at end of file diff --git a/res/translations/en-US/add.stp_localized b/res/translations/en-US/add.stp_localized new file mode 100644 index 000000000..322c9fc1f --- /dev/null +++ b/res/translations/en-US/add.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +ca3f0783-02d8-4006-8bbe-2311ffd708fa >> ", the result is " +547d6d96-de8d-4f2e-af3b-2da475d8d161 >> "Subtracting {0} from {1} since {2} is negative." +6e1121d2-75a4-4173-a54b-0b6c2f98abfc >> "Number 1" +852e4cdb-cb19-4717-95b3-eaec08777ebc >> "Number 2" +c935c960-609c-4ecd-97f5-d4f36d3bbc9f >> "Amount of steps while adding. 0 = No steps, 2 = All steps." +6959b967-151d-44b0-a250-464f871d6dc1 >> "profiling the program" +0c7e9691-2777-4cb8-8ae6-e21206859c5d >> "Column Method Addition :" \ No newline at end of file diff --git a/res/translations/en-US/argParse.stp_localized b/res/translations/en-US/argParse.stp_localized new file mode 100644 index 000000000..7ae232dd0 --- /dev/null +++ b/res/translations/en-US/argParse.stp_localized @@ -0,0 +1,38 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +91408f1e-6627-41e5-9707-d8a660c2b86b >> "Usage: " +38f61169-17f1-4a49-870b-814745cdf4c6 >> "[switches] " +4f332974-1fd1-43eb-bbbc-8d32071ed735 >> "[keywordArguments] " +5d482eea-c4e4-4c4d-89f0-6b33fcc9618c >> "Available positional arguments:" +10b1c33b-070f-4dfb-be12-a1a4349e76bc >> "Available switches:" +227375c6-6ec8-479e-ad39-59f975272c6b >> " Enables/Disables {0}" +be2d8c84-0dfc-4f52-b450-e34d1cf20c91 >> "Available keyword arguments:" +fd67fddb-ca42-4a79-b852-c0bc71aa9969 >> "(*) Requires a number" +b782de55-513d-4eda-b068-98d2d6210603 >> "Missing positional argument: " +aa26a7f2-0949-454e-b987-42b40348e104 >> "Missing keyword argument: " +2b854b9f-da27-483e-a016-0eb0d26eb9e9 >> "Missing switch: " +34782921-b560-4706-a2c9-d5c326af2cff >> "Invalid argument: {0}" \ No newline at end of file diff --git a/res/translations/en-US/baseConvert.stp_localized b/res/translations/en-US/baseConvert.stp_localized new file mode 100644 index 000000000..53abb890a --- /dev/null +++ b/res/translations/en-US/baseConvert.stp_localized @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +4e5a4863-4e4a-44f1-a782-e74de6b93469 >> "It is impossilbe to represent a number in base greater than 36" +783e7915-f4a3-4973-9747-2d8de3de5545 >> "Conversion to base 0 or 1 is not possible" +f3211410-9b0d-49f6-8797-c4756b2fee28 >> "Number to convert" +61826029-8d77-4133-8bc7-7f03365bd9a3 >> "Base of the number" +f988a0b2-decd-4d0c-a2e2-dd4127c1e83b >> "Amount of steps while converting. 0 = No steps, 2 = All steps." +0826ae41-c7f6-4e1f-a932-2f6c00930a05 >> "profiling the program" +74dd79f5-7c24-4b39-bf66-59a3570e4a03 >> "Base conversion :" +8a0b5c6d-b1a8-49b4-99fd-b1710744f4bf >> " The number {0} in base {1} is " \ No newline at end of file diff --git a/res/translations/en-US/comparison.stp_localized b/res/translations/en-US/comparison.stp_localized new file mode 100644 index 000000000..671b0e173 --- /dev/null +++ b/res/translations/en-US/comparison.stp_localized @@ -0,0 +1,40 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +0095d521-ccba-4c5b-b33f-9d9f2b3d18e3 >> "Comparing the integer part of {0} and {1}" +07ff2704-10c1-4eea-bba2-bd63116ca34b >> "Amount of steps while comparing" +1d411edd-f7a6-4ad5-8a0a-cc8b5eea01b1 >> "Number 1" +0972be2d-ce73-4226-82d8-778fb5293894 >> "Number 2" +09a9b12d-7b58-4626-b7c8-62a16933bfce >> "Comparing the polarities of {0} and {1}" +1b7ea6d8-9909-4589-8d59-b3eb7121cdee >> " The integer part of {0} is greater than that of {1}" +ab1363eb-bfdb-44a9-89ee-b125a8d60cbd >> " At digit {0}, {1} is greater than {2}" +b930c709-22e7-46f8-9cdf-5ed193469964 >> "profiling the program" +bd4f865a-ce08-4825-ac74-f824e4da2fed >> " is identical to " +c49d968f-31df-4654-b13b-0f16212f4591 >> "Equal" +eb150ad5-09a5-4be6-8400-988e6f0eb252 >> " {0} is positive and {1} is negative " +237615f7-6c35-4ca2-a791-43d8ccc925dd >> " {0} is negative and {1} is positive " +ec120274-c8f2-4a41-9e64-b7b0d011d20e >> " {0} is less than {1}" +aaad3a6a-1257-478a-b3d1-245c4dc0e6fb >> " {0} is greater than {1}" diff --git a/res/translations/en-US/decimalConvert.stp_localized b/res/translations/en-US/decimalConvert.stp_localized new file mode 100644 index 000000000..ecd62a7b1 --- /dev/null +++ b/res/translations/en-US/decimalConvert.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +cbb9ed62-1127-4e1d-95ef-e75cc7fb2837 >> "The base is larger than 36, which means that it is impossible to represent the number." +e97b6539-8f69-4ccb-a50e-82a66aff2898 >> "The digit {0} is larger than the base {1}" +53053bf2-84ba-4b63-9f27-d334dc38b60d >> "Number in the base" +b771e8bc-9b66-4b4d-b9ff-fd4111111cf4 >> "Base number" +b461a3e5-12c3-48ea-aaba-2b4e234f3234 >> "Amount of steps while converting the number. 0 = No steps, 2 = All steps." +d14e05b6-cb8e-43a5-9ab2-11f960f4e199 >> "profiling the program" +d1536a73-2eb9-4bf9-8b25-00ff88038dab >> "Decimal Conversion :" \ No newline at end of file diff --git a/res/translations/en-US/division.stp_localized b/res/translations/en-US/division.stp_localized new file mode 100644 index 000000000..def85aa39 --- /dev/null +++ b/res/translations/en-US/division.stp_localized @@ -0,0 +1,36 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +e8ad759d-fcb8-4280-a7a8-a637ae834ffc >> "Imagine that you have zero cookies and you split them evenly among zero friends. How many cookies does each person get? See? It doesn't make sense. And Cookie Monster is sad that there are no cookies, and your friends are sad because they don't exist. Oh wow this escalated quickly." +977f3c9f-01c3-49e4-bf4a-94d7c58bbe82 >> "Division of {0} by zero leads to infinity." +b4cace82-0076-40f3-85de-92aa1a81df44 >> "Since {0} is equal to {1} the result is 1" +d38c283c-e75d-4cc2-a634-bf1b3361d489 >> "The result is inaccurate, as the decimals you specified is not enough to display the result." +e7bbfa43-684d-498a-b10f-d8a76a371583 >> "Number 1" +9e6d7430-7006-4c77-ad4a-00955080765c >> "Number 2" +797de85c-787c-4c05-bc42-763da058f9e0 >> "Amount of steps while dividing. 0 = No steps, 2 = All steps." +e10fcce8-4bb3-4b3b-9820-33571065a8ee >> "Decimals to output" +98a3f915-5e93-4417-942a-071b2d9a13b3 >> "profiling the program" +bc2c8ff9-2d67-45e9-8824-2bc971e21cc9 >> "Column Method Division :" \ No newline at end of file diff --git a/res/translations/en-US/factorial.stp_localized b/res/translations/en-US/factorial.stp_localized new file mode 100644 index 000000000..257ff4105 --- /dev/null +++ b/res/translations/en-US/factorial.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +4eeba5fa-a5b8-4abf-ae65-22a466da6d18 >> "{0} is not an integer." +d023ddb5-8a71-441b-8c67-8836bd94e93d >> "By definition, 0! = 1" +69d93fb8-1bb7-4ed2-be6d-8eeafd5f23a6 >> "{0} is negative." +135326d7-4e93-46d1-9e0e-8407eab6307b >> "Number" +7e1e72c2-256d-4b71-84b6-65166937d7ba >> "Amount of steps while calculating the factorial. 0 = No steps, 2 = All steps." +b781d070-00e5-4c26-a56a-c0ad9504c0e3 >> "profiling the program" +3ab32522-695e-4551-9542-0eb1824c8bd2 >> "Factorial :" \ No newline at end of file diff --git a/res/translations/en-US/hyp.stp_localized b/res/translations/en-US/hyp.stp_localized new file mode 100644 index 000000000..1e0cb8593 --- /dev/null +++ b/res/translations/en-US/hyp.stp_localized @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +e1f6e8db-64cd-4882-b5b2-ddd1c79c1e57 >> "Hyperbolic cotangent is not defined here." +30735b1c-5f92-4d2a-ab4a-056dd0f03c9b >> "Hyperbolic cosecant is not defined here." +1f091fa2-47c1-4432-8951-c7db1dff0995 >> "Hyperbolic secant is not defined here." +4c28b4d6-3002-458a-88bd-9d7c03b9b614 >> "Command" +1d369138-f330-42b2-9aa9-40ab5f7f3df8 >> "Number" +92717527-91df-4fa8-905c-cde0525612af >> "Amount of decimals while calculating." +ba4083c0-788f-4f3c-9748-df0cf7b7b41c >> "profiling the program" +b2f5e0cd-3c21-4fb6-8964-7b411c27785a >> "Invalid command." \ No newline at end of file diff --git a/res/translations/en-US/log.stp_localized b/res/translations/en-US/log.stp_localized new file mode 100644 index 000000000..07ae4d50a --- /dev/null +++ b/res/translations/en-US/log.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +3e0597e5-96e5-4de8-9982-f28a42e717fb >> "The number cannot be zero." +56363a7f-4277-4805-95b2-ef3b8ccc1671 >> "Amount of decimals while calculating." +8623ed47-e7bd-46a2-a1db-3c0746520e2e >> "profiling the program" +0fc4245a-fee9-4e99-bbbd-378d091c5143 >> "Unknown command {0}" +e8227bec-443c-4d2d-a569-06e3d20c11ad >> "Command" +d67686ce-2bad-48c9-a8ff-ec709d23ccea >> "Number" +4a3f8558-00dd-430e-921c-792542d9c29a >> "Base" \ No newline at end of file diff --git a/res/translations/en-US/multiply.stp_localized b/res/translations/en-US/multiply.stp_localized new file mode 100644 index 000000000..2123f9a9e --- /dev/null +++ b/res/translations/en-US/multiply.stp_localized @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +9cdeff33-fefa-40ac-b867-a811f652d6e3 >> "Since any of a or b is zero, the result must be zero as well." +36adc27f-07e8-4118-88ed-f148164044da >> "Since {0} is 1, the result is {2}." +0e76c0f9-6d14-450d-abc4-f4a758787d06 >> "Since {0} is a power of 10, we can move the decimal places to obtain the result." +1d54da58-ec3c-4888-80a8-c40565efb603 >> "Number 1" +3db8b80f-9667-476a-b096-9323615dd461 >> "Number 2" +5ed5291e-6269-4d76-a8f8-db5eec807955 >> "Amount of steps while multiplying" +eec47776-991b-40cc-9956-7227127d2c1f >> "profiling the program" +776a33fd-982a-4888-8b42-83b0f3797dc2 >> "Column Method Multiplication :" \ No newline at end of file diff --git a/res/translations/en-US/power.stp_localized b/res/translations/en-US/power.stp_localized new file mode 100644 index 000000000..0fec3dc86 --- /dev/null +++ b/res/translations/en-US/power.stp_localized @@ -0,0 +1,35 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +7c866c46-d67e-4c1e-8fd5-b3bfa07d005d >> "Since the number is 1, the result is 1." +f8fdd5af-6450-4c19-97a9-9724493f76ab >> "Since the exponent is 0, the result is 1." +4252ac37-a36b-4605-9ec1-d69e70b91b46 >> "Number as the base" +1fefffaf-7731-430b-989f-42e74017a2eb >> "Number as the exponent" +cb935566-6125-49ce-9ebc-e157410a3005 >> "Amount of steps while raising the power (i.e., multiplying). 0 = No steps, 2 = All steps." +e5d48237-e161-494d-940b-e2457411fcfb >> "profiling the program" +2a9fd067-59a3-4a65-b1a6-2ca479e0f1a1 >> "Power :" +7b3b39ff-c3fa-4998-b9e2-8989fb6846f9 >> "The exponent {0} is a decimal. Therefore, the result is a root." +261e4299-0132-4ab5-a37d-aa376efbdd5f >> "Since the number is 0, the result is 0." \ No newline at end of file diff --git a/res/translations/en-US/root.stp_localized b/res/translations/en-US/root.stp_localized new file mode 100644 index 000000000..e534fd60c --- /dev/null +++ b/res/translations/en-US/root.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +0b4174a0-75ae-4dbb-93e0-144938272fd6 >> "Number" +43d64cf7-6f56-4081-a239-34a972cf5cce >> "Base" +c4392b15-37a2-4d0e-9b3a-fc11b46bf369 >> "Amount of decimals while taking the n-th root." +5f1f7d97-0ef3-4ccc-95c3-f7582ba11a20 >> "profiling the program" +aca8b9a2-c7ff-470a-a72f-86204a413c18 >> "Taking n-th root :" +248c0c3b-05f8-45d6-868f-ec921c088ce1 >> "The base {0} is a decimal. Therefore, we need to perform a power operation first." +3178f539-1d1c-4e7b-8f5e-6186b361b4e6 >> "Number of steps when taking the root." \ No newline at end of file diff --git a/res/translations/en-US/subtract.stp_localized b/res/translations/en-US/subtract.stp_localized new file mode 100644 index 000000000..dd5a14cf3 --- /dev/null +++ b/res/translations/en-US/subtract.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +063f0bd2-a4ca-4433-97c0-8baa73cd0e7c >> "Adding {0} and {1} since {2} is negative" +3db38a7c-58e9-44f2-ba36-47e355b60294 >> "Number 1" +a697967c-5010-423c-9a84-201c955310de >> "Number 2" +645b0f26-3c2a-49ae-a9d6-1e06c11fe15e >> "steps while subtracting" +7704320c-1391-405f-8147-0b4023d769f6 >> "shows the minus sign" +4c13dd96-fb5b-4e99-b8e6-08e8be07b446 >> "profiling the program" +4dee3c00-c204-4cb0-afad-e57e41763bf5 >> "Column Method Subtraction :" \ No newline at end of file diff --git a/res/translations/en-US/trig.stp_localized b/res/translations/en-US/trig.stp_localized new file mode 100644 index 000000000..7c2bbd9a5 --- /dev/null +++ b/res/translations/en-US/trig.stp_localized @@ -0,0 +1,41 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +82443952-e7cc-4566-b6fe-f1caba92534d >> "Invalid mode. Defaulting to radians." +a7ed4324-5cc3-48d2-9798-d3e743b809d3 >> "Tangent is undefined here." +0dd11fcc-bdd0-48d1-9b4a-7ebcccb4915f >> "Cosecant is undefined here." +62792c6c-6751-4850-bf66-5e6366322cc0 >> "Secant is undefined here." +65650a93-4298-4e19-8c81-f5fbd9f14ac2 >> "Cotangent is undefined here." +b06650e0-7101-4734-9647-5abb56beb492 >> "Arc sine is not defined here." +fffb4742-3712-4c9a-a7ff-65cd51508a0a >> "Arc secant is not defined here." +c021dfde-300c-4d74-a6a1-87a514c1bbe0 >> "Arc cosecant is not defined here." +c0c6a29f-abda-4676-9662-1d00f94f10a4 >> "Arc cotangent is not defined here." +47dcf91b-847c-48f0-9889-f5ce1b6831e3 >> "Command" +bcd0a3e9-3d89-4921-94b3-d7533d60911f >> "Number" +03fdd1f2-6ea5-49d4-ac3f-27f01f04a518 >> "The mode to calculate in. 0 = radians (default), 1 = degrees, 2 = gradians." +d1df3b60-dac1-496c-99bb-ba763dc551df >> "Amount of decimals while calculating." +162adb13-c4b2-4418-b3df-edb6f9355d64 >> "profiling the program" +6ad9958f-f127-4ee4-a4c6-94cf19576b9a >> "Invalid command {0}." \ No newline at end of file diff --git a/res/translations/factorial.stp_strings b/res/translations/factorial.stp_strings new file mode 100644 index 000000000..67bc92913 --- /dev/null +++ b/res/translations/factorial.stp_strings @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +4eeba5fa-a5b8-4abf-ae65-22a466da6d18 >> "{0} is not an integer." +d023ddb5-8a71-441b-8c67-8836bd94e93d >> "By definition, 0! = 1" +69d93fb8-1bb7-4ed2-be6d-8eeafd5f23a6 >> "{0} is negative." +135326d7-4e93-46d1-9e0e-8407eab6307b >> "Number" +7e1e72c2-256d-4b71-84b6-65166937d7ba >> "Amount of steps while calculating the factorial. 0 = No steps, 2 = All steps." +b781d070-00e5-4c26-a56a-c0ad9504c0e3 >> "profiling the program" +3ab32522-695e-4551-9542-0eb1824c8bd2 >> "Factorial :" diff --git a/res/translations/hyp.stp_strings b/res/translations/hyp.stp_strings new file mode 100644 index 000000000..77bbc501a --- /dev/null +++ b/res/translations/hyp.stp_strings @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +e1f6e8db-64cd-4882-b5b2-ddd1c79c1e57 >> "Hyperbolic cotangent is not defined here." +30735b1c-5f92-4d2a-ab4a-056dd0f03c9b >> "Hyperbolic cosecant is not defined here." +1f091fa2-47c1-4432-8951-c7db1dff0995 >> "Hyperbolic secant is not defined here." +4c28b4d6-3002-458a-88bd-9d7c03b9b614 >> "Command" +1d369138-f330-42b2-9aa9-40ab5f7f3df8 >> "Number" +92717527-91df-4fa8-905c-cde0525612af >> "Amount of decimals while calculating." +ba4083c0-788f-4f3c-9748-df0cf7b7b41c >> "profiling the program" +b2f5e0cd-3c21-4fb6-8964-7b411c27785a >> "Invalid command." \ No newline at end of file diff --git a/res/translations/log.stp_strings b/res/translations/log.stp_strings new file mode 100644 index 000000000..31882f9ae --- /dev/null +++ b/res/translations/log.stp_strings @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +3e0597e5-96e5-4de8-9982-f28a42e717fb >> "The number cannot be zero." +0fc4245a-fee9-4e99-bbbd-378d091c5143 >> "Unknown command {0}" +e8227bec-443c-4d2d-a569-06e3d20c11ad >> "Command" +d67686ce-2bad-48c9-a8ff-ec709d23ccea >> "Number" +4a3f8558-00dd-430e-921c-792542d9c29a >> "Base" +56363a7f-4277-4805-95b2-ef3b8ccc1671 >> "Amount of decimals while calculating." +8623ed47-e7bd-46a2-a1db-3c0746520e2e >> "profiling the program" diff --git a/res/translations/multiply.stp_strings b/res/translations/multiply.stp_strings new file mode 100644 index 000000000..d3725dc43 --- /dev/null +++ b/res/translations/multiply.stp_strings @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +9cdeff33-fefa-40ac-b867-a811f652d6e3 >> "Since any of a or b is zero, the result must be zero as well." +36adc27f-07e8-4118-88ed-f148164044da >> "Since {0} is 1, the result is {1}." +0e76c0f9-6d14-450d-abc4-f4a758787d06 >> "Since {0} is a power of 10, we can move the decimal places to obtain the result." +1d54da58-ec3c-4888-80a8-c40565efb603 >> "Number 1" +3db8b80f-9667-476a-b096-9323615dd461 >> "Number 2" +5ed5291e-6269-4d76-a8f8-db5eec807955 >> "Amount of steps while multiplying" +eec47776-991b-40cc-9956-7227127d2c1f >> "profiling the program" +776a33fd-982a-4888-8b42-83b0f3797dc2 >> "Column Method Multiplication :" diff --git a/res/translations/power.stp_strings b/res/translations/power.stp_strings new file mode 100644 index 000000000..c720237cf --- /dev/null +++ b/res/translations/power.stp_strings @@ -0,0 +1,35 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +7c866c46-d67e-4c1e-8fd5-b3bfa07d005d >> "Since the number is 1, the result is 1." +f8fdd5af-6450-4c19-97a9-9724493f76ab >> "Since the exponent is 0, the result is 1." +4252ac37-a36b-4605-9ec1-d69e70b91b46 >> "Number as the base" +1fefffaf-7731-430b-989f-42e74017a2eb >> "Number as the exponent" +cb935566-6125-49ce-9ebc-e157410a3005 >> "Amount of steps while raising the power (i.e., multiplying). 0 = No steps, 2 = All steps." +e5d48237-e161-494d-940b-e2457411fcfb >> "profiling the program" +2a9fd067-59a3-4a65-b1a6-2ca479e0f1a1 >> "Power :" +7b3b39ff-c3fa-4998-b9e2-8989fb6846f9 >> "The exponent {0} is a decimal. Therefore, the result is a root." +261e4299-0132-4ab5-a37d-aa376efbdd5f >> "Since the number is 0, the result is 0." diff --git a/res/translations/root.stp_strings b/res/translations/root.stp_strings new file mode 100644 index 000000000..bc16f62a8 --- /dev/null +++ b/res/translations/root.stp_strings @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +0b4174a0-75ae-4dbb-93e0-144938272fd6 >> "Number" +43d64cf7-6f56-4081-a239-34a972cf5cce >> "Base" +c4392b15-37a2-4d0e-9b3a-fc11b46bf369 >> "Amount of decimals while taking the n-th root." +5f1f7d97-0ef3-4ccc-95c3-f7582ba11a20 >> "profiling the program" +aca8b9a2-c7ff-470a-a72f-86204a413c18 >> "Taking n-th root :" +248c0c3b-05f8-45d6-868f-ec921c088ce1 >> "The base {0} is a decimal. Therefore, we need to perform a power operation first." +3178f539-1d1c-4e7b-8f5e-6186b361b4e6 >> "Number of steps when taking the root." diff --git a/res/translations/subtract.stp_strings b/res/translations/subtract.stp_strings new file mode 100644 index 000000000..3d97edda9 --- /dev/null +++ b/res/translations/subtract.stp_strings @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +063f0bd2-a4ca-4433-97c0-8baa73cd0e7c >> "Adding {0} and {1} since {2} is negative" +3db38a7c-58e9-44f2-ba36-47e355b60294 >> "Number 1" +a697967c-5010-423c-9a84-201c955310de >> "Number 2" +645b0f26-3c2a-49ae-a9d6-1e06c11fe15e >> "steps while subtracting" +7704320c-1391-405f-8147-0b4023d769f6 >> "shows the minus sign" +4c13dd96-fb5b-4e99-b8e6-08e8be07b446 >> "profiling the program" +4dee3c00-c204-4cb0-afad-e57e41763bf5 >> "Column Method Subtraction :" diff --git a/res/translations/trig.stp_strings b/res/translations/trig.stp_strings new file mode 100644 index 000000000..2793d149c --- /dev/null +++ b/res/translations/trig.stp_strings @@ -0,0 +1,41 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +82443952-e7cc-4566-b6fe-f1caba92534d >> "Invalid mode. Defaulting to radians." +a7ed4324-5cc3-48d2-9798-d3e743b809d3 >> "Tangent is undefined here." +0dd11fcc-bdd0-48d1-9b4a-7ebcccb4915f >> "Cosecant is undefined here." +62792c6c-6751-4850-bf66-5e6366322cc0 >> "Secant is undefined here." +65650a93-4298-4e19-8c81-f5fbd9f14ac2 >> "Cotangent is undefined here." +b06650e0-7101-4734-9647-5abb56beb492 >> "Arc sine is not defined here." +fffb4742-3712-4c9a-a7ff-65cd51508a0a >> "Arc secant is not defined here." +c021dfde-300c-4d74-a6a1-87a514c1bbe0 >> "Arc cosecant is not defined here." +c0c6a29f-abda-4676-9662-1d00f94f10a4 >> "Arc cotangent is not defined here." +47dcf91b-847c-48f0-9889-f5ce1b6831e3 >> "Command" +bcd0a3e9-3d89-4921-94b3-d7533d60911f >> "Number" +03fdd1f2-6ea5-49d4-ac3f-27f01f04a518 >> "The mode to calculate in. 0 = radians (default), 1 = degrees, 2 = gradians." +d1df3b60-dac1-496c-99bb-ba763dc551df >> "Amount of decimals while calculating." +162adb13-c4b2-4418-b3df-edb6f9355d64 >> "profiling the program" +6ad9958f-f127-4ee4-a4c6-94cf19576b9a >> "Invalid command {0}." diff --git a/res/translations/zh-HK/abs.stp_localized b/res/translations/zh-HK/abs.stp_localized new file mode 100644 index 000000000..52c4ae691 --- /dev/null +++ b/res/translations/zh-HK/abs.stp_localized @@ -0,0 +1,35 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +ca70a6a7-d1d8-4e43-a94e-014d8f9839c9 >> "數值" +3860a4ae-1073-4a6d-a75e-f64426291573 >> "計算絕對值所需步驟。 代表沒有步驟,2 代表全部步驟。" +5d7bddda-e33f-4f9c-81b2-d30baad2ec5c >> "分析程式" +be63279d-b251-4785-8f12-df12a729419f >> "正在計算絕對值:" +f39c432d-9031-423a-a12f-1efcd3e113b2 >> "因為 " +5c8a89a7-4cb1-40d8-b926-6ae84fc3a3ef >> " 是負數," +8fd01dbe-c921-4f22-a0ab-d1348967e4b0 >> " {0}的絕對值" +7066c6e7-6b80-4671-bc61-6c0322204c87 >> "是" +b119f705-751b-425e-a758-47d755307700 >> " 是正數," diff --git a/res/translations/zh-HK/add.stp_localized b/res/translations/zh-HK/add.stp_localized new file mode 100644 index 000000000..072d6ad69 --- /dev/null +++ b/res/translations/zh-HK/add.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +ca3f0783-02d8-4006-8bbe-2311ffd708fa >> ",結果是" +547d6d96-de8d-4f2e-af3b-2da475d8d161 >> "由{2}為負數,因此需要從{1}中減去{0}。" +6e1121d2-75a4-4173-a54b-0b6c2f98abfc >> "數值一" +852e4cdb-cb19-4717-95b3-eaec08777ebc >> "數值二" +c935c960-609c-4ecd-97f5-d4f36d3bbc9f >> "計算加法所需步驟。0代表沒有步驟,2代表全部步驟。" +6959b967-151d-44b0-a250-464f871d6dc1 >> "分析程式" +0c7e9691-2777-4cb8-8ae6-e21206859c5d >> "直式加法:" diff --git a/res/translations/zh-HK/argParse.stp_localized b/res/translations/zh-HK/argParse.stp_localized new file mode 100644 index 000000000..4c0109be6 --- /dev/null +++ b/res/translations/zh-HK/argParse.stp_localized @@ -0,0 +1,38 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +91408f1e-6627-41e5-9707-d8a660c2b86b >> "使用方法:" +38f61169-17f1-4a49-870b-814745cdf4c6 >> "[開關] " +4f332974-1fd1-43eb-bbbc-8d32071ed735 >> "[關鍵字參數] " +5d482eea-c4e4-4c4d-89f0-6b33fcc9618c >> "可用的位置參數:" +10b1c33b-070f-4dfb-be12-a1a4349e76bc >> "可用的開關:" +227375c6-6ec8-479e-ad39-59f975272c6b >> " 啟用/停用{0}功能" +be2d8c84-0dfc-4f52-b450-e34d1cf20c91 >> "可用的關鍵字參數:" +fd67fddb-ca42-4a79-b852-c0bc71aa9969 >> "(*)需為數字" +b782de55-513d-4eda-b068-98d2d6210603 >> "欠缺位置參數:" +aa26a7f2-0949-454e-b987-42b40348e104 >> "欠缺關鍵字參數:" +2b854b9f-da27-483e-a016-0eb0d26eb9e9 >> "欠缺開關:" +34782921-b560-4706-a2c9-d5c326af2cff >> "錯誤的參數:{0}" diff --git a/res/translations/zh-HK/baseConvert.stp_localized b/res/translations/zh-HK/baseConvert.stp_localized new file mode 100644 index 000000000..8c8878a18 --- /dev/null +++ b/res/translations/zh-HK/baseConvert.stp_localized @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +4e5a4863-4e4a-44f1-a782-e74de6b93469 >> "無法以大於36的進制方式表示數值" +783e7915-f4a3-4973-9747-2d8de3de5545 >> "無法轉換至0或1進制" +f3211410-9b0d-49f6-8797-c4756b2fee28 >> "需轉換之數值" +61826029-8d77-4133-8bc7-7f03365bd9a3 >> "目標進制" +f988a0b2-decd-4d0c-a2e2-dd4127c1e83b >> "轉換時所顯示步驟。0代表沒有步驟,2代表所有步驟。" +0826ae41-c7f6-4e1f-a932-2f6c00930a05 >> "分析程式" +74dd79f5-7c24-4b39-bf66-59a3570e4a03 >> "進制轉換:" +8a0b5c6d-b1a8-49b4-99fd-b1710744f4bf >> " 在{1}進制中,數值{0}是" diff --git a/res/translations/zh-HK/comparison.stp_localized b/res/translations/zh-HK/comparison.stp_localized new file mode 100644 index 000000000..677643b2a --- /dev/null +++ b/res/translations/zh-HK/comparison.stp_localized @@ -0,0 +1,40 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +0095d521-ccba-4c5b-b33f-9d9f2b3d18e3 >> "正在比較{0}和{1}的整數部分" +07ff2704-10c1-4eea-bba2-bd63116ca34b >> "比較時所顯示步驟" +1d411edd-f7a6-4ad5-8a0a-cc8b5eea01b1 >> "數值一" +0972be2d-ce73-4226-82d8-778fb5293894 >> "數值二" +09a9b12d-7b58-4626-b7c8-62a16933bfce >> "正在比較{0}和{1}的正負" +1b7ea6d8-9909-4589-8d59-b3eb7121cdee >> " {0}的整數部分比{1}的大" +ab1363eb-bfdb-44a9-89ee-b125a8d60cbd >> " 在數位{0}處,{1}大於{2}" +b930c709-22e7-46f8-9cdf-5ed193469964 >> "分析程式" +bd4f865a-ce08-4825-ac74-f824e4da2fed >> " {0}和{1}完全相同," +c49d968f-31df-4654-b13b-0f16212f4591 >> "相等" +eb150ad5-09a5-4be6-8400-988e6f0eb252 >> " {0}是正數而{1}是負數" +237615f7-6c35-4ca2-a791-43d8ccc925dd >> " {0}是負數而{1}是正數" +ec120274-c8f2-4a41-9e64-b7b0d011d20e >> "{0}小於{1}" +aaad3a6a-1257-478a-b3d1-245c4dc0e6fb >> "{0}大於{1}" diff --git a/res/translations/zh-HK/decimalConvert.stp_localized b/res/translations/zh-HK/decimalConvert.stp_localized new file mode 100644 index 000000000..9f808e2f1 --- /dev/null +++ b/res/translations/zh-HK/decimalConvert.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +cbb9ed62-1127-4e1d-95ef-e75cc7fb2837 >> "無法以大於36的進制方式表示數值。" +e97b6539-8f69-4ccb-a50e-82a66aff2898 >> "數位{0}大於進制{1}" +53053bf2-84ba-4b63-9f27-d334dc38b60d >> "數值" +b771e8bc-9b66-4b4d-b9ff-fd4111111cf4 >> "數值之進制" +b461a3e5-12c3-48ea-aaba-2b4e234f3234 >> "轉換時所顯示的步驟。0代表沒有步驟,2代表全部步驟。" +d14e05b6-cb8e-43a5-9ab2-11f960f4e199 >> "分析程式" +d1536a73-2eb9-4bf9-8b25-00ff88038dab >> "十進制轉換:" \ No newline at end of file diff --git a/res/translations/zh-HK/division.stp_localized b/res/translations/zh-HK/division.stp_localized new file mode 100644 index 000000000..733ceed9b --- /dev/null +++ b/res/translations/zh-HK/division.stp_localized @@ -0,0 +1,36 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +e8ad759d-fcb8-4280-a7a8-a637ae834ffc >> "想像一下,您有零個餅乾,並且您將它們平均分配給零個朋友。每人得到多少塊餅乾?看?這沒有道理。餅乾怪物會因為沒有餅乾而感到悲傷,而你的朋友也會因為它們不存在而感到悲傷。哦,哇,這事升級得很快。" +977f3c9f-01c3-49e4-bf4a-94d7c58bbe82 >> "將{0}除以0️0,結果是無窮大。" +b4cace82-0076-40f3-85de-92aa1a81df44 >> "由於{0}等於{1},結果是1" +d38c283c-e75d-4cc2-a634-bf1b3361d489 >> "此結果並不準確,因為所提供的小數位數不足以完全顯示結果。" +e7bbfa43-684d-498a-b10f-d8a76a371583 >> "數值一" +9e6d7430-7006-4c77-ad4a-00955080765c >> "數值二" +797de85c-787c-4c05-bc42-763da058f9e0 >> "計算除法時所顯示的步驟。0代表沒有步驟,2代表全部步驟。" +e10fcce8-4bb3-4b3b-9820-33571065a8ee >> "輸出小數位數" +98a3f915-5e93-4417-942a-071b2d9a13b3 >> "分析程式" +bc2c8ff9-2d67-45e9-8824-2bc971e21cc9 >> "直式除法:" \ No newline at end of file diff --git a/res/translations/zh-HK/factorial.stp_localized b/res/translations/zh-HK/factorial.stp_localized new file mode 100644 index 000000000..d56f240d8 --- /dev/null +++ b/res/translations/zh-HK/factorial.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +4eeba5fa-a5b8-4abf-ae65-22a466da6d18 >> "{0}不是整數。" +d023ddb5-8a71-441b-8c67-8836bd94e93d >> "根據定義,0! = 1" +69d93fb8-1bb7-4ed2-be6d-8eeafd5f23a6 >> "{0}是負數。" +135326d7-4e93-46d1-9e0e-8407eab6307b >> "數值" +7e1e72c2-256d-4b71-84b6-65166937d7ba >> "計算階乘時所顯示步驟。0代表沒有步驟,2代表全部步驟。" +b781d070-00e5-4c26-a56a-c0ad9504c0e3 >> "分析程式" +3ab32522-695e-4551-9542-0eb1824c8bd2 >> "階乘:" \ No newline at end of file diff --git a/res/translations/zh-HK/hyp.stp_localized b/res/translations/zh-HK/hyp.stp_localized new file mode 100644 index 000000000..6225cbb2b --- /dev/null +++ b/res/translations/zh-HK/hyp.stp_localized @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +e1f6e8db-64cd-4882-b5b2-ddd1c79c1e57 >> "雙曲餘切在此沒有定義。" +30735b1c-5f92-4d2a-ab4a-056dd0f03c9b >> "雙曲餘割在此沒有定義。" +1f091fa2-47c1-4432-8951-c7db1dff0995 >> "雙曲正割在此沒有定義。" +4c28b4d6-3002-458a-88bd-9d7c03b9b614 >> "命令" +1d369138-f330-42b2-9aa9-40ab5f7f3df8 >> "數值" +92717527-91df-4fa8-905c-cde0525612af >> "計算時所輸出的小數位數。" +ba4083c0-788f-4f3c-9748-df0cf7b7b41c >> "分析程式" +b2f5e0cd-3c21-4fb6-8964-7b411c27785a >> "未知的命令。" \ No newline at end of file diff --git a/res/translations/zh-HK/log.stp_localized b/res/translations/zh-HK/log.stp_localized new file mode 100644 index 000000000..606362103 --- /dev/null +++ b/res/translations/zh-HK/log.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +3e0597e5-96e5-4de8-9982-f28a42e717fb >> "數值不能為0。" +56363a7f-4277-4805-95b2-ef3b8ccc1671 >> "計算時所輸出的小數位數。" +8623ed47-e7bd-46a2-a1db-3c0746520e2e >> "分析程式" +0fc4245a-fee9-4e99-bbbd-378d091c5143 >> "未知的命令{0}" +e8227bec-443c-4d2d-a569-06e3d20c11ad >> "命令" +d67686ce-2bad-48c9-a8ff-ec709d23ccea >> "數值" +4a3f8558-00dd-430e-921c-792542d9c29a >> "底數" \ No newline at end of file diff --git a/res/translations/zh-HK/multiply.stp_localized b/res/translations/zh-HK/multiply.stp_localized new file mode 100644 index 000000000..54ee72b55 --- /dev/null +++ b/res/translations/zh-HK/multiply.stp_localized @@ -0,0 +1,34 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +9cdeff33-fefa-40ac-b867-a811f652d6e3 >> "由於a或b為零,結果為零。" +36adc27f-07e8-4118-88ed-f148164044da >> "由於{0}是1,結果為{1}。" +0e76c0f9-6d14-450d-abc4-f4a758787d06 >> "由於{0}是10的冪,我們可以移動小數位來得到結果。" +1d54da58-ec3c-4888-80a8-c40565efb603 >> "數值一" +3db8b80f-9667-476a-b096-9323615dd461 >> "數值二" +5ed5291e-6269-4d76-a8f8-db5eec807955 >> "計算乘法時所顯示的步驟" +eec47776-991b-40cc-9956-7227127d2c1f >> "分析程式" +776a33fd-982a-4888-8b42-83b0f3797dc2 >> "直式乘法:" \ No newline at end of file diff --git a/res/translations/zh-HK/power.stp_localized b/res/translations/zh-HK/power.stp_localized new file mode 100644 index 000000000..35fe8e497 --- /dev/null +++ b/res/translations/zh-HK/power.stp_localized @@ -0,0 +1,35 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +7c866c46-d67e-4c1e-8fd5-b3bfa07d005d >> "由於數值為一,結果為一。" +f8fdd5af-6450-4c19-97a9-9724493f76ab >> "由於指數為零,結果為一。" +4252ac37-a36b-4605-9ec1-d69e70b91b46 >> "數值" +1fefffaf-7731-430b-989f-42e74017a2eb >> "指數" +cb935566-6125-49ce-9ebc-e157410a3005 >> "計算指數(乘法)時所顯示的步驟。0代表沒有步驟,2代表全部步驟。" +e5d48237-e161-494d-940b-e2457411fcfb >> "分析程式" +2a9fd067-59a3-4a65-b1a6-2ca479e0f1a1 >> "指數:" +7b3b39ff-c3fa-4998-b9e2-8989fb6846f9 >> "因為指數{0},結果為方根。" +261e4299-0132-4ab5-a37d-aa376efbdd5f >> "由於數值為零,結果為零。" diff --git a/res/translations/zh-HK/root.stp_localized b/res/translations/zh-HK/root.stp_localized new file mode 100644 index 000000000..f711350c3 --- /dev/null +++ b/res/translations/zh-HK/root.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +0b4174a0-75ae-4dbb-93e0-144938272fd6 >> "數值" +43d64cf7-6f56-4081-a239-34a972cf5cce >> "指數" +c4392b15-37a2-4d0e-9b3a-fc11b46bf369 >> "方根所輸出的小數位數。" +5f1f7d97-0ef3-4ccc-95c3-f7582ba11a20 >> "分析程式" +aca8b9a2-c7ff-470a-a72f-86204a413c18 >> "計算方根:" +248c0c3b-05f8-45d6-868f-ec921c088ce1 >> "指數{0}為小數,需首先計算指數。" +3178f539-1d1c-4e7b-8f5e-6186b361b4e6 >> "計算方根所顯示的步驟。" diff --git a/res/translations/zh-HK/subtract.stp_localized b/res/translations/zh-HK/subtract.stp_localized new file mode 100644 index 000000000..a86a69fe9 --- /dev/null +++ b/res/translations/zh-HK/subtract.stp_localized @@ -0,0 +1,33 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING TRANSLATED: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +063f0bd2-a4ca-4433-97c0-8baa73cd0e7c >> "由於{2}是負數,將{0}和{1}加起來" +3db38a7c-58e9-44f2-ba36-47e355b60294 >> "數值一" +a697967c-5010-423c-9a84-201c955310de >> "數值二" +645b0f26-3c2a-49ae-a9d6-1e06c11fe15e >> "計算減法時所顯示的步驟" +7704320c-1391-405f-8147-0b4023d769f6 >> "顯示減號" +4c13dd96-fb5b-4e99-b8e6-08e8be07b446 >> "分析程式" +4dee3c00-c204-4cb0-afad-e57e41763bf5 >> "直式減法" \ No newline at end of file diff --git a/res/translations/zh-HK/trig.stp_localized b/res/translations/zh-HK/trig.stp_localized new file mode 100644 index 000000000..ad527be12 --- /dev/null +++ b/res/translations/zh-HK/trig.stp_localized @@ -0,0 +1,41 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING ORIGINAL: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +82443952-e7cc-4566-b6fe-f1caba92534d >> "Invalid mode. Defaulting to radians." +a7ed4324-5cc3-48d2-9798-d3e743b809d3 >> "正切在此未定義。" +0dd11fcc-bdd0-48d1-9b4a-7ebcccb4915f >> "餘割在此未定義。" +62792c6c-6751-4850-bf66-5e6366322cc0 >> "正割在此未定義。" +65650a93-4298-4e19-8c81-f5fbd9f14ac2 >> "餘切在此未定義。" +b06650e0-7101-4734-9647-5abb56beb492 >> "反正弦在此未定義。" +fffb4742-3712-4c9a-a7ff-65cd51508a0a >> "反正割在此未定義。" +c021dfde-300c-4d74-a6a1-87a514c1bbe0 >> "反餘割在此未定義。" +c0c6a29f-abda-4676-9662-1d00f94f10a4 >> "反餘切在此未定義。" +47dcf91b-847c-48f0-9889-f5ce1b6831e3 >> "命令" +bcd0a3e9-3d89-4921-94b3-d7533d60911f >> "數值" +03fdd1f2-6ea5-49d4-ac3f-27f01f04a518 >> "計算模式:0 = 弧度 (默認),1 = 度,2 = 百分度。" +d1df3b60-dac1-496c-99bb-ba763dc551df >> "計算時所輸出的小數位數" +162adb13-c4b2-4418-b3df-edb6f9355d64 >> "分析程式" +6ad9958f-f127-4ee4-a4c6-94cf19576b9a >> "未知的命令 {0}" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ca89fa07..64330da66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,7 +20,7 @@ # SOFTWARE. # ##################################################################################################### -ADD_LIBRARY(util STATIC argParse.cpp colors.cpp logging.cpp symbols.cpp testing.cpp util.cpp) +ADD_LIBRARY(util STATIC argParse.cpp colors.cpp logging.cpp symbols.cpp testing.cpp util.cpp getString.cpp platform.cpp format.cpp) SET_TARGET_PROPERTIES(util PROPERTIES POSITION_INDEPENDENT_CODE ON) ADD_LIBRARY(steppable STATIC number.cpp fraction.cpp) diff --git a/src/abs/abs.cpp b/src/abs/abs.cpp index c6618a67e..11e0e3b49 100644 --- a/src/abs/abs.cpp +++ b/src/abs/abs.cpp @@ -30,18 +30,20 @@ #include "absReport.hpp" #include "argParse.hpp" +#include "getString.hpp" #include "util.hpp" #include +#include #include -#include using namespace steppable::__internals::utils; using namespace steppable::__internals::arithmetic; +using namespace steppable::localization; namespace steppable::__internals::arithmetic { - std::string abs(const std::string_view& _number, const int steps) + std::string abs(const std::string& _number, const int steps) { std::string number = static_cast(_number); return reportAbs(number, steps); @@ -53,9 +55,9 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number"); - program.addKeywordArg("steps", 2, "Amount of steps while taking the absolute value. 0 = No steps, 2 = All steps."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("abs", "ca70a6a7-d1d8-4e43-a94e-014d8f9839c9")); + program.addKeywordArg("steps", 2, $("abs", "3860a4ae-1073-4a6d-a75e-f64426291573")); + program.addSwitch("profile", false, $("abs", "5d7bddda-e33f-4f9c-81b2-d30baad2ec5c")); program.parseArgs(); const int steps = program.getKeywordArgument("steps"); @@ -65,7 +67,9 @@ int main(const int _argc, const char* _argv[]) if (profile) { TIC(Column Method Addition) - std::cout << "Taking absolute value :\n" << abs(number, steps) << '\n'; + std::cout << "Taking absolute value :" + << "\n" + << abs(number, steps) << '\n'; TOC() } else diff --git a/src/abs/absReport.cpp b/src/abs/absReport.cpp index 486bb8d97..b9032ebfa 100644 --- a/src/abs/absReport.cpp +++ b/src/abs/absReport.cpp @@ -29,17 +29,18 @@ * @date 12th January 2024 */ +#include "getString.hpp" #include "symbols.hpp" #include #include -#include #include using namespace steppable::__internals::numUtils; using namespace steppable::__internals::symbols; +using namespace steppable::localization; -std::string reportAbs(const std::string_view& number, int steps = 2) +std::string reportAbs(const std::string& number, int steps = 2) { std::stringstream ss; @@ -47,13 +48,29 @@ std::string reportAbs(const std::string_view& number, int steps = 2) { if (number[0] == '-') { - ss << "Since " << number << " is negative, abs(" << number << ") = -(" << number << ")\n"; - ss << THEREFORE << " The absolute value of " << number << " is " << standardizeNumber(number.substr(1)); + // Since + ss << $("abs", "f39c432d-9031-423a-a12f-1efcd3e113b2") + << number + // is negative, + << $("abs", "5c8a89a7-4cb1-40d8-b926-6ae84fc3a3ef") << "abs(" << number << ") = -(" << number << ")\n"; + // The absolute value of... + ss << THEREFORE + << $("abs", "8fd01dbe-c921-4f22-a0ab-d1348967e4b0", { number }) + // is + << $("abs", "7066c6e7-6b80-4671-bc61-6c0322204c87") << standardizeNumber(number.substr(1)); } else { - ss << "Since " << number << " is positive, abs(" << number << ") = " << number << '\n'; - ss << THEREFORE << " The absolute value of " << number << " is " << standardizeNumber(number); + // Since + ss << $("abs", "f39c432d-9031-423a-a12f-1efcd3e113b2") + << number + // Is positive,... + << $("abs", "b119f705-751b-425e-a758-47d755307700") << "abs(" << number << ") = " << number << '\n'; + // The absolute value of... + ss << THEREFORE + << $("abs", "8fd01dbe-c921-4f22-a0ab-d1348967e4b0", { number }) + // is + << $("abs", "7066c6e7-6b80-4671-bc61-6c0322204c87") << standardizeNumber(number); } } else if (steps == 1) diff --git a/src/abs/absReport.hpp b/src/abs/absReport.hpp index b7058a2d7..64abc45ce 100644 --- a/src/abs/absReport.hpp +++ b/src/abs/absReport.hpp @@ -32,7 +32,6 @@ #pragma once #include -#include /** * @brief Reports the absolute value of a number string to the user. @@ -42,4 +41,4 @@ * * @return The absolute value of the number. */ -std::string reportAbs(const std::string_view& number, int steps = 2); +std::string reportAbs(const std::string& number, int steps = 2); diff --git a/src/add/add.cpp b/src/add/add.cpp index 82a2c9673..241e3d355 100644 --- a/src/add/add.cpp +++ b/src/add/add.cpp @@ -31,22 +31,24 @@ #include "addReport.hpp" #include "argParse.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "util.hpp" #include #include -#include +#include #include using namespace steppable::__internals::numUtils; using namespace steppable::__internals::utils; using namespace steppable::__internals::arithmetic; using namespace steppable::__internals::symbols; +using namespace steppable::localization; namespace steppable::__internals::arithmetic { - std::string add(const std::string_view& a, - const std::string_view& b, + std::string add(const std::string& a, + const std::string& b, const int steps, const bool negative, const bool properlyFormat) @@ -56,7 +58,8 @@ namespace steppable::__internals::arithmetic std::stringstream ss; if (steps == 2) { - ss << BECAUSE << " a = 0, the result is " << b << '\n'; + // The result is... + ss << BECAUSE << " a = 0" << $("add", "ca3f0783-02d8-4006-8bbe-2311ffd708fa") << b << '\n'; ss << THEREFORE << " " << a << " + " << b << " = " << b; } else if (steps == 1) @@ -72,7 +75,8 @@ namespace steppable::__internals::arithmetic std::stringstream ss; if (steps == 2) { - ss << BECAUSE << " b = 0, the result is " << a << '\n'; + // The result is... + ss << BECAUSE << " b = 0" << $("add", "ca3f0783-02d8-4006-8bbe-2311ffd708fa") << a << '\n'; ss << THEREFORE << " " << a << " + " << b << " = " << a; } else if (steps == 1) @@ -99,13 +103,15 @@ namespace steppable::__internals::arithmetic else if (aIsNegative) { if (steps == 2) - std::cout << "Subtracting " << b << " from " << a << " since " << a << " is negative.\n"; + // Subtracting {0} from {1} since {2} is negative + std::cout << $("add", "547d6d96-de8d-4f2e-af3b-2da475d8d161", { b, a.substr(1), a }) << "\n"; return subtract(b, a.substr(1), steps); } else if (bIsNegative) { if (steps == 2) - std::cout << "Subtracting " << a << " from " << b << " since " << b << " is negative.\n"; + // Subtracting {0} from {1} since {2} is negative + std::cout << $("add", "547d6d96-de8d-4f2e-af3b-2da475d8d161", { a, b.substr(1), b }) << "\n"; return subtract(a, b.substr(1), steps); } @@ -162,10 +168,14 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number 1"); - program.addPosArg('b', "Number 2"); - program.addKeywordArg("steps", 2, "Amount of steps while adding. 0 = No steps, 2 = All steps."); - program.addSwitch("profile", false, "profiling the program"); + // Number 1 + program.addPosArg('a', $("add", "6e1121d2-75a4-4173-a54b-0b6c2f98abfc")); + // Number 2 + program.addPosArg('b', $("add", "852e4cdb-cb19-4717-95b3-eaec08777ebc")); + // Steps while adding... + program.addKeywordArg("steps", 2, $("add", "c935c960-609c-4ecd-97f5-d4f36d3bbc9f")); + // Profiling + program.addSwitch("profile", false, $("add", "6959b967-151d-44b0-a250-464f871d6dc1")); program.parseArgs(); const int steps = program.getKeywordArgument("steps"); @@ -176,7 +186,7 @@ int main(const int _argc, const char* _argv[]) if (profile) { TIC(Column Method Addition) - std::cout << "Column Method Addition :\n" << add(aStr, bStr) << '\n'; + std::cout << $("add", "0c7e9691-2777-4cb8-8ae6-e21206859c5d") << "\n" << add(aStr, bStr) << '\n'; TOC() } else diff --git a/src/argParse.cpp b/src/argParse.cpp index 6a1b7c4a6..de7a70d78 100644 --- a/src/argParse.cpp +++ b/src/argParse.cpp @@ -22,6 +22,7 @@ #include "argParse.hpp" #include "colors.hpp" +#include "getString.hpp" #include "output.hpp" #include "platform.hpp" #include "util.hpp" @@ -30,50 +31,49 @@ #include #include #include -#include #include using namespace std::literals; +using namespace steppable::localization; namespace steppable::__internals::utils { - void ProgramArgs::addSwitch(const std::string_view& name, - const bool defaultValue, - const std::string_view& description) + void ProgramArgs::addSwitch(const std::string& name, const bool defaultValue, const std::string& description) { switches.insert({ name, defaultValue }); switchDescriptions.insert_or_assign(name, description); } - void ProgramArgs::addKeywordArg(const std::string_view& name, int defaultValue, const std::string_view description) + void ProgramArgs::addKeywordArg(const std::string& name, int defaultValue, const std::string& description) { keywordArgs.insert({ name, defaultValue }); keywordArgDescriptions.insert({ name, description }); } - void ProgramArgs::addPosArg(const char name, const std::string_view& description, const bool requiresNumber) + void ProgramArgs::addPosArg(const char name, const std::string& description, const bool requiresNumber) { posArgDescriptions.insert({ name, description }); posArgIsNumber.push_back(requiresNumber); } - void ProgramArgs::printUsage(const std::string_view& reason) const + void ProgramArgs::printUsage(const std::string& reason) const { - std::cout << "Usage: " << formats::bold << programName << reset << " "; + std::cout << $("argParse", "91408f1e-6627-41e5-9707-d8a660c2b86b") << formats::bold << programName << reset + << " "; if (not posArgDescriptions.empty()) for (const auto& posArg : posArgDescriptions | std::views::keys) std::cout << colors::brightGreen << '<' << posArg << '>' << " "; if (not switchDescriptions.empty()) - std::cout << colors::brightGreen << "[switches] " << reset; + std::cout << colors::brightGreen << $("argParse", "38f61169-17f1-4a49-870b-814745cdf4c6") << reset; if (not keywordArgDescriptions.empty()) - std::cout << colors::brightGreen << "[keywordArguments] " << reset; + std::cout << colors::brightGreen << $("argParse", "4f332974-1fd1-43eb-bbbc-8d32071ed735") << reset; std::cout << '\n'; if (not posArgDescriptions.empty()) { - std::cout << formats::bold << "Available positional arguments:" << reset << '\n'; + std::cout << formats::bold << $("argParse", "5d482eea-c4e4-4c4d-89f0-6b33fcc9618c") << reset << '\n'; for (const auto& [posArgName, posArgDescription] : posArgDescriptions) { std::cout << colors::brightGreen << formats::bold << '<' << posArgName << '>' << reset; @@ -87,19 +87,19 @@ namespace steppable::__internals::utils if (not switchDescriptions.empty()) { - std::cout << formats::bold << "Available switches:" << reset << '\n'; + std::cout << formats::bold << $("argParse", "10b1c33b-070f-4dfb-be12-a1a4349e76bc") << reset << '\n'; for (const auto& [switchName, switchDescription] : switchDescriptions) { std::cout << colors::brightGreen << formats::bold << '[' << '-' << switchName << "] "; std::cout << '[' << '+' << switchName << "]" << reset << '\n'; - std::cout << " Enables/Disables " << switchDescription << '\n'; + std::cout << $("argParse", "227375c6-6ec8-479e-ad39-59f975272c6b") << switchDescription << '\n'; } std::cout << reset << '\n'; } if (not keywordArgDescriptions.empty()) { - std::cout << formats::bold << "Available keyword arguments:" << reset << '\n'; + std::cout << formats::bold << $("argParse", "be2d8c84-0dfc-4f52-b450-e34d1cf20c91") << reset << '\n'; for (const auto& [keywordArgName, keywordArgDescription] : keywordArgDescriptions) { std::cout << colors::brightGreen << formats::bold << '[' << '-' << keywordArgName << ": ]" @@ -112,40 +112,40 @@ namespace steppable::__internals::utils if (not reason.empty()) { std::cerr << '\n'; - output::error("ProgramArgs::printUsage", std::string(reason)); + output::error("ProgramArgs::printUsage"s, "{0}"s, { reason }); } // Print the footnote only if there are positional arguments that require a number if (std::ranges::any_of(posArgIsNumber, [](const bool isNumber) { return isNumber; })) - std::cout << "(*) Requires a number\n"; + std::cout << $("argParse", "fd67fddb-ca42-4a79-b852-c0bc71aa9969") << "\n"; programSafeExit(-1); } - std::string_view ProgramArgs::getPosArg(const size_t index) const + std::string ProgramArgs::getPosArg(const size_t index) const { if (posArgs.size() <= index) - printUsage("Missing positional argument: " + std::to_string(index)); + printUsage($("argParse", "b782de55-513d-4eda-b068-98d2d6210603") + std::to_string(index)); return posArgs[index]; } - int ProgramArgs::getKeywordArgument(const std::string_view& name) + int ProgramArgs::getKeywordArgument(const std::string& name) { if (not keywordArgs.contains(name)) - printUsage("Missing switch: " + static_cast(name)); + printUsage($("argParse", "aa26a7f2-0949-454e-b987-42b40348e104") + name); return keywordArgs[name]; } - bool ProgramArgs::getSwitch(const std::string_view& name) + bool ProgramArgs::getSwitch(const std::string& name) { if (not switches.contains(name)) - printUsage("Missing switch: " + static_cast(name)); + printUsage($("argParse", "2b854b9f-da27-483e-a016-0eb0d26eb9e9") + name); return switches[name]; } - ProgramArgs::ProgramArgs(const int _argc, const char** _argv) : argc(_argc - 1) + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + ProgramArgs::ProgramArgs(const int _argc, const char** _argv) : argc(_argc - 1), programName(_argv[0]) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - programName = _argv[0]; // Call this program whatever the user calls it + // Call this program whatever the user calls it PosArgs pos; // Copy the arguments into a vector @@ -157,7 +157,7 @@ namespace steppable::__internals::utils void ProgramArgs::parseArgs() { - for (auto _arg : argv) + for (const auto& _arg : argv) { auto arg = static_cast(_arg); if (std::smatch match; std::regex_match(arg, match, KEYWORD_ARG_REGEX)) @@ -177,7 +177,8 @@ namespace steppable::__internals::utils { if (not numUtils::isNumber(_arg) and posArgIsNumber[posArgs.size()]) { - output::error("ProgramArgs::parseArgs", "Invalid argument: %s"s, _arg); + output::error("ProgramArgs::parseArgs"s, + $("argParse", "34782921-b560-4706-a2c9-d5c326af2cff", { _arg })); programSafeExit(-1); } posArgs.push_back(_arg); diff --git a/src/baseConvert/baseConvert.cpp b/src/baseConvert/baseConvert.cpp index ff2ed0bbe..1139c5aec 100644 --- a/src/baseConvert/baseConvert.cpp +++ b/src/baseConvert/baseConvert.cpp @@ -23,7 +23,6 @@ /** * @file baseConvert.cpp * @brief This file contains the implementation of the baseConvert function, which converts any number to any base. - * @warning Still work-in-progress. * * @author Andy Zhang * @date 9th October 2023 @@ -32,18 +31,19 @@ #include "argParse.hpp" #include "baseConvertReport.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "output.hpp" #include "symbols.hpp" #include "util.hpp" #include -#include #include using namespace std::literals; using namespace steppable::__internals::stringUtils; using namespace steppable::__internals::arithmetic; using namespace steppable::__internals::symbols; +using namespace steppable::localization; using namespace steppable::output; namespace steppable::prettyPrint::printers @@ -69,7 +69,7 @@ namespace steppable::__internals::arithmetic * @param[in] _number The number in decimal form. * @returns The number represented using alphabets and numberals. */ - std::string representNumber(const std::string_view& _number) + std::string representNumber(const std::string& _number) { if (compare(_number, "10", 0) != "1") { @@ -78,12 +78,13 @@ namespace steppable::__internals::arithmetic } const int number = std::stoi(static_cast(_number)); if (number > 10) + // Do not localize. throw std::invalid_argument("Number should be a single digit or a letter from A to Z"); const unsigned char letter = 'A' + static_cast(number) - 10; return { 1, static_cast(letter) }; } - std::string baseConvert(const std::string_view& _number, const std::string_view& baseStr, const int steps) + std::string baseConvert(const std::string& _number, const std::string& baseStr, const int steps) { const size_t base = std::stoll(static_cast(baseStr)); auto numberOrig = static_cast(_number); @@ -91,12 +92,14 @@ namespace steppable::__internals::arithmetic if (base > 36) { - error("baseConvert"s, "It is impossilbe to represent a number in base greater than 36"s); + // It is impossible to convert to a base greater than 36. + error("baseConvert"s, $("baseConvert", "4e5a4863-4e4a-44f1-a782-e74de6b93469")); return "Impossible"; } if (base == 0 or base == 1) { - error("baseConvert"s, "Conversion to base 0 or 1 is not possible"s); + // It is impossible to convert to a base of 0 or 1. + error("baseConvert"s, $("baseConvert", "783e7915-f4a3-4973-9747-2d8de3de5545")); return "Impossible"; } @@ -128,13 +131,12 @@ namespace steppable::__internals::arithmetic #ifndef NO_MAIN int main(const int _argc, const char* _argv[]) { - std::cout << steppable::prettyPrint::printers::ppSubscript("342", "32341"); Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number to convert"); - program.addPosArg('b', "Base of the number"); - program.addKeywordArg("steps", 2, "Amount of steps while converting. 0 = No steps, 2 = All steps."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("baseConvert", "f3211410-9b0d-49f6-8797-c4756b2fee28")); + program.addPosArg('b', $("baseConvert", "61826029-8d77-4133-8bc7-7f03365bd9a3")); + program.addKeywordArg("steps", 2, $("baseConvert", "f988a0b2-decd-4d0c-a2e2-dd4127c1e83b")); + program.addSwitch("profile", false, $("baseConvert", "0826ae41-c7f6-4e1f-a932-2f6c00930a05")); program.parseArgs(); const int steps = program.getKeywordArgument("steps"); @@ -145,7 +147,8 @@ int main(const int _argc, const char* _argv[]) if (profile) { TIC(baseConvert) - std::cout << "baseConvert :\n" << baseConvert(aStr, bStr) << '\n'; + std::cout << $("baseConvert", "74dd79f5-7c24-4b39-bf66-59a3570e4a03") << "\n" + << baseConvert(aStr, bStr) << '\n'; TOC() } else diff --git a/src/baseConvert/baseConvertReport.cpp b/src/baseConvert/baseConvertReport.cpp index 086f8d262..9e9b950a3 100644 --- a/src/baseConvert/baseConvertReport.cpp +++ b/src/baseConvert/baseConvertReport.cpp @@ -32,16 +32,17 @@ #include "baseConvertReport.hpp" +#include "getString.hpp" #include "symbols.hpp" #include #include #include -#include #include using namespace std::string_literals; using namespace steppable::__internals::symbols; +using namespace steppable::localization; std::string reportBaseConvertStep(const std::string& _number, const std::string& _base, @@ -61,7 +62,7 @@ std::string reportBaseConvert(const std::string& _number, std::stringstream ss; if (steps == 2) - ss << THEREFORE << " The number " << _number << " in base " << _base << " is "; + ss << THEREFORE << $("baseConvert", "8a0b5c6d-b1a8-49b4-99fd-b1710744f4bf", { _number, _base }); else if (steps == 1) ss << _number << steppable::__internals::symbols::makeSubscript("10") << " = "; // Output the result in reverse order diff --git a/src/comparison/comparison.cpp b/src/comparison/comparison.cpp index c299cfbd4..9dd5a8516 100644 --- a/src/comparison/comparison.cpp +++ b/src/comparison/comparison.cpp @@ -21,7 +21,7 @@ **************************************************************************************************/ /** - * @file comparision.cpp + * @file comparison.cpp * @brief This file contains the implementation of the compare function, which compares two numbers. * * @author Andy Zhang @@ -30,33 +30,33 @@ #include "argParse.hpp" #include "comparisonReport.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "util.hpp" #include #include -#include using namespace steppable::__internals::numUtils; using namespace steppable::__internals::symbols; using namespace steppable::__internals::utils; using namespace steppable::__internals::arithmetic; +using namespace steppable::localization; namespace steppable::__internals::arithmetic { - std::string compare(const std::string_view& _a, const std::string_view& _b, const int steps) + std::string compare(const std::string& _a, const std::string& _b, const int steps) { if (standardizeNumber(_a) == standardizeNumber(_b)) { std::stringstream ss; if (steps == 2) { - ss << BECAUSE << " " << static_cast(_a) << " is identical to " - << static_cast(_b); - ss << ", " << THEREFORE << " a = b"; + ss << BECAUSE << $("comparison", "bd4f865a-ce08-4825-ac74-f824e4da2fed", { _a, _b }) << THEREFORE + << " a = b"; return ss.str(); } if (steps == 1) - return static_cast(_a) + " = " + static_cast(_b); + return _a + " = " + _b; return "2"; } const auto [splitNumberArray, aIsNegative, bIsNegative] = splitNumber(_a, _b, false, true); @@ -111,7 +111,7 @@ namespace steppable::__internals::arithmetic } if (steps == 1) - return "Equal"; + return $("comparison", "c49d968f-31df-4654-b13b-0f16212f4591"); if (steps == 2) { std::stringstream ss; @@ -127,10 +127,10 @@ int main(int _argc, const char** _argv) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number 1"); - program.addPosArg('b', "Number 2"); - program.addKeywordArg("steps", 2, "Amount of steps while comparing"); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("comparison", "1d411edd-f7a6-4ad5-8a0a-cc8b5eea01b1")); + program.addPosArg('b', $("comparison", "0972be2d-ce73-4226-82d8-778fb5293894")); + program.addKeywordArg("steps", 2, $("comparison", "07ff2704-10c1-4eea-bba2-bd63116ca34b")); + program.addSwitch("profile", false, $("comparison", "b930c709-22e7-46f8-9cdf-5ed193469964")); program.parseArgs(); int steps = program.getKeywordArgument("steps"); diff --git a/src/comparison/comparisonReport.cpp b/src/comparison/comparisonReport.cpp index 809ae29ed..1833b491e 100644 --- a/src/comparison/comparisonReport.cpp +++ b/src/comparison/comparisonReport.cpp @@ -21,9 +21,9 @@ **************************************************************************************************/ /** - * @file comparisionReport.cpp + * @file comparisonReport.cpp * @brief This file contains the implementation of functions reportComparisonAtInteger, reportComparisonByPolarity and - * reportComparisonByDigit, which reports the result of the comparision from the integer part, polarity and digit + * reportComparisonByDigit, which reports the result of the comparison from the integer part, polarity and digit * respectively. * * @author Andy Zhang @@ -32,32 +32,35 @@ #include "comparisonReport.hpp" +#include "getString.hpp" #include "symbols.hpp" #include -#include +#include using namespace steppable::__internals::symbols; +using namespace steppable::localization; -std::string reportComparisonAtInteger(const std::string_view& a, - const std::string_view& b, - const bool bigger, - const int steps) +std::string reportComparisonAtInteger(const std::string& a, const std::string& b, const bool bigger, const int steps) { std::stringstream ss; if (steps == 2) { - ss << "Comparing the integer part of a and b" << '\n'; + ss << $("comparison", "0095d521-ccba-4c5b-b33f-9d9f2b3d18e3", { a, b }) << '\n'; if (bigger) { - ss << BECAUSE << " The integer part of " << a << " is bigger than the integer part of " << b << '\n'; - ss << THEREFORE << " " << a << " is greater than " << b; + // The integer part of {0} is greater than that of {1} + ss << BECAUSE << $("comparison", "1b7ea6d8-9909-4589-8d59-b3eb7121cdee", { a, b }) << '\n'; + // {0} is greater than {1} + ss << THEREFORE << $("comparison", "aaad3a6a-1257-478a-b3d1-245c4dc0e6fb", { a, b }); } else { - ss << BECAUSE << " The integer part of " << b << " is bigger than the integer part of " << a << '\n'; - ss << THEREFORE << " " << a << " is less than " << b; + // The integer part of {0} is greater than that of {1} + ss << BECAUSE << $("comparison", "1b7ea6d8-9909-4589-8d59-b3eb7121cdee", { b, a }) << '\n'; + // {0} is less than {1} + ss << THEREFORE << $("comparison", "ec120274-c8f2-4a41-9e64-b7b0d011d20e", { a, b }); } } else if (steps == 1) @@ -68,25 +71,24 @@ std::string reportComparisonAtInteger(const std::string_view& a, return ss.str(); } -std::string reportComparisonByPolarity(const std::string_view& a, - const std::string_view& b, - const bool greater, - const int steps) +std::string reportComparisonByPolarity(const std::string& a, const std::string& b, const bool greater, const int steps) { std::stringstream ss; if (steps == 2) { - ss << "Comparing the polarities of a and b" << '\n'; + // Comparing the polarities of {0} and {1} + ss << $("comparison", "09a9b12d-7b58-4626-b7c8-62a16933bfce", { a, b }) << '\n'; if (greater) { - ss << BECAUSE << " " << a << " is positive and " << b << " is negative" << '\n'; - ss << THEREFORE << " " << a << " is greater than " << b; + // {0} is positive and {1} is negative + ss << BECAUSE << $("comparison", "eb150ad5-09a5-4be6-8400-988e6f0eb252", { a, b }) << '\n'; + ss << THEREFORE << $("comparison", "aaad3a6a-1257-478a-b3d1-245c4dc0e6fb", { a, b }); } else { - ss << BECAUSE << " " << a << " is negative and " << b << " is positive" << '\n'; - ss << THEREFORE << " " << a << " is less than " << b; + ss << BECAUSE << $("comparison", "237615f7-6c35-4ca2-a791-43d8ccc925dd", { a, b }) << '\n'; + ss << THEREFORE << $("comparison", "ec120274-c8f2-4a41-9e64-b7b0d011d20e", { a, b }); } } else if (steps == 1) @@ -97,8 +99,8 @@ std::string reportComparisonByPolarity(const std::string_view& a, return ss.str(); } -std::string reportComparisonByDigit(const std::string_view& a, - const std::string_view& b, +std::string reportComparisonByDigit(const std::string& a, + const std::string& b, const size_t _digit, const bool greater, const bool bothNegative, @@ -113,15 +115,23 @@ std::string reportComparisonByDigit(const std::string_view& a, if (greater) { - ss << std::string(digit + 4, ' ') << "^~~~~ " << BECAUSE << " At digit " << digit + 1 << ", " << a[digit] - << " is greater than " << b[digit] << '\n'; - ss << THEREFORE << " " << a << " is greater than " << b; + // At digit {0}... + ss << std::string(digit + 4, ' ') << "^~~~~ " << BECAUSE + << $("comparison", + "ab1363eb-bfdb-44a9-89ee-b125a8d60cbd", + { std::to_string(digit + 1), std::string(1, a[digit]), std::string(1, b[digit]) }) + << '\n'; + ss << THEREFORE << $("comparison", "aaad3a6a-1257-478a-b3d1-245c4dc0e6fb", { a, b }); } else { - ss << std::string(digit + 4, ' ') << "^~~~~ " << BECAUSE << " At digit " << digit + 1 << ", " << a[digit] - << " is less than " << b[digit] << '\n'; - ss << THEREFORE << " " << a << " is less than " << b; + // At digit {0}... + ss << std::string(digit + 4, ' ') << "^~~~~ " << BECAUSE + << $("comparison", + "ab1363eb-bfdb-44a9-89ee-b125a8d60cbd", + { std::to_string(digit + 1), std::string(1, b[digit]), std::string(1, a[digit]) }) + << '\n'; + ss << THEREFORE << $("comparison", "ec120274-c8f2-4a41-9e64-b7b0d011d20e", { a, b }); } } else if (steps == 1) diff --git a/src/comparison/comparisonReport.hpp b/src/comparison/comparisonReport.hpp index 50ddb6aa4..53f692b9e 100644 --- a/src/comparison/comparisonReport.hpp +++ b/src/comparison/comparisonReport.hpp @@ -34,7 +34,6 @@ #include #include -#include /** * @brief Reports the comparison based on the integer. If the integer parts are of different length, the one with longer @@ -47,7 +46,7 @@ * * @returns The comparison result. */ -std::string reportComparisonAtInteger(const std::string_view& a, const std::string_view& b, bool bigger, int steps = 2); +std::string reportComparisonAtInteger(const std::string& a, const std::string& b, bool bigger, int steps = 2); /** * @brief Reports the comparison based on the polarity. If they are of different polarity, the one that is positive is @@ -60,10 +59,7 @@ std::string reportComparisonAtInteger(const std::string_view& a, const std::stri * * @returns The comparison result. */ -std::string reportComparisonByPolarity(const std::string_view& a, - const std::string_view& b, - bool greater, - int steps = 2); +std::string reportComparisonByPolarity(const std::string& a, const std::string& b, bool greater, int steps = 2); /** * @brief Compares each digit and see if one is larger. @@ -78,8 +74,8 @@ std::string reportComparisonByPolarity(const std::string_view& a, * * @returns The comparison result. */ -std::string reportComparisonByDigit(const std::string_view& a, - const std::string_view& b, +std::string reportComparisonByDigit(const std::string& a, + const std::string& b, size_t digit, bool greater, bool bothNegative, diff --git a/src/decimalConvert/decimalConvert.cpp b/src/decimalConvert/decimalConvert.cpp index c8b63e178..bd1888bcf 100644 --- a/src/decimalConvert/decimalConvert.cpp +++ b/src/decimalConvert/decimalConvert.cpp @@ -28,6 +28,7 @@ #include "argParse.hpp" #include "decimalConvertReport.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "util.hpp" #include @@ -38,6 +39,7 @@ using namespace steppable::__internals::numUtils; using namespace steppable::__internals::utils; using namespace steppable::__internals::symbols; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::arithmetic; namespace steppable::__internals::arithmetic @@ -58,20 +60,20 @@ namespace steppable::__internals::arithmetic // Where A is the 10th numeral. if ('A' <= input and input <= 'Z') return std::to_string(input - 'A' + 10); + // Do not localize. throw std::runtime_error("Cannot convert "s + _input + " to Number"); } - std::string decimalConvert(const std::string_view& _inputString, const std::string_view& baseString, int steps) + std::string decimalConvert(const std::string& _inputString, const std::string& baseString, int steps) { if (compare(baseString, "36", 0) == "1") { - error("decimalConvert", - "The base is larger than 36, which means that it is impossible to represent the number."s); - return ""; + error("decimalConvert", $("decimalConvert", "cbb9ed62-1127-4e1d-95ef-e75cc7fb2837")); + return "Impossible"; } std::string converted = "0"; - std::string inputString = static_cast(_inputString); + std::string inputString = _inputString; std::ranges::reverse(inputString); auto maxWidth = power(baseString, std::to_string(_inputString.length()), 0).length(); @@ -85,8 +87,8 @@ namespace steppable::__internals::arithmetic if (compare(digit, baseString, 0) != "0") { error("decimalConvert", - "The digit "s + digit + " is larger than the base " + static_cast(baseString)); - return ""; + $("decimalConvert", "e97b6539-8f69-4ccb-a50e-82a66aff2898", { digit, baseString })); + return "Impossible"; } auto placeValue = power(baseString, std::to_string(index), 0); auto convertedDigit = multiply(placeValue, digit, 0); @@ -106,10 +108,10 @@ int main(int _argc, const char* _argv[]) { [[maybe_unused]] Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number in the base", false); - program.addPosArg('b', "Base number"); - program.addKeywordArg("steps", 2, "Amount of steps while converting the number. 0 = No steps, 2 = All steps."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("decimalConvert", "53053bf2-84ba-4b63-9f27-d334dc38b60d"), false); + program.addPosArg('b', $("decimalConvert", "b771e8bc-9b66-4b4d-b9ff-fd4111111cf4")); + program.addKeywordArg("steps", 2, $("decimalConvert", "b461a3e5-12c3-48ea-aaba-2b4e234f3234")); + program.addSwitch("profile", false, $("decimalConvert", "d14e05b6-cb8e-43a5-9ab2-11f960f4e199")); program.parseArgs(); int steps = program.getKeywordArgument("steps"); @@ -120,7 +122,8 @@ int main(int _argc, const char* _argv[]) if (profile) { TIC(Decimal Conversion) - std::cout << "Decimal Conversion :\n" << decimalConvert(inputString, baseString, steps) << '\n'; + std::cout << $("decimalConvert", "d1536a73-2eb9-4bf9-8b25-00ff88038dab") << "\n" + << decimalConvert(inputString, baseString, steps) << '\n'; TOC() } else diff --git a/src/decimalConvert/decimalConvertReport.cpp b/src/decimalConvert/decimalConvertReport.cpp index bb2a83179..2235e216f 100644 --- a/src/decimalConvert/decimalConvertReport.cpp +++ b/src/decimalConvert/decimalConvertReport.cpp @@ -27,14 +27,13 @@ #include #include #include -#include using namespace steppable::__internals::symbols; -std::string reportDecimalConvertStep(const std::string_view& baseString, - const std::string_view& digit, +std::string reportDecimalConvertStep(const std::string& baseString, + const std::string& digit, const size_t powerIndex, - const std::string_view& convertedDigit, + const std::string& convertedDigit, const size_t maxWidth) { std::stringstream ss; @@ -45,9 +44,9 @@ std::string reportDecimalConvertStep(const std::string_view& baseString, return ss.str(); } -std::string reportDecimalConvert(const std::string_view& inputString, - const std::string_view& baseString, - const std::string_view& convertedString, +std::string reportDecimalConvert(const std::string& inputString, + const std::string& baseString, + const std::string& convertedString, const int steps) { if (steps == 0) diff --git a/src/decimalConvert/decimalConvertReport.hpp b/src/decimalConvert/decimalConvertReport.hpp index 1f44dfee7..820d5eef0 100644 --- a/src/decimalConvert/decimalConvertReport.hpp +++ b/src/decimalConvert/decimalConvertReport.hpp @@ -24,13 +24,13 @@ #include -std::string reportDecimalConvertStep(const std::string_view& baseString, - const std::string_view& digit, +std::string reportDecimalConvertStep(const std::string& baseString, + const std::string& digit, size_t powerIndex, - const std::string_view& convertedDigit, + const std::string& convertedDigit, size_t maxWidth); -std::string reportDecimalConvert(const std::string_view& inputString, - const std::string_view& baseString, - const std::string_view& convertedString, +std::string reportDecimalConvert(const std::string& inputString, + const std::string& baseString, + const std::string& convertedString, int steps = 2); diff --git a/src/division/division.cpp b/src/division/division.cpp index 9435a8a04..957af62d4 100644 --- a/src/division/division.cpp +++ b/src/division/division.cpp @@ -31,6 +31,7 @@ #include "argParse.hpp" #include "divisionReport.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "output.hpp" #include "rounding.hpp" #include "util.hpp" @@ -40,11 +41,11 @@ #include #include #include -#include using namespace steppable::__internals::numUtils; using namespace steppable::__internals::stringUtils; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::arithmetic; namespace steppable::__internals::arithmetic @@ -114,25 +115,18 @@ namespace steppable::__internals::arithmetic return diffScale; } - std::string divide(const std::string_view& _number, - const std::string_view& _divisor, - const int steps, - const int _decimals) + std::string divide(const std::string& _number, const std::string& _divisor, const int steps, const int _decimals) { if (isZeroString(_number) and isZeroString(_divisor)) { // Easter egg in open-source code - error("division", - "Imagine that you have zero cookies and you split them evenly among zero friends, how many " - "cookies does " - "each person get? See? It doesn't make sense. And Cookie Monster is sad that there are no " - "cookies, and " - "you are sad that you have no friends."s); + error("division", $("division", "e8ad759d-fcb8-4280-a7a8-a637ae834ffc")); return "Indeterminate"; } if (isZeroString(_divisor)) { - error("division", "Division of %s by zero leads to infinity."s, std::string(_number).c_str()); + // Division by zero leads to infinity. + error("division", $("division", "977f3c9f-01c3-49e4-bf4a-94d7c58bbe82", { _number })); return "Infinity"; } @@ -140,7 +134,8 @@ namespace steppable::__internals::arithmetic { std::stringstream ss; if (steps == 2) - ss << "Since " << _number << " is equal to " << _divisor << ", " << THEREFORE << " the result is 1"; + // Since the number is equal to the divisor, the result is 1. + ss << $("division", "b4cace82-0076-40f3-85de-92aa1a81df44", { _number, _divisor }); else if (steps == 1) ss << _number << " " << DIVIDED_BY << " " << _divisor << " = 1"; else @@ -228,7 +223,8 @@ namespace steppable::__internals::arithmetic if ((numberIntegers < 0) and (-numberIntegers >= decimals)) { if (steps != 0) - warning("The result is inaccurate, as the decimals you specified is not enough to display the result."); + // Warn the user that the result is inaccurate. + warning("division"s, $("division", "d38c283c-e75d-4cc2-a634-bf1b3361d489")); return "0"; } @@ -284,7 +280,7 @@ namespace steppable::__internals::arithmetic return { quotient, remainder }; } - std::string getGCD(const std::string_view& _a, const std::string_view& _b) + std::string getGCD(const std::string& _a, const std::string& _b) { // Sign for GCD does not matter. // https://proofwiki.org/wiki/GCD_for_Negative_Integers @@ -314,11 +310,11 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number 1"); - program.addPosArg('b', "Number 2"); - program.addKeywordArg("steps", 2, "Amount of steps while dividing. 0 = No steps, 2 = All steps."); - program.addKeywordArg("decimals", 5, "Decimals to output"); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("division", "e7bbfa43-684d-498a-b10f-d8a76a371583")); + program.addPosArg('b', $("division", "9e6d7430-7006-4c77-ad4a-00955080765c")); + program.addKeywordArg("steps", 2, $("division", "797de85c-787c-4c05-bc42-763da058f9e0")); + program.addKeywordArg("decimals", 5, $("division", "e10fcce8-4bb3-4b3b-9820-33571065a8ee")); + program.addSwitch("profile", false, $("division", "98a3f915-5e93-4417-942a-071b2d9a13b3")); program.parseArgs(); const int steps = program.getKeywordArgument("steps"); @@ -334,8 +330,9 @@ int main(const int _argc, const char* _argv[]) } if (profile) { - TIC(Column Method Division) - std::cout << "Column Method Division :\n" << divide(aStr, bStr, steps, decimals) << '\n'; + TIC(Column method division) + std::cout << $("division", "bc2c8ff9-2d67-45e9-8824-2bc971e21cc9") << "\n" + << divide(aStr, bStr, steps, decimals) << '\n'; TOC() } else diff --git a/src/division/divisionReport.cpp b/src/division/divisionReport.cpp index ca6cb3b72..8ce8e3d33 100644 --- a/src/division/divisionReport.cpp +++ b/src/division/divisionReport.cpp @@ -36,7 +36,6 @@ #include #include -#include using namespace std::literals; using namespace steppable::__internals::stringUtils; @@ -44,11 +43,11 @@ using namespace steppable::__internals::symbols; using namespace steppable::__internals::arithmetic; std::string reportDivision(std::stringstream& tempFormattedAns, - const std::string_view& temp, - const std::string_view& ans, - const std::string_view& divisor, - const std::string_view& _divisor, - const std::string_view& _number, + const std::string& temp, + const std::string& ans, + const std::string& divisor, + const std::string& _divisor, + const std::string& _number, const int steps, const int width, const bool resultIsNegative) @@ -57,9 +56,8 @@ std::string reportDivision(std::stringstream& tempFormattedAns, if (steps == 2) { - tempFormattedAns << std::string(width - temp.length(), ' ') << makeWider(static_cast(temp)) - << '\n'; - formattedAns << std::string(width - ans.length(), ' ') << makeWider(static_cast(ans)) << '\n'; + tempFormattedAns << std::string(width - temp.length(), ' ') << makeWider(temp) << '\n'; + formattedAns << std::string(width - ans.length(), ' ') << makeWider(ans) << '\n'; formattedAns << std::string(divisor.length() * 3 - 1, ' '); formattedAns << std::string(width - divisor.length() * 2, '_') << '\n'; formattedAns << tempFormattedAns.rdbuf(); @@ -80,12 +78,12 @@ std::string reportDivision(std::stringstream& tempFormattedAns, return static_cast(ans); } -std::string reportDivisionStep(const std::string_view& temp, - const std::string_view& quotient, - const std::string_view& divisor, +std::string reportDivisionStep(const std::string& temp, + const std::string& quotient, + const std::string& divisor, size_t width, size_t index, - const std::string_view lastRemainder) + const std::string& lastRemainder) { std::stringstream ss; diff --git a/src/division/divisionReport.hpp b/src/division/divisionReport.hpp index d7c94ffde..fbeb45128 100644 --- a/src/division/divisionReport.hpp +++ b/src/division/divisionReport.hpp @@ -33,7 +33,6 @@ #include #include -#include /** * @brief Reports a division operation to the user. @@ -51,11 +50,11 @@ * @return The formatted report. */ std::string reportDivision(std::stringstream& tempFormattedAns, - const std::string_view& temp, - const std::string_view& ans, - const std::string_view& divisor, - const std::string_view& _divisor, - const std::string_view& _number, + const std::string& temp, + const std::string& ans, + const std::string& divisor, + const std::string& _divisor, + const std::string& _number, int steps, int width, bool resultIsNegative); @@ -72,9 +71,9 @@ std::string reportDivision(std::stringstream& tempFormattedAns, * * @return The formatted division step report. */ -std::string reportDivisionStep(const std::string_view& temp, - const std::string_view& quotient, - const std::string_view& divisor, +std::string reportDivisionStep(const std::string& temp, + const std::string& quotient, + const std::string& divisor, size_t width, size_t index, - std::string_view lastRemainder); + const std::string& lastRemainder); diff --git a/src/factorial/factorial.cpp b/src/factorial/factorial.cpp index 0cd22e46c..d38a32f2f 100644 --- a/src/factorial/factorial.cpp +++ b/src/factorial/factorial.cpp @@ -31,17 +31,19 @@ #include "argParse.hpp" #include "factorialReport.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "output.hpp" #include "util.hpp" #include -#include +#include using namespace steppable::__internals::numUtils; using namespace steppable::__internals::utils; using namespace steppable::__internals::arithmetic; using namespace steppable::__internals::symbols; using namespace steppable::output; +using namespace steppable::localization; using namespace std::literals; namespace steppable::__internals::arithmetic @@ -60,19 +62,19 @@ namespace steppable::__internals::arithmetic // / 0 // and factorial is defined as // n! = n * G(n) ,where n is a non-zero decimal ............ (2) - error("factorial"s, "%s is not an integer."s, number.c_str()); + error("factorial"s, $("factorial", "4eeba5fa-a5b8-4abf-ae65-22a466da6d18", { number })); return "0"; } if (isZeroString(number)) { if (steps == 2) - return "By definition, 0! = 1"; + return $("factorial", "d023ddb5-8a71-441b-8c67-8836bd94e93d"); return "1"; // By definition, 0! = 1 } // Negative numbers do not have a factorial. if (number.front() == '-') { - error("factorial"s, "%s is negative."s, number.c_str()); + error("factorial"s, $("factorial", "69d93fb8-1bb7-4ed2-be6d-8eeafd5f23a6", { number })); return "0"; } @@ -89,9 +91,9 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number"); - program.addKeywordArg("steps", 2, "Amount of steps while calculating the factorial. 0 = No steps, 2 = All steps."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("factorial", "135326d7-4e93-46d1-9e0e-8407eab6307b")); + program.addKeywordArg("steps", 2, $("factorial", "7e1e72c2-256d-4b71-84b6-65166937d7ba")); + program.addSwitch("profile", false, $("factorial", "b781d070-00e5-4c26-a56a-c0ad9504c0e3")); program.parseArgs(); const int steps = program.getKeywordArgument("steps"); @@ -101,7 +103,7 @@ int main(const int _argc, const char* _argv[]) if (profile) { TIC(Factorial) - std::cout << "Factorial :\n" << factorial(number, steps) << '\n'; + std::cout << $("factorial", "3ab32522-695e-4551-9542-0eb1824c8bd2") << "\n" << factorial(number, steps) << '\n'; TOC() } else diff --git a/src/format.cpp b/src/format.cpp new file mode 100644 index 000000000..8e80f7f73 --- /dev/null +++ b/src/format.cpp @@ -0,0 +1,89 @@ +/************************************************************************************************** + * Copyright (c) 2023-2024 NWSOFT * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **************************************************************************************************/ + +#include "format.hpp" + +#include +#include +#include +#include + +namespace steppable::__internals::format +{ + + std::string format(const std::string& format, const std::vector& args) + { + // Format string + // Original format: + // {0} -> args[0] + // {1} -> args[1] + // ... + // {n} -> args[n] + + std::string result = format; + std::string index; + bool inBrackets = false; + for (size_t idx = 0; idx < format.size(); idx++) + { + char i = format.at(idx); + switch (i) + { + // Start replacing! + case '{': + { + inBrackets = true; + index.erase(index.begin(), index.end()); + break; + } + + // End replacing + case '}': + { + inBrackets = false; + // SIZE_MAX is 20 digits long, so we can safely assume that the index must not be longer than 20 + // characters. + if (index.length() > 20 or index.length() < 1) + throw std::length_error("Argument index too long or too short."); + if (not std::ranges::all_of(index, [](const char& c) { return std::isdigit(c); })) + throw std::invalid_argument("Argument index must be a number."); + + size_t argIndex = std::stoull(index); + if (argIndex >= args.size()) + throw std::out_of_range("Argument index out of range."); + + // +1 for the closing bracket + result.replace(result.find("{" + index), index.size() + 2, args.at(argIndex)); + break; + } + + default: + { + if (inBrackets) + index += i; + break; + } + } + } + + return result; + } +} // namespace steppable::__internals::format diff --git a/src/getString.cpp b/src/getString.cpp new file mode 100644 index 000000000..cee6c75fa --- /dev/null +++ b/src/getString.cpp @@ -0,0 +1,161 @@ +/************************************************************************************************** + * Copyright (c) 2023-2024 NWSOFT * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **************************************************************************************************/ + +#include "getString.hpp" + +#include "output.hpp" +#include "platform.hpp" +#include "util.hpp" + +#include +#include +#include + +// DO NOT LOCALIZE + +namespace steppable::localization +{ + using namespace steppable::__internals::utils; + using namespace steppable::__internals::stringUtils; + + std::string getLanguage() + { + // Get the language of the system + // On Windows, we use GetUserDefaultUILanguage + // On macOS, we use getenv("LANG") + // If we cannot find the language, return "en" + + std::string lang; +#ifdef WINDOWS + LANGID langId = GetUserDefaultUILanguage(); + WCHAR localeName[LOCALE_NAME_MAX_LENGTH]; + + if (LCIDToLocaleName(langId, localeName, LOCALE_NAME_MAX_LENGTH, 0) != 0) + { + // Convert WCHAR to std::string + char localeNameStr[LOCALE_NAME_MAX_LENGTH]; + WideCharToMultiByte(CP_UTF8, 0, localeName, -1, localeNameStr, LOCALE_NAME_MAX_LENGTH, NULL, NULL); + lang = std::string(localeNameStr); + } + else + return "en-US"; +#else + std::string langC = getenv("LANG"); // NOLINT(concurrency-mt-unsafe) + if (not langC.empty()) + lang = langC; + + // If the language contains a period, remove everything after the period. Eg., en-US.UTF-8 -> en-US + auto splitResult = split(lang, '.'); + if (splitResult.size() > 1) + lang = splitResult.front(); +#endif + // The languages may be in xx_YY format. We need to convert it to xx-YY format. + std::ranges::replace(lang, '_', '-'); + // We cannot find the language, so we return "en-US" as the default language. + if (lang.empty()) + lang = "en-US"; + return lang; + } + + std::string $(const std::string& origin, const std::string& key) + { + // Get localization directory -> origin -> key -> **string** + // If we cannot find the string, return the default string. + // Localization is in /translations//.stp_localized + + // Group 1: Key, Group 2: String + const std::regex STRING_REGEX( + R"(^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}) >> \"([^\"]+?)\"$)"); + + const auto& confDir = getConfDirectory(); + const auto& lang = getLanguage(); + + const auto& langDir = confDir / "translations" / lang; + const auto& originFile = langDir / (origin + ".stp_localized"); + + if (not exists(originFile)) + { + // If the file does not exist, we return the key as the string. Also, we log an error. + output::error("getString"s, "Cannot find the localization file: " + originFile.string()); + return "<"s + key + ">"s; // Since the key is in UUID format, we need to make it look like a placeholder. + } + + // Read the file and get the string + std::ifstream file(originFile); + if (not file.is_open()) + { + // If we cannot open the file, we return the key as the string. Also, we log an error. + output::error("getString"s, "Cannot open the localization file: " + originFile.string()); + return "<"s + key + ">"s; // Since the key is in UUID format, we need to make it look like a placeholder. + } + + std::string line; + std::string translation; + while (std::getline(file, line)) + { + // LINE FORMAT + // key >> "string" + if (line.front() == '#') + continue; // Skip comments + if (line.empty()) + continue; // Skip empty lines + // Get the key and the string + if (std::regex_match(line, STRING_REGEX)) + { + std::smatch match; + std::regex_search(line, match, STRING_REGEX); + if (match.size() == 3) + { + if (match[1].str() == key) + { + translation = match[2].str(); + break; + } + } + } + else + { + output::error("getString"s, + "Malformed line in localization file: " + originFile.string() + " -> " + line); + break; + } + } + + // If we cannot find the string, we return the key as the string. Also, we log an error. + if (translation.empty()) + { + output::error("getString"s, "Cannot find the string for the key: " + key); + return "<" + key + ">"; // Since the key is in UUID format, we need to make it look like a placeholder. + } + return translation; + } + + std::string $(const std::string& origin, + const std::string& formatKey, + const std::vector& formatStrings) + { + // Get the key + const std::string& key = $(origin, formatKey); + // Format the string + return __internals::format::format(key, formatStrings); + } +} // namespace steppable::localization diff --git a/src/hyp/hyp.cpp b/src/hyp/hyp.cpp index f3c585b8c..d32c4d51d 100644 --- a/src/hyp/hyp.cpp +++ b/src/hyp/hyp.cpp @@ -31,6 +31,7 @@ #include "argParse.hpp" #include "constants.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "hypReport.hpp" #include "output.hpp" #include "rounding.hpp" @@ -42,6 +43,7 @@ using namespace std::literals; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::utils; using namespace steppable::__internals::numUtils; @@ -50,8 +52,8 @@ namespace steppable::__internals::arithmetic std::string sinh(const std::string& x, const int decimals) { const auto& twoX = multiply(x, "2", 0); - const auto& eTwoX = roundOff(power(constants::E, twoX, 0), decimals + 2); - const auto& eX = roundOff(power(constants::E, x, 0), decimals + 2); + const auto& eTwoX = roundOff(power(static_cast(constants::E), twoX, 0), decimals + 2); + const auto& eX = roundOff(power(static_cast(constants::E), x, 0), decimals + 2); const auto& numerator = subtract(eTwoX, "1", 0); const auto& denominator = multiply("2", eX, 0); @@ -62,8 +64,8 @@ namespace steppable::__internals::arithmetic std::string cosh(const std::string& x, const int decimals) { const auto& twoX = multiply(x, "2", 0); - const auto& eTwoX = roundOff(power(constants::E, twoX, 0), decimals + 2); - const auto& eX = roundOff(power(constants::E, x, 0), decimals + 2); + const auto& eTwoX = roundOff(power(static_cast(constants::E), twoX, 0), decimals + 2); + const auto& eX = roundOff(power(static_cast(constants::E), x, 0), decimals + 2); const auto& numerator = add(eTwoX, "1", 0); const auto& denominator = multiply("2", eX, 0); @@ -84,7 +86,7 @@ namespace steppable::__internals::arithmetic const auto& denominator = tanh(x, decimals); if (isZeroString(denominator)) { - error("hyp::coth"s, "Hyperbolic cotangent is not defined here."s); + error("hyp::coth"s, $("hyp", "e1f6e8db-64cd-4882-b5b2-ddd1c79c1e57")); return "Infinity"; } @@ -96,7 +98,7 @@ namespace steppable::__internals::arithmetic const auto& denominator = sinh(x, decimals); if (isZeroString(denominator)) { - error("hyp::csch"s, "Hyperbolic cosecant is not defined here."s); + error("hyp::csch"s, $("hyp", "30735b1c-5f92-4d2a-ab4a-056dd0f03c9b")); return "Infinity"; } @@ -108,7 +110,7 @@ namespace steppable::__internals::arithmetic const auto& denominator = cosh(x, decimals); if (isZeroString(denominator)) { - error("hyp::sech"s, "Hyperbolic secant is not defined here."s); + error("hyp::sech"s, $("hyp", "1f091fa2-47c1-4432-8951-c7db1dff0995")); return "Infinity"; } @@ -210,10 +212,10 @@ int main(int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('c', "Command", false); - program.addPosArg('n', "Number", false); - program.addKeywordArg("decimals", 5, "Amount of decimals while calculating."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('c', $("hyp", "4c28b4d6-3002-458a-88bd-9d7c03b9b614"), false); + program.addPosArg('n', $("hyp", "1d369138-f330-42b2-9aa9-40ab5f7f3df8"), false); + program.addKeywordArg("decimals", 5, $("hyp", "92717527-91df-4fa8-905c-cde0525612af")); + program.addSwitch("profile", false, $("hyp", "ba4083c0-788f-4f3c-9748-df0cf7b7b41c")); program.parseArgs(); const bool profile = program.getSwitch("profile"); @@ -255,7 +257,7 @@ int main(int _argc, const char* _argv[]) // Invalid command else { - error("hyp::main", "Invalid command."s); + error("hyp::main", $("hyp", "b2f5e0cd-3c21-4fb6-8964-7b411c27785a")); return EXIT_FAILURE; } std::cout << function(arg, decimals) << '\n'; diff --git a/src/log/log.cpp b/src/log/log.cpp index e489e6905..5d8a678d1 100644 --- a/src/log/log.cpp +++ b/src/log/log.cpp @@ -30,6 +30,7 @@ #include "argParse.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "logReport.hpp" #include "output.hpp" #include "rounding.hpp" @@ -41,6 +42,7 @@ using namespace steppable::__internals::arithmetic; using namespace steppable::__internals::utils; +using namespace steppable::localization; using namespace std::literals; namespace steppable::__internals::arithmetic @@ -119,20 +121,18 @@ int main(int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('c', "Command", false); - program.addPosArg('n', "Number", true); - program.addPosArg('b', "Base", true); - program.addKeywordArg("mode", 0, "The mode to calculate in. 0 = radians (default), 1 = degrees, 2 = gradians."); - program.addKeywordArg("decimals", 5, "Amount of decimals while calculating."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('c', $("log", "e8227bec-443c-4d2d-a569-06e3d20c11ad"), false); + program.addPosArg('n', $("log", "d67686ce-2bad-48c9-a8ff-ec709d23ccea"), true); + program.addPosArg('b', $("log", "4a3f8558-00dd-430e-921c-792542d9c29a"), true); + program.addKeywordArg("decimals", 5, $("log", "56363a7f-4277-4805-95b2-ef3b8ccc1671")); + program.addSwitch("profile", false, $("log", "8623ed47-e7bd-46a2-a1db-3c0746520e2e")); program.parseArgs(); - const int mode = program.getKeywordArgument("mode"); const bool profile = program.getSwitch("profile"); const int decimals = program.getKeywordArgument("decimals"); - const auto& command = static_cast(program.getPosArg(0)); - const auto& arg = static_cast(program.getPosArg(1)); - const auto& base = static_cast(program.getPosArg(2)); + const auto& command = program.getPosArg(0); + const auto& arg = program.getPosArg(1); + const auto& base = program.getPosArg(2); using namespace steppable::__internals; using namespace steppable::output; @@ -147,7 +147,7 @@ int main(int _argc, const char* _argv[]) std::cout << arithmetic::ln(arg, decimals) << "\n"; else { - error("log"s, "Unknown command: "s + command); + error("log"s, $("log", "0fc4245a-fee9-4e99-bbbd-378d091c5143", { command })); return EXIT_FAILURE; } } diff --git a/src/multiply/multiply.cpp b/src/multiply/multiply.cpp index d743cd17f..ce009e62c 100644 --- a/src/multiply/multiply.cpp +++ b/src/multiply/multiply.cpp @@ -30,23 +30,24 @@ #include "argParse.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "multiplyReport.hpp" #include "rounding.hpp" #include "util.hpp" #include #include -#include #include using namespace steppable::__internals::numUtils; using namespace steppable::__internals::stringUtils; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::arithmetic; namespace steppable::__internals::arithmetic { - std::string multiply(const std::string_view& _a, const std::string_view& _b, const int steps) + std::string multiply(const std::string& _a, const std::string& _b, const int steps) { auto a = static_cast(_a); auto b = static_cast(_b); @@ -67,7 +68,7 @@ namespace steppable::__internals::arithmetic if (isZeroString(a) or isZeroString(b)) { if (steps == 2) - out << "Since any of a or b is zero, the result must be zero as well.\n"; + out << $("multiply", "9cdeff33-fefa-40ac-b867-a811f652d6e3") << "\n"; out << "0"; // Since a or b is zero, the result must be zero as well } @@ -75,14 +76,14 @@ namespace steppable::__internals::arithmetic if (a == "1") { if (steps == 2) - out << "Since " << a << " is 1, the result is " << b << ".\n"; + out << $("multiply", "36adc27f-07e8-4118-88ed-f148164044da", { a, b }) << "\n"; out << b; return out.str(); } if (b == "1") { if (steps == 2) - out << "Since " << b << " is 1, the result is " << a << ".\n"; + out << $("multiply", "36adc27f-07e8-4118-88ed-f148164044da", { b, a }) << "\n"; out << a; return out.str(); } @@ -91,7 +92,7 @@ namespace steppable::__internals::arithmetic if (isPowerOfTen(a)) { if (steps == 2) - out << "Since " << a << " is a power of 10, we can move the decimal places to obtain the result.\n"; + out << $("multiply", "0e76c0f9-6d14-450d-abc4-f4a758787d06", { a }) << "\n"; auto result = moveDecimalPlaces(b, determineScale(a)); if (resultIsNegative) result = "-" + result; // NOLINT(performance-inefficient-string-concatenation) @@ -102,7 +103,7 @@ namespace steppable::__internals::arithmetic if (isPowerOfTen(b)) { if (steps == 2) - out << "Since " << b << " is a power of 10, we can move the decimal places to obtain the result.\n"; + out << $("multiply", "0e76c0f9-6d14-450d-abc4-f4a758787d06", { b }) << "\n"; auto result = moveDecimalPlaces(a, determineScale(b)); if (resultIsNegative) result = "-" + result; // NOLINT(performance-inefficient-string-concatenation) @@ -196,10 +197,10 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number 1"); - program.addPosArg('b', "Number 2"); - program.addKeywordArg("steps", 2, "Amount of steps while multiplying"); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("multiply", "1d54da58-ec3c-4888-80a8-c40565efb603")); + program.addPosArg('b', $("multiply", "3db8b80f-9667-476a-b096-9323615dd461")); + program.addKeywordArg("steps", 2, $("multiply", "5ed5291e-6269-4d76-a8f8-db5eec807955")); + program.addSwitch("profile", false, $("multiply", "eec47776-991b-40cc-9956-7227127d2c1f")); program.parseArgs(); int steps = program.getKeywordArgument("steps"); @@ -210,7 +211,8 @@ int main(const int _argc, const char* _argv[]) if (profile) { TIC(Column Method Multiplication) - std::cout << "Column Method Multiplication :\n" << multiply(aStr, bStr, steps) << '\n'; + std::cout << $("multiply", "776a33fd-982a-4888-8b42-83b0f3797dc2") << "\n" + << multiply(aStr, bStr, steps) << '\n'; TOC() } else diff --git a/src/number.cpp b/src/number.cpp index 3360de735..31675a634 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -70,7 +70,7 @@ namespace steppable else { usePrec = 0; - output::warning("Invalid precision specified"); + output::warning("Number::operator/"s, "Invalid precision specified"s); } return divide(value, rhs.value, 0, static_cast(usePrec)); } diff --git a/src/platform.cpp b/src/platform.cpp new file mode 100644 index 000000000..f0a29768a --- /dev/null +++ b/src/platform.cpp @@ -0,0 +1,108 @@ +/************************************************************************************************** + * Copyright (c) 2023-2024 NWSOFT * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **************************************************************************************************/ + +#include "platform.hpp" + +#include "output.hpp" + +#ifdef LINUX + #include +#endif +#include + +#ifdef WINDOWS + #include + #include +#else + #include + #include + #include +#endif + +namespace steppable::__internals::utils +{ + std::filesystem::path getHomeDirectory() + { + std::filesystem::path homeDir; + +#ifdef WINDOWS + char homePath[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, homePath))) + homeDir = homePath; + else + output::error("platform::getHomeDirectory"s, "Error: Unable to get the home directory."s); +#else + const std::filesystem::path& homeEnv = std::getenv("HOME"); // NOLINT(concurrency-mt-unsafe) + + if (std::filesystem::is_directory(homeEnv)) + homeDir = homeEnv; + else + { + std::array buffer{}; + std::array errBuffer{}; + const char* homeEnv = nullptr; + int error = 0; + struct passwd pw + { + }; + struct passwd* result = nullptr; + + uid_t userId = getuid(); + error = getpwuid_r(userId, &pw, buffer.data(), sizeof(buffer), &result); + + if (result != nullptr) + homeDir = pw.pw_dir; + else if (error != 0) + { + strerror_r(error, errBuffer.data(), errBuffer.size()); + output::error("platform::getHomeDirectory"s, + "Error occurred while getting the home directory: {0}"s, + { buffer.data() }); + } + else + output::error("platform::getHomeDirectory"s, "Error: Unable to get the home directory."s); + } +#endif + + return homeDir; + } + + std::filesystem::path getConfDirectory() + { + // When we have a full application, we can allow users to change the configuration directory. + // However, now, we will use the default configuration directory for the platform. + std::filesystem::path confDir = getHomeDirectory(); + +#ifndef WINDOWS + confDir /= ".config"; + confDir /= "steppable"; +#else + confDir /= "AppData"; + confDir /= "Roaming"; + confDir /= "Steppable"; +#endif + // If the directory does not exist, create it. + if (not std::filesystem::is_directory(confDir)) + std::filesystem::create_directories(confDir); + return confDir; + } +} // namespace steppable::__internals::utils diff --git a/src/power/power.cpp b/src/power/power.cpp index 6d8a933b6..b14f546dd 100644 --- a/src/power/power.cpp +++ b/src/power/power.cpp @@ -30,12 +30,14 @@ #include "argParse.hpp" #include "fn/basicArithm.hpp" #include "fraction.hpp" +#include "getString.hpp" #include "powerReport.hpp" #include "symbols.hpp" #include "util.hpp" using namespace steppable::__internals::numUtils; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::arithmetic; namespace steppable::prettyPrint::printers @@ -55,7 +57,7 @@ namespace steppable::prettyPrint::printers namespace steppable::__internals::arithmetic { - std::string power(const std::string_view _number, const std::string_view& _raiseTo, const int steps) + std::string power(const std::string& _number, const std::string& _raiseTo, const int steps) { std::string raiseTo = static_cast(_raiseTo); std::string number = static_cast(_number); @@ -78,7 +80,7 @@ namespace steppable::__internals::arithmetic if (number == "1") { if (steps == 2) - return "Since the number is 1, the result is 1."; + return $("power", "7c866c46-d67e-4c1e-8fd5-b3bfa07d005d"); if (steps == 1) return "1"s + symbols::makeSuperscript(raiseTo) + " = 1"; return "1"; @@ -86,7 +88,7 @@ namespace steppable::__internals::arithmetic if (number == "0") { if (steps == 2) - return "Since the number is 0, the result is 0."; + return $("power", "261e4299-0132-4ab5-a37d-aa376efbdd5f"); if (steps == 1) return "0"s + symbols::makeSuperscript(raiseTo) + " = 0"; return "0"; @@ -121,11 +123,10 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage(); ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number as the base"); - program.addPosArg('b', "Number as the exponent"); - program.addKeywordArg( - "steps", 2, "Amount of steps while raising the power (i.e., multiplying). 0 = No steps, 2 = All steps."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("power", "4252ac37-a36b-4605-9ec1-d69e70b91b46")); + program.addPosArg('b', $("power", "1fefffaf-7731-430b-989f-42e74017a2eb")); + program.addKeywordArg("steps", 2, $("power", "cb935566-6125-49ce-9ebc-e157410a3005")); + program.addSwitch("profile", false, $("power", "e5d48237-e161-494d-940b-e2457411fcfb")); program.parseArgs(); int steps = program.getKeywordArgument("steps"); @@ -136,7 +137,7 @@ int main(const int _argc, const char* _argv[]) if (profile) { TIC(Power) - std::cout << "Power :\n" << power(aStr, bStr, steps) << '\n'; + std::cout << $("power", "2a9fd067-59a3-4a65-b1a6-2ca479e0f1a1") << "\n" << power(aStr, bStr, steps) << '\n'; TOC() } else diff --git a/src/power/powerReport.cpp b/src/power/powerReport.cpp index 5877456a9..3c1452564 100644 --- a/src/power/powerReport.cpp +++ b/src/power/powerReport.cpp @@ -33,6 +33,7 @@ #include "fn/basicArithm.hpp" #include "fraction.hpp" +#include "getString.hpp" #include "symbols.hpp" #include "util.hpp" @@ -40,6 +41,7 @@ using namespace std::literals; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::prettyPrint; using namespace steppable::__internals::symbols; using namespace steppable::__internals::arithmetic; @@ -54,7 +56,8 @@ std::string reportPowerRoot(const std::string& _number, std::stringstream ss; if (steps == 2) - ss << "The exponent " << raiseTo << " is a decimal. Therefore, the result is a root." << '\n'; + // The exponent is a decimal, so the result is a root. + ss << $("power", "7b3b39ff-c3fa-4998-b9e2-8989fb6846f9", { raiseTo }) << '\n'; if (steps >= 1) { ss << _number << makeSuperscript(static_cast(raiseTo)); @@ -64,8 +67,8 @@ std::string reportPowerRoot(const std::string& _number, return ss.str(); } -std::string reportPower(const std::string_view _number, - const std::string_view& raiseTo, +std::string reportPower(const std::string& _number, + const std::string& raiseTo, const size_t numberTrailingZeros, const bool negative, const int steps) @@ -81,7 +84,8 @@ std::string reportPower(const std::string_view _number, if (numberOrig == "0") { if (steps == 2) - return "Since the number is 0, the result is 0."; + // The number is 0, so the result is 0. + return $("power", "261e4299-0132-4ab5-a37d-aa376efbdd5f"); if (steps == 1) return printers::ppSuperscript("0", static_cast(raiseTo)) + " = 0"; return "0"; diff --git a/src/power/powerReport.hpp b/src/power/powerReport.hpp index 1b20a8ae3..6d212c05c 100644 --- a/src/power/powerReport.hpp +++ b/src/power/powerReport.hpp @@ -58,8 +58,8 @@ std::string reportPowerRoot(const std::string& _number, * * @return The formatted power report. */ -std::string reportPower(std::string_view _number, - const std::string_view& raiseTo, +std::string reportPower(const std::string& _number, + const std::string& raiseTo, size_t numberTrailingZeros, bool negative, int steps); diff --git a/src/root/root.cpp b/src/root/root.cpp index 80e42bff0..b3d265d33 100644 --- a/src/root/root.cpp +++ b/src/root/root.cpp @@ -34,6 +34,7 @@ #include "factors.hpp" #include "fn/basicArithm.hpp" #include "fraction.hpp" +#include "getString.hpp" #include "rootReport.hpp" #include "rounding.hpp" #include "symbols.hpp" @@ -50,6 +51,7 @@ using namespace steppable::__internals::arithmetic; using namespace steppable::__internals::utils; using namespace steppable::__internals::stringUtils; using namespace steppable::__internals::numUtils; +using namespace steppable::localization; using namespace std::literals; namespace steppable::prettyPrint::printers @@ -123,15 +125,15 @@ namespace steppable::__internals::arithmetic return { radicand, multiplier }; } - std::string _root(const std::string& _number, const std::string& base, const size_t _decimals) + std::string _root(const std::string& _number, const std::string& base, const size_t _decimals, const int steps) { if (isDecimal(base)) { const auto& fraction = Fraction(base); const auto& [top, bottom] = fraction.asArray(); const auto& powerResult = power(_number, bottom, 0); - const auto rootResult = _root(powerResult, top, _decimals); - return reportRootPower(_number, base, fraction, rootResult, 0); + const auto rootResult = _root(powerResult, top, _decimals, 0); + return reportRootPower(_number, base, fraction, rootResult, steps); } if (compare(base, "1", 0) == "2") @@ -153,6 +155,19 @@ namespace steppable::__internals::arithmetic while (true) { + // Try to approximate the correct radicand. + // Method: + // +---+ ********* +---+ + // | y | <= * value * <= | x | + // +---+ ********* +---+ + // x - y + // - value = y + ------- + // 2 + // + // base + // - If value > actual, x is too large, exchange x with y. + // - If < actual, y is too large, exchange y with x. + // - If is within acceptable range, return. auto newAvg = divide(subtract(x, y, 0), "2", 0, static_cast(decimals) + 1); auto radicand = add(y, newAvg, 0); auto test = power(radicand, base, 0); @@ -169,18 +184,18 @@ namespace steppable::__internals::arithmetic } } - std::string root(const std::string& _number, const std::string& base, const size_t _decimals) + std::string root(const std::string& _number, const std::string& base, const size_t _decimals, const int steps) { if (isZeroString(_number)) return "0"; if (isInteger(_number)) { auto result = rootSurd(_number, base); - auto rootResult = _root(result.radicand, base, _decimals); + auto rootResult = _root(result.radicand, base, _decimals, 0); return multiply(rootResult, result.multiplier, 0); } - return _root(_number, base, _decimals); + return _root(_number, base, _decimals, steps); } } // namespace steppable::__internals::arithmetic @@ -190,24 +205,27 @@ int main(const int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', "Number"); - program.addPosArg('n', "Base"); - program.addKeywordArg("decimals", 8, "Amount of decimals while taking the n-th root."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("root", "0b4174a0-75ae-4dbb-93e0-144938272fd6")); + program.addPosArg('n', $("root", "43d64cf7-6f56-4081-a239-34a972cf5cce")); + program.addKeywordArg("decimals", 8, $("root", "c4392b15-37a2-4d0e-9b3a-fc11b46bf369")); + program.addKeywordArg("steps", 2, $("root", "3178f539-1d1c-4e7b-8f5e-6186b361b4e6")); + program.addSwitch("profile", false, $("root", "5f1f7d97-0ef3-4ccc-95c3-f7582ba11a20")); program.parseArgs(); const int decimals = program.getKeywordArgument("decimals"); const bool profile = program.getSwitch("profile"); + const int steps = program.getKeywordArgument("steps"); const auto& number = static_cast(program.getPosArg(0)); const auto& base = static_cast(program.getPosArg(1)); if (profile) { TIC(Nth root) - std::cout << "Taking n-th root :\n" << root(number, base, decimals) << '\n'; + std::cout << $("root", "aca8b9a2-c7ff-470a-a72f-86204a413c18") << "\n" + << root(number, base, decimals, steps) << '\n'; TOC() } else - std::cout << root(number, base, decimals) << '\n'; + std::cout << root(number, base, decimals, steps) << '\n'; } #endif diff --git a/src/root/rootReport.cpp b/src/root/rootReport.cpp index fa8e49e62..1e356ece5 100644 --- a/src/root/rootReport.cpp +++ b/src/root/rootReport.cpp @@ -22,6 +22,7 @@ #include "rootReport.hpp" +#include "getString.hpp" #include "symbols.hpp" #include @@ -29,6 +30,7 @@ using namespace steppable::__internals::symbols; using namespace steppable::prettyPrint::printers; +using namespace steppable::localization; std::string reportRootPower(const std::string& _number, const std::string& base, @@ -40,7 +42,7 @@ std::string reportRootPower(const std::string& _number, std::stringstream ss; if (steps == 2) - ss << "The base " << base << " is a decimal. Therefore, we need to perform a power operation first." << '\n'; + ss << $("root", "248c0c3b-05f8-45d6-868f-ec921c088ce1", { _number }) << '\n'; if (steps >= 1) { ss << ppRoot(_number, base) << '\n'; diff --git a/src/subtract/subtract.cpp b/src/subtract/subtract.cpp index 211768831..c7f4c35fd 100644 --- a/src/subtract/subtract.cpp +++ b/src/subtract/subtract.cpp @@ -31,6 +31,7 @@ #include "argParse.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "subtractReport.hpp" #include "symbols.hpp" #include "util.hpp" @@ -39,16 +40,16 @@ #include #include #include -#include #include using namespace steppable::__internals::numUtils; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::arithmetic; namespace steppable::__internals::arithmetic { - std::string subtract(const std::string_view& a, const std::string_view& b, const int steps, const bool noMinus) + std::string subtract(const std::string& a, const std::string& b, const int steps, const bool noMinus) { auto [splitNumberArray, aIsNegative, bIsNegative] = splitNumber(a, b); auto [aInteger, aDecimal, bInteger, bDecimal] = splitNumberArray; @@ -74,7 +75,8 @@ namespace steppable::__internals::arithmetic { resultIsNegative = true; if (steps == 2) - std::cout << "Adding " << a.substr(1) << " and " << b << " since " << a << " is negative\n"; + // Adding {0} and {1} since {0} is negative + std::cout << $("subtract", "063f0bd2-a4ca-4433-97c0-8baa73cd0e7c", { a.substr(1), b }) << "\n"; auto addResult = add(a.substr(1), b, steps, true); auto res = addResult.substr(addResult.find_last_of(' ') + 1); if (steps == 2) @@ -96,7 +98,8 @@ namespace steppable::__internals::arithmetic if (bIsNegative) { if (steps == 2) - std::cout << "Adding " << a << " and " << b.substr(1) << " since " << b << " is negative\n"; + // Adding {0} and {1} since {1} is negative + std::cout << $("subtract", "063f0bd2-a4ca-4433-97c0-8baa73cd0e7c", { a, b.substr(1) }) << "\n"; resultIsNegative = false; return add(a, b.substr(1), steps); } @@ -191,11 +194,11 @@ int main(int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('a', ""); - program.addPosArg('b', ""); - program.addKeywordArg("steps", 2, "steps while adding"); - program.addSwitch("noMinus", false, "shows the minus sign"); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('a', $("subtract", "3db38a7c-58e9-44f2-ba36-47e355b60294")); + program.addPosArg('b', $("subtract", "a697967c-5010-423c-9a84-201c955310de")); + program.addKeywordArg("steps", 2, $("subtract", "645b0f26-3c2a-49ae-a9d6-1e06c11fe15e")); + program.addSwitch("noMinus", false, $("subtract", "7704320c-1391-405f-8147-0b4023d769f6")); + program.addSwitch("profile", false, $("subtract", "4c13dd96-fb5b-4e99-b8e6-08e8be07b446")); program.parseArgs(); int steps = program.getKeywordArgument("steps"); @@ -207,7 +210,8 @@ int main(int _argc, const char* _argv[]) if (profile) { TIC(Column Method Subtraction) - std::cout << "Column Method Subtraction :\n" << subtract(aStr, bStr, steps, noMinus) << '\n'; + std::cout << $("subtract", "4dee3c00-c204-4cb0-afad-e57e41763bf5") << "\n" + << subtract(aStr, bStr, steps, noMinus) << '\n'; TOC() } else diff --git a/src/testing.cpp b/src/testing.cpp index fdb518a7e..03d572e0e 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -26,70 +26,70 @@ #include "output.hpp" #include -#include using namespace std::literals; using namespace steppable::output; -using namespace steppable::__internals::format; namespace steppable::testing { - TestCase::TestCase(const std::string& testCaseName) { this->testCaseName = testCaseName; } + TestCase::TestCase(const std::string& testCaseName) : testCaseName(testCaseName) {} void TestCase::assert(const bool condition, const std::string& conditionName) { if (condition) { - info("%s PASSED", conditionName.c_str()); + info("TestCase::assert"s, "{0} PASSED"s, { conditionName }); return; } - error( - "TestCase::assert", "%i: Condition %s evaluates to false. FAILED"s, errorCount + 1, conditionName.c_str()); + error("TestCase::assert", + "{0}: Condition {1} evaluates to false. FAILED"s, + { std::to_string(errorCount + 1), conditionName }); errorCount++; } void TestCase::assertIsEqual(const std::string& a, const std::string& b) { - const std::string& conditionName = vFormat("String %s == %s", a.c_str(), b.c_str()); + const std::string& conditionName = format::format("String {0} == {1}", { a, b }); assert(a == b, conditionName); } void TestCase::assertIsNotEqual(const std::string& a, const std::string& b) { - const std::string& conditionName = vFormat("String %s != %s", a.c_str(), b.c_str()); + const std::string& conditionName = format::format("String {0} != {1}", { a, b }); assert(a != b, conditionName); } void TestCase::assertIsEqual(const int a, const int b) { - const std::string& conditionName = vFormat("Integer %i == %i", a, b); + const std::string& conditionName = + format::format("Integer {0} == {1}", { std::to_string(a), std::to_string(b) }); assert(a == b, conditionName); } void TestCase::assertIsNotEqual(const int a, const int b) { - const std::string& conditionName = vFormat("Integer %i != %i", a, b); + const std::string& conditionName = + format::format("Integer {0} != {1}", { std::to_string(a), std::to_string(b) }); assert(a != b, conditionName); } void TestCase::assertTrue(const bool value) { - const std::string& conditionName = vFormat("%i is True", static_cast(value)); + const std::string& conditionName = format::format("{0} is True", { std::to_string(static_cast(value)) }); assert(value, conditionName); } void TestCase::assertFalse(const bool value) { - const std::string& conditionName = vFormat("%i is False", static_cast(value)); + const std::string& conditionName = format::format("{0} is False", { std::to_string(static_cast(value)) }); assert(not value, conditionName); } void TestCase::summarize() const { - if (errorCount == 1) - std::cout << colors::red << '[' << testCaseName << ": Total " << errorCount << " error]" << reset << '\n'; - else if (errorCount > 1) - std::cout << colors::red << '[' << testCaseName << ": Total " << errorCount << " errors]" << reset << '\n'; + if (errorCount != 0) + std::cout << colors::red << '[' << testCaseName << ": Total " << errorCount << " error(s)]" << reset + << '\n'; else std::cout << colors::brightGreen << '[' << testCaseName << ": All tests passed]" << reset << '\n'; } diff --git a/src/trig/trig.cpp b/src/trig/trig.cpp index a93fc289e..c4e52f3d9 100644 --- a/src/trig/trig.cpp +++ b/src/trig/trig.cpp @@ -31,6 +31,7 @@ #include "argParse.hpp" #include "constants.hpp" #include "fn/basicArithm.hpp" +#include "getString.hpp" #include "rounding.hpp" #include "trigReport.hpp" #include "util.hpp" @@ -41,6 +42,7 @@ using namespace std::literals; using namespace steppable::output; +using namespace steppable::localization; using namespace steppable::__internals::utils; using namespace steppable::__internals::numUtils; @@ -50,7 +52,7 @@ namespace steppable::__internals::arithmetic { // rad = deg * (pi / 180) auto deg = divideWithQuotient(_deg, "360").remainder; - auto rad = multiply(deg, constants::PI_OVER_180, 0); + auto rad = multiply(deg, static_cast(constants::PI_OVER_180), 0); return rad; } @@ -58,7 +60,7 @@ namespace steppable::__internals::arithmetic { // rad = grad * (pi / 200) auto grad = divideWithQuotient(_grad, "400").remainder; - auto rad = multiply(grad, constants::PI_OVER_200, 0); + auto rad = multiply(grad, static_cast(constants::PI_OVER_200), 0); return rad; } @@ -68,7 +70,7 @@ namespace steppable::__internals::arithmetic auto rad = _rad; rad = divideWithQuotient(rad, static_cast(constants::TWO_PI)).remainder; rad = standardizeNumber(rad); - auto deg = divide(rad, constants::PI_OVER_180, 0); + auto deg = divide(rad, static_cast(constants::PI_OVER_180), 0); deg = standardizeNumber(deg); deg = divideWithQuotient(deg, "90").remainder; return standardizeNumber(deg); @@ -79,7 +81,7 @@ namespace steppable::__internals::arithmetic // grad = rad * (200 / pi) auto rad = divideWithQuotient(_rad, static_cast(constants::TWO_PI)).remainder; rad = standardizeNumber(rad); - auto grad = divide(rad, constants::PI_OVER_200, 0); + auto grad = divide(rad, static_cast(constants::PI_OVER_200), 0); grad = standardizeNumber(grad); grad = divideWithQuotient(grad, "100").remainder; return standardizeNumber(grad); @@ -176,25 +178,25 @@ namespace steppable::__internals::arithmetic case 0: { result = cos(subtract(divideWithQuotient(x, static_cast(constants::TWO_PI)).remainder, - constants::PI_OVER_2, + static_cast(constants::PI_OVER_2), 0), decimals); break; } case 1: { - result = cos(subtract(degToRad(x), constants::PI_OVER_2, 0), decimals); + result = cos(subtract(degToRad(x), static_cast(constants::PI_OVER_2), 0), decimals); break; } case 2: { - result = cos(subtract(gradToRad(x), constants::PI_OVER_2, 0), decimals); + result = cos(subtract(gradToRad(x), static_cast(constants::PI_OVER_2), 0), decimals); break; } default: { error("trig::sin"s, "Invalid mode. Defaulting to radians."s); - result = cos(subtract(x, constants::PI_OVER_2, 0), decimals); + result = cos(subtract(x, static_cast(constants::PI_OVER_2), 0), decimals); } } @@ -215,7 +217,7 @@ namespace steppable::__internals::arithmetic auto cosX = cos(divideWithQuotient(x, static_cast(constants::TWO_PI)).remainder, decimals + 1); if (isZeroString(cosX)) { - error("trig::tan"s, "Tangent is undefined here."s); + error("trig::tan"s, $("trig", "a7ed4324-5cc3-48d2-9798-d3e743b809d3")); return "Infinity"; } result = divide(sin(x, decimals + 1), cosX, 0, decimals); @@ -227,7 +229,7 @@ namespace steppable::__internals::arithmetic auto cosX = cos(xRad, decimals + 1); if (isZeroString(cosX)) { - error("trig::tan"s, "Tangent is undefined here."s); + error("trig::tan"s, $("trig", "a7ed4324-5cc3-48d2-9798-d3e743b809d3")); return "Infinity"; } result = divide(sin(xRad, decimals + 1), cosX, 0, decimals); @@ -239,7 +241,7 @@ namespace steppable::__internals::arithmetic auto cosX = cos(xRad, decimals + 1); if (isZeroString(cosX)) { - error("trig::tan"s, "Tangent is undefined here."s); + error("trig::tan"s, $("trig", "a7ed4324-5cc3-48d2-9798-d3e743b809d3")); return "Infinity"; } result = divide(sin(xRad, decimals + 1), cosX, 0, decimals); @@ -260,7 +262,7 @@ namespace steppable::__internals::arithmetic auto sinX = sin(x, decimals + 1, mode); if (isZeroString(sinX)) { - error("trig::csc"s, "Cosecant is undefined here."s); + error("trig::csc"s, $("trig", "0dd11fcc-bdd0-48d1-9b4a-7ebcccb4915f")); return "Infinity"; } return divide("1", sinX, 0, decimals); @@ -271,7 +273,7 @@ namespace steppable::__internals::arithmetic auto cosX = cos(x, decimals + 1, mode); if (isZeroString(cosX)) { - error("trig::sec"s, "Secant is undefined here."s); + error("trig::sec"s, $("trig", "62792c6c-6751-4850-bf66-5e6366322cc0")); return "Infinity"; } return divide("1", cosX, 0, decimals); @@ -282,7 +284,7 @@ namespace steppable::__internals::arithmetic auto tanX = tan(x, decimals + 1, mode); if (isZeroString(tanX)) { - error("trig::cot"s, "Cotangent is undefined here."s); + error("trig::cot"s, $("trig", "65650a93-4298-4e19-8c81-f5fbd9f14ac2")); return "Infinity"; } return divide("1", tanX, 0, decimals); @@ -320,7 +322,7 @@ namespace steppable::__internals::arithmetic { // If x was reduced, use the identity // arctan(1/x) = pi/2 - arctan(x) - result = subtract(constants::PI_OVER_2, result, 0); + result = subtract(static_cast(constants::PI_OVER_2), result, 0); } result = roundOff(result, decimals); @@ -344,7 +346,7 @@ namespace steppable::__internals::arithmetic { if (compare(abs(x, 0), "1", 0) == "1") { - error("trig::asin"s, "Arc sine is not defined here."s); + error("trig::asin", $("trig", "b06650e0-7101-4734-9647-5abb56beb492")); return "Infinity"; } if (compare(abs(x, 0), "0", 0) == "2") @@ -436,7 +438,7 @@ namespace steppable::__internals::arithmetic { if (compare(abs(x, 0), "1", 0) == "1") { - error("trig::asec"s, "Arc secant is not defined here."s); + error("trig::asec", $("trig", "fffb4742-3712-4c9a-a7ff-65cd51508a0a")); return "Infinity"; } @@ -450,7 +452,7 @@ namespace steppable::__internals::arithmetic { if (compare(abs(x, 0), "1", 0) != "0") { - error("trig::acsc"s, "Arc cosecant is not defined here."s); + error("trig::acsc"s, $("trig", "c021dfde-300c-4d74-a6a1-87a514c1bbe0")); return "Infinity"; } @@ -464,7 +466,7 @@ namespace steppable::__internals::arithmetic { if (compare(abs(x, 0), "1", 0) != "0") { - error("trig::acot"s, "Arc cotangent is not defined here."s); + error("trig::acot"s, $("trig", "c0c6a29f-abda-4676-9662-1d00f94f10a4")); return "Infinity"; } @@ -480,11 +482,11 @@ int main(int _argc, const char* _argv[]) { Utf8CodePage _; ProgramArgs program(_argc, _argv); - program.addPosArg('c', "Command", false); - program.addPosArg('n', "Number", false); - program.addKeywordArg("mode", 0, "The mode to calculate in. 0 = radians (default), 1 = degrees, 2 = gradians."); - program.addKeywordArg("decimals", 5, "Amount of decimals while calculating."); - program.addSwitch("profile", false, "profiling the program"); + program.addPosArg('c', $("trig", "47dcf91b-847c-48f0-9889-f5ce1b6831e3"), false); + program.addPosArg('n', $("trig", "bcd0a3e9-3d89-4921-94b3-d7533d60911f"), false); + program.addKeywordArg("mode", 0, $("trig", "03fdd1f2-6ea5-49d4-ac3f-27f01f04a518")); + program.addKeywordArg("decimals", 5, $("trig", "d1df3b60-dac1-496c-99bb-ba763dc551df")); + program.addSwitch("profile", false, $("trig", "162adb13-c4b2-4418-b3df-edb6f9355d64")); program.parseArgs(); const int mode = program.getKeywordArgument("mode"); @@ -527,7 +529,7 @@ int main(int _argc, const char* _argv[]) // Invalid command else { - error("trig::main", "Invalid command."s); + error("trig::main", $("trig", "6ad9958f-f127-4ee4-a4c6-94cf19576b9a", { command })); return EXIT_FAILURE; } std::cout << function(arg, decimals, mode) << '\n'; diff --git a/src/util.cpp b/src/util.cpp index e177a3576..f195a5438 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -37,7 +37,7 @@ namespace steppable::__internals::numUtils { - bool isNumber(const std::string_view& s) + bool isNumber(const std::string& s) { if (s.empty()) return false; @@ -64,7 +64,7 @@ namespace steppable::__internals::numUtils return true; } - std::string simplifyZeroPolarity(const std::string_view& string) + std::string simplifyZeroPolarity(const std::string& string) { // Check if the string is zero if (isZeroString(string)) @@ -72,7 +72,7 @@ namespace steppable::__internals::numUtils return static_cast(string); } - std::string simplifyPolarity(const std::string_view& _string) + std::string simplifyPolarity(const std::string& _string) { auto string = simplifyZeroPolarity(_string); while (string[0] == '-' and string[1] == '-') @@ -80,7 +80,7 @@ namespace steppable::__internals::numUtils return string; } - std::string standardizeNumber(const std::string_view& _number) + std::string standardizeNumber(const std::string& _number) { auto number = simplifyPolarity(_number); // Remove the trailing decimal point @@ -98,8 +98,8 @@ namespace steppable::__internals::numUtils return number; } - SplitNumberResult splitNumber(const std::string_view& _a, - const std::string_view& _b, + SplitNumberResult splitNumber(const std::string& _a, + const std::string& _b, const bool padInteger, const bool padDecimal, bool properlyFormat, @@ -237,7 +237,7 @@ namespace steppable::__internals::numUtils return result; } - long long determineScale(const std::string_view& number) + long long determineScale(const std::string& number) { auto splitNumberResult = splitNumber(number, "0", false, false).splitNumberArray; auto numberInteger = splitNumberResult[0]; @@ -389,21 +389,3 @@ namespace steppable::__internals::stringUtils return ""; } } // namespace steppable::__internals::stringUtils - -namespace steppable::__internals::utils -{ - void initLocale() - { -#if MS_STDLIB_BUGS - constexpr char cp_utf16le[] = ".1200"; - setlocale(LC_ALL, cp_utf16le); - _setmode(_fileno(stdout), _O_WTEXT); -#else - // The correct locale name may vary by OS, e.g., "en_US.utf8". - (void)setlocale(LC_ALL, ""); // NOLINT(concurrency-mt-unsafe) - std::locale::global(std::locale("")); - std::wcin.imbue(std::locale()); - std::wcout.imbue(std::locale()); -#endif - } -} // namespace steppable::__internals::utils diff --git a/tests/testFormat.cpp b/tests/testFormat.cpp new file mode 100644 index 000000000..39126817b --- /dev/null +++ b/tests/testFormat.cpp @@ -0,0 +1,65 @@ +/************************************************************************************************** + * Copyright (c) 2023-2024 NWSOFT * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **************************************************************************************************/ + +#include "colors.hpp" +#include "factors.hpp" +#include "output.hpp" +#include "testing.hpp" +#include "util.hpp" + +#include +#include +#include + +using namespace steppable::__internals; + +TEST_START() +SECTION(Test format) +const std::string& formatOrig = "Hello, {0}!"; +const std::string& arg = "world"; +const std::string& expected = "Hello, world!"; + +const std::string& result = format::format(formatOrig, { arg }); +_.assertIsEqual(result, expected); +SECTION_END() + +SECTION(Test format with multiple values) +const std::string& formatOrig = "{0}, {1}!"; +const std::string& arg1 = "Hello"; +const std::string& arg2 = "world"; +const std::string& expected = "Hello, world!"; + +const std::string& result = format::format(formatOrig, { arg1, arg2 }); +_.assertIsEqual(result, expected); +SECTION_END() + +SECTION(Test format with multiple values reversed) +const std::string& formatOrig = "{1}, {0}!"; +const std::string& arg1 = "world"; +const std::string& arg2 = "Hello"; +const std::string& expected = "Hello, world!"; + +const std::string& result = format::format(formatOrig, { arg1, arg2 }); +_.assertIsEqual(result, expected); +SECTION_END() + +TEST_END() diff --git a/tools/add_copyright_header.py b/tools/add_copyright_header.py index 7df7aba6c..4e1557490 100644 --- a/tools/add_copyright_header.py +++ b/tools/add_copyright_header.py @@ -20,6 +20,10 @@ # SOFTWARE. # ##################################################################################################### +""" +Add a copyright header to all files. +""" + import datetime import re from pathlib import Path @@ -128,18 +132,36 @@ def count_lines(text: str) -> int: + """ + Count the number of lines in a string. + :param text: The string to count the lines of. + :return: The number of lines. + """ + return len(text.splitlines()) def first_n_lines(text: str, n: int) -> str: + """ + Get the first n lines of a string. + :param text: The string to get the first n lines of. + :param n: The number of lines to get. + :return: The first n lines of the string. + """ + lines = text.splitlines() return "\n".join(lines[0:n]) -def process(file: Path): +def process(file: Path) -> None: + """ + Process the file, adding or updating the header if necessary. + :param file: The file to process. + """ if ( - file.suffix in [".cpp", ".hpp", ".stp_settings"] or file.name == "cpp.hint" - ): # C++ Source / Header + file.suffix in (".cpp", ".hpp") # C++ Source / Header + or file.name == "cpp.hint" # C++ Hint file + ): with open(file, "r") as f: contents = f.read() results = re.match( @@ -161,7 +183,9 @@ def process(file: Path): with open(file, "w") as f: f.write(contents) elif ( - file.suffix == ".py" or file.name == "CMakeLists.txt" + file.suffix == ".py" + or file.name == "CMakeLists.txt" + or ".stp_" in file.suffix # Steppable configuration files ): # Python File or CMake file with open(file, "r") as f: contents = f.read() @@ -186,7 +210,12 @@ def process(file: Path): f.write(contents) -def walk_into_directory(path: Path): +def walk_into_directory(path: Path) -> None: + """ + Walk into the directory and process all files. + :param path: The directory to walk + """ + for subpath in path.rglob("*"): if subpath.is_file(): process(subpath) diff --git a/tools/benchmark.py b/tools/benchmark.py index 58f6dce6e..4132c7a09 100644 --- a/tools/benchmark.py +++ b/tools/benchmark.py @@ -20,6 +20,10 @@ # SOFTWARE. # ##################################################################################################### +""" +Benchmarking script for Steppable executables. +""" + import argparse import random import subprocess @@ -32,7 +36,7 @@ BUILD_PATH_DEFAULT = "build" FUNCTIONS = { - "abs": lambda x, y: abs(x), + "abs": lambda x, _: abs(x), "add": lambda x, y: x + y, "comparison": lambda x, y: x > y, "division": lambda x, y: x / y, @@ -48,6 +52,14 @@ def _benchmark_function( input_1: int, input_2: int, ) -> float: + """ + Benchmark a Python function. + :param function: The function to benchmark. + :param input_1: The first input. + :param input_2: The second input. + :return: The time taken to run the function. + """ + start = time.time() try: function(input_1, input_2) @@ -65,6 +77,16 @@ def _benchmark( verbose: bool = False, timeout: int = 10, ) -> float: + """ + Benchmark a system executable. + :param cmd: The executable to run. + :param input_str1: The first input. + :param input_str2: The second input. + :param verbose: Whether to print the output. + :param timeout: The timeout for the process. + :return: The time taken to run the executable. + """ + start = time.time() try: result = subprocess.run( @@ -92,6 +114,16 @@ def _benchmark( def benchmark( cmd: str, inputs: List[str], limit: int, verbose: bool = False, timeout: int = 10 ) -> Tuple[List[float], List[float], bool]: + """ + Benchmark a Steppable executable. + :param cmd: The executable to run. + :param inputs: The inputs to run the executable on. + :param limit: The limit for the inputs. + :param verbose: Whether to print the output. + :param timeout: The timeout for the process. + :return: The time taken to run the executable. + """ + random_number = random.randint(0, limit) random_number_str = str(random_number) time_needed = [] @@ -114,7 +146,11 @@ def benchmark( return time_needed, time_needed_system, system_available -def main(): +def main() -> None: + """ + Main function for the benchmarking script. + """ + parser = argparse.ArgumentParser( prog="benchmark.py", description="Performs benchmarks on Steppable executables", diff --git a/tools/building/compiler_detection.py b/tools/building/compiler_detection.py index 0ea383775..148ff445b 100644 --- a/tools/building/compiler_detection.py +++ b/tools/building/compiler_detection.py @@ -78,6 +78,7 @@ def get_identification(compiler_path: Path, compiler_type: int) -> str: def register_compiler(path: Path) -> None: """ Adds the compiler path to the status.json file in the build directory. This is used to cache the compiler path. + :param path: The path to the compiler executable. """ with open(BUILD_DIR / "status.json", "w") as f: json.dump({"compiler": str(path)}, f) diff --git a/tools/building/project.py b/tools/building/project.py index c84d0687e..161eb9311 100644 --- a/tools/building/project.py +++ b/tools/building/project.py @@ -338,6 +338,8 @@ def add_component(self, group: str, name: str) -> None: """ Adds a component to the project. Components are the building blocks of the project, and are linked together to build the final executables. + :param group: The group to which the component belongs. + :param name: The name of the component. """ files = [ diff --git a/tools/generate_changelog.py b/tools/generate_changelog.py new file mode 100644 index 000000000..1769b2681 --- /dev/null +++ b/tools/generate_changelog.py @@ -0,0 +1,71 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +import subprocess +from typing import List + + +def get_commits() -> List[str]: + """ + Get the commits between the main and develop branches. + :return: A list of commits. + """ + + # git log main..develop --pretty="%B" --reverse + try: + output = subprocess.check_output( + ["git", "log", "main..develop", "--pretty=%B#", "--reverse"], + universal_newlines=True, + ) + except subprocess.CalledProcessError as e: + print(f"ERROR: {e}") + return [] + except FileNotFoundError: + print(f"ERROR: Git not found on the system.") + return [] + + # Do some processing, ie. split the output into a list of commits + lines = output.split("\n#") + commits = [line.strip() for line in lines if line.strip()] + + return commits + + +def process_changelog() -> None: + """ + Generate a changelog from the commits between the main and develop branches. + """ + + print("INFO: Generating changelog") + commits = get_commits() + + for commit in commits: + lines = commit.split("\n") + print(f"- **{lines[0]}**") + lines.pop(0) + + for line in lines: + print(f" {line}") + + +if __name__ == "__main__": + process_changelog() diff --git a/tools/install.py b/tools/install.py new file mode 100644 index 000000000..6e7b65ff9 --- /dev/null +++ b/tools/install.py @@ -0,0 +1,58 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +""" +Installs the Steppable settings and resources to the user home. +""" + +from lib.paths import DEFAULT_CONFIG_DIR, CONFIG_DIR +import shutil + + +def copy_resources() -> None: + """ + Copy the resources to the user home. + """ + # Copy the resources + if CONFIG_DIR.is_dir(): + # Only copy the files + for file in DEFAULT_CONFIG_DIR.iterdir(): + if file.is_file(): + print(f"Copying FILE {file.name}") + shutil.copy(file, CONFIG_DIR) + else: + print(f"Copying DIRECTORY {file.name}") + shutil.copytree(file, CONFIG_DIR / file.name, dirs_exist_ok=True) + return + shutil.copytree(DEFAULT_CONFIG_DIR, CONFIG_DIR) + + +def install() -> None: + """ + Install the Steppable settings and resources. + """ + + copy_resources() + + +if __name__ == "__main__": + install() diff --git a/tools/new_component.py b/tools/new_component.py index bdd1de246..85839b9d9 100644 --- a/tools/new_component.py +++ b/tools/new_component.py @@ -21,66 +21,10 @@ ##################################################################################################### import datetime -import sys from pathlib import Path from lib.paths import PROJECT_PATH, SRC_DIR, TESTS_DIR - - -class _Getch: - """Gets a single character from standard input. Does not echo to the - screen.""" - - def __init__(self): - if not hasattr(sys.stdin, "fileno"): - self.impl = input - return - try: - self.impl = _GetchWindows() - except ImportError: - self.impl = _GetchUnix() - - def __call__(self): - return self.impl() - - -class _GetchUnix: - def __init__(self): - import tty # pyright: ignore - - def __call__(self) -> str: - import termios - import tty - - fd = sys.stdin.fileno() - error = False - try: - old_settings = termios.tcgetattr(fd) - tty.setraw(sys.stdin.fileno()) - ch = sys.stdin.read(1) - error = False - except termios.error: - ch = input() - error = True - finally: - if not error: - termios.tcsetattr( - fd, termios.TCSADRAIN, old_settings # pyright: ignore - ) - return ch - - -class _GetchWindows: - def __init__(self): - import msvcrt # pyright: ignore - - def __call__(self) -> str: - import msvcrt - - return msvcrt.getch() # pyright: ignore - - -getch = _Getch() +from lib.getch import getch WELCOME_STRING = """\ WELCOME TO STEPPABLE! @@ -148,6 +92,10 @@ def __call__(self) -> str: def show_help() -> None: + """ + Show the help text for new contributors. + """ + for idx, part in enumerate(HELP): print(part) if idx != (len(HELP) - 1): @@ -163,6 +111,11 @@ def show_help() -> None: def validate_name(name: str) -> bool: + """ + Validate the name of the component. It cannot contain restricted characters. + :param name: The name of the component. + :return: True if the name is valid, False otherwise. + """ if ( "*" in name or '"' in name @@ -180,6 +133,12 @@ def validate_name(name: str) -> bool: def make_dir(name: str, date: str, author: str) -> None: + """ + Create a new directory for the component. + :param name: The name of the component. + :param date: The date of creation. + :param author: The author of the component. + """ path: Path = SRC_DIR / name if not path.is_dir(): @@ -361,6 +320,10 @@ def make_dir(name: str, date: str, author: str) -> None: def patch_cmakelists(name: str) -> None: + """ + Patch the CMakeLists.txt file to include the new component. + :param name: The name of the component. + """ with open(PROJECT_PATH / "CMakeLists.txt") as f: contents = f.read() @@ -374,7 +337,11 @@ def patch_cmakelists(name: str) -> None: def ordinal(n: int) -> str: """ Get the ordinal numeral for a given number n. + :param n: The number. + :return: The ordinal numeral. """ + + # Credits to https://stackoverflow.com/a/20007730/14868780 for this crazy one-liner. return f"{n:d}{'tsnrhtdd'[(n // 10 % 10 != 1) * (n % 10 < 4) * n % 10::4]}" @@ -384,6 +351,10 @@ def ordinal(n: int) -> str: def main(): + """ + Main function for the new component wizard. + """ + print(WELCOME_STRING) selection = getch().upper() diff --git a/tools/patch_compile_commands.py b/tools/patch_compile_commands.py index 01a3ff8fc..463012141 100644 --- a/tools/patch_compile_commands.py +++ b/tools/patch_compile_commands.py @@ -71,12 +71,17 @@ def get_compile_commands() -> Path: raise RuntimeError("Cannot get the CMake build directory") -def patch(): +def patch() -> None: """Remove the NO_MAIN definition in compile_commands.json.""" - file = get_compile_commands() - with open(file) as f: - objs = json.load(f) + try: + file = get_compile_commands() + + with open(file) as f: + objs = json.load(f) + except (RuntimeError, FileNotFoundError): + print("Warning: CMake compile_commands cannot be found. Exiting.") + exit(0) modified_objs = [] for obj in objs: diff --git a/tools/run_clang_tidy.py b/tools/run_clang_tidy.py index 5bb551af6..46cd134ae 100644 --- a/tools/run_clang_tidy.py +++ b/tools/run_clang_tidy.py @@ -63,15 +63,18 @@ import tempfile import threading import traceback +from typing import List, Union -try: - import yaml # pyright: ignore -except ImportError: - yaml = None +import yaml # pyright: ignore -def strtobool(val): - """Convert a string representation of truth to a bool following LLVM's CLI argument parsing.""" +def strtobool(val: str) -> bool: + """ + Convert a string representation of truth to a bool following LLVM's CLI argument parsing. + :param val: The string to convert. + :return: The bool value. + :raises argparse.ArgumentTypeError: If the string is not a valid boolean. + """ val = val.lower() if val in ["", "true", "1"]: @@ -85,8 +88,12 @@ def strtobool(val): ) -def find_compilation_database(path): - """Adjusts the directory until a compilation database is found.""" +def find_compilation_database(path: str) -> str: + """ + Adjusts the directory until a compilation database is found. + :param path: The path close to the compilation database. + :return: The absolute path to the compilation database. + """ result = os.path.realpath("./") while not os.path.isfile(os.path.join(result, path)): parent = os.path.dirname(result) @@ -97,31 +104,58 @@ def find_compilation_database(path): return result -def make_absolute(f, directory): +def make_absolute(f: str, directory: str) -> str: + """ + Return an absolute path if f is not already an absolute path. + :param f: The file path. + :param directory: The directory path. + :return: The absolute path. + """ if os.path.isabs(f): return f return os.path.normpath(os.path.join(directory, f)) def get_tidy_invocation( - f, - clang_tidy_binary, - checks, - tmpdir, - build_path, - header_filter, - allow_enabling_alpha_checkers, - extra_arg, - extra_arg_before, - quiet, - config_file_path, - config, - line_filter, - use_color, - plugins, - warnings_as_errors, -): - """Gets a command line for clang-tidy.""" + f: str, + clang_tidy_binary: str, + checks: str, + tmpdir: Union[str, None], + build_path: str, + header_filter: str, + allow_enabling_alpha_checkers: str, + extra_arg: str, + extra_arg_before: str, + quiet: str, + config_file_path: str, + config: str, + line_filter: str, + use_color: str, + plugins: str, + warnings_as_errors: str, +) -> List[str]: + """ + Gets a command line for clang-tidy. + :param f: The file path. + :param clang_tidy_binary: The clang-tidy binary path. + :param checks: The checks to run. + :param tmpdir: The temporary directory. + :param build_path: The build path. + :param header_filter: The header filter. + :param allow_enabling_alpha_checkers: Whether to allow enabling alpha checkers. + :param extra_arg: The extra arguments. + :param extra_arg_before: The extra arguments before. + :param quiet: Whether to run clang-tidy in quiet mode. + :param config_file_path: The config file path. + :param config: The config. + :param line_filter: The line filter. + :param use_color: Whether to use colors in diagnostics. + :param plugins: The plugins to load. + :param warnings_as_errors: Whether to upgrade warnings to errors. + + :return: The full command line. + """ + start = [clang_tidy_binary] if allow_enabling_alpha_checkers: start.append("-allow-enabling-analyzer-alpha-checkers") @@ -162,8 +196,13 @@ def get_tidy_invocation( return start -def merge_replacement_files(tmpdir, mergefile): - """Merge all replacement files in a directory into a single file""" +def merge_replacement_files(tmpdir: str, mergefile: str) -> None: + """ + Merge all replacement files in a directory into a single file + with the same format. + :param tmpdir: The temporary directory. + :param mergefile: The file to merge into. + """ # The fixes suggested by clang-tidy >= 4.0.0 are given under # the top level key 'Diagnostics' in the output yaml files mergekey = "Diagnostics" @@ -187,8 +226,15 @@ def merge_replacement_files(tmpdir, mergefile): open(mergefile, "w").close() -def find_binary(arg, name, build_path): - """Get the path for a binary or exit""" +def find_binary(arg: str, name: str, build_path: str) -> str: + """ + Get the path for a binary or exit + :param arg: The binary path. + :param name: The binary name. + :param build_path: The build path. + :return: The binary path. + :raises SystemExit: If the binary is not found. + """ if arg: if shutil.which(arg): return arg @@ -209,8 +255,15 @@ def find_binary(arg, name, build_path): ) -def apply_fixes(args, clang_apply_replacements_binary, tmpdir): - """Calls clang-apply-fixes on a given directory.""" +def apply_fixes( + args: argparse.Namespace, clang_apply_replacements_binary: str, tmpdir: str +) -> None: + """ + Calls clang-apply-fixes on a given directory. + :param args: The command line arguments. + :param clang_apply_replacements_binary: The clang-apply-replacements binary path. + :param tmpdir: The temporary directory. + """ invocation = [clang_apply_replacements_binary] invocation.append("-ignore-insert-conflict") if args.format: @@ -221,8 +274,25 @@ def apply_fixes(args, clang_apply_replacements_binary, tmpdir): subprocess.call(invocation) -def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_files): - """Takes filenames out of queue and runs clang-tidy on them.""" +def run_tidy( + args: argparse.Namespace, + clang_tidy_binary: str, + tmpdir: str, + build_path: str, + queue: queue.Queue, + lock: threading.Lock, + failed_files: List[str], +) -> None: + """ + Takes filenames out of queue and runs clang-tidy on them. + :param args: The command line arguments. + :param clang_tidy_binary: The clang-tidy binary path. + :param tmpdir: The temporary directory. + :param build_path: The build path. + :param queue: The queue of files to process. + :param lock: The threading lock. + :param failed_files: The list of failed files. + """ while True: name = queue.get() invocation = get_tidy_invocation( @@ -261,7 +331,10 @@ def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_fi queue.task_done() -def main(): +def main() -> None: + """ + The main function. + """ parser = argparse.ArgumentParser( description=( "Runs clang-tidy over all files in a compilation database. Requires clang-tidy and clang-apply-replacements" @@ -435,7 +508,7 @@ def main(): ) combine_fixes = False - export_fixes_dir = None + export_fixes_dir = "" delete_fixes_dir = False if args.export_fixes is not None: # if a directory is given, create it if it does not exist @@ -569,7 +642,7 @@ def main(): if args.fix: print("Applying fixes ...") try: - apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir) + apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir) # type: ignore except: print("Error applying fixes.\n", file=sys.stderr) traceback.print_exc() diff --git a/tools/translation.py b/tools/translation.py new file mode 100644 index 000000000..76ec45749 --- /dev/null +++ b/tools/translation.py @@ -0,0 +1,237 @@ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +""" +Translates all strings in a stp_strings file. + +Process: + |-> Yes ----------------+ + | | ++----------+ |-Index file exists? | +| Read all | | +-------------+ | +--------------------------+ +| strings | -+-> No | Write index |--+---> | Write translated strings | +| in file | | file | | to a new file | ++----------+ +-------------+ +--------------------------+ +""" +import argparse +import re +import readline as _ # Enables input history and more advanced editing capabilities. +import uuid +from pathlib import Path + +from lib.printing import erase_line, print_error +from tools.install import install + +ISO_639_REGEX = re.compile(r"^[a-z]{2}(-[A-Z]{2})?$") +LOCALIZED_HEADER = """\ +##################################################################################################### +# Copyright (c) 2023-2024 NWSOFT # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy # +# of this software and associated documentation files (the "Software"), to deal # +# in the Software without restriction, including without limitation the rights # +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # +# copies of the Software, and to permit persons to whom the Software is # +# furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in all # +# copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # +# SOFTWARE. # +##################################################################################################### + +# NOTE: This file is generated. Do not edit it manually. Any changes will be overwritten. +# STR_GUID: (key) / STRING {TYPE}: (string) +# eg: a491b7b2-1239-4acb-9045-0747d806b96f >> "Hello World!" +# Recommended syntax highlighting: Bash Script +""" + + +def ask_translation(string: str) -> str: + """ + Asks the user to translate a string. + :param string: The string to translate. + :return: The translation of the string. + """ + print(f'String : "{string}"') + translation = input("Translation : ") + print(erase_line(2)) + + return translation + + +def verify_language(language: str) -> None: + """ + Verifies that the language code is a valid ISO 639-1 code. Eg. "en" or "en-US". + Exits the program if the language code is invalid. + :param language: The language code to verify. + """ + if not ISO_639_REGEX.match(language): + print(f"ERROR: Invalid language code: {language}") + exit(1) + + +def write_indexed_file(component: str, *, append: bool = False) -> None: + """ + Writes the indexed entries to a file with the given path. + Indexed entries are the strings with a GUID assigned to them. + + :param component: The name of the component to write the indexed file for. + :param append: If True, appends the strings to the file. If False, overwrites the file. + """ + path = Path(f"res/translations/{component}.stp_strings") + mode = "a" if append else "w" + + print(f"Enter the strings in {component}, blank line to quit.") + string = input("> ") + guid = str(uuid.uuid4()) + strings = [f'{guid} >> "{string}"'] + while string != "": + string = input("> ") + guid = str(uuid.uuid4()) + strings.append(f'{guid} >> "{string}"') + + strings.pop(-1) + for idx, string in enumerate(strings): + if string.endswith(" >> "): + strings.pop(idx) + + with path.open(mode) as f: + content = "\n".join(strings) + if not append: + content = LOCALIZED_HEADER.format(TYPE="ORIGINAL") + content + else: + content = "\n" + content + f.write(content) + + +def add_translations(file: Path, language: str) -> None: + """ + Adds a new translation to the given file. + Writes the translations to a new file. + :param file: The file to translate. + :param language: The language to translate the strings to. + """ + + verify_language(language) # Check if the language code is valid + print("INFO: Thank you for helping us translate the project!") + print(f"INFO: TRANSLATING {file} TO {language}") + component = file.stem + + if not file.is_file(): + write_indexed_file(component, append=False) + + entries = [] + + with file.open("r") as f: + lines = f.readlines() + for line in lines: + line = line.strip() + if not line: + # Skip empty lines + continue + + # Step 2: Check for invalid characters: \ " ' + if line.startswith("#"): + continue # Skip comments + line_parts = line.split(" >> ") # Split the UUID and the string + + # Step 1: Get the GUID and the string + guid, line = line_parts + line = line.replace('"', "") # Remove quotes + + if (pos := line.find("\\")) != -1: + print_error(line, pos, "Invalid character: \\") + exit(1) + if (pos := line.find('"')) != -1: + print_error(line, pos, 'Invalid character: "') + exit(1) + + if not line: + print_error(line, 0, "Empty string") + exit(1) + + # Step 3: Ask for translations + if language.startswith("en"): + # Since strings in Steppable are in English, we don't need to translate them. + translation = line + else: + translation = ask_translation(line) + # Step 4: Make the translation entry + entry = f'{guid} >> "{translation}"' + entries.append(entry) + + # Step 5: Write the translations to a new file + if not (lang_path := Path(f"res/translations/{language}")).is_dir(): + lang_path.mkdir(parents=True) + output_file = Path(f"res/translations/{language}/{component}.stp_localized") + with output_file.open("w") as f: + f.write(LOCALIZED_HEADER.format(TYPE="TRANSLATED") + "\n".join(entries)) + print(f"INFO: Translations written to {output_file}. Done.") + + # Step 6: Write the indexed file to the user configuration for future reference. + install() + + +def main(): + parser = argparse.ArgumentParser( + description="Translate strings in a stp_strings file." + ) + subparsers = parser.add_subparsers(dest="command") + + add_tr_parser = subparsers.add_parser("add_tr") + add_tr_parser.add_argument( + "component", + help="The name of the component to translate.", + ) + add_tr_parser.add_argument( + "language", + help="The language to translate the strings to.", + ) + + wr_idx_parser = subparsers.add_parser("wr_idx") + wr_idx_parser.add_argument( + "component", + help="The name of the component to write the indexed file for.", + ) + wr_idx_parser.add_argument( + "--append", + action="store_true", + help="Append the strings to the file.", + ) + + args = parser.parse_args() + if args.command == "add_tr": + path = Path(f"res/translations/{args.component}.stp_strings") + add_translations(path, args.language) + elif args.command == "wr_idx": + write_indexed_file(args.component, append=args.append) + + +if __name__ == "__main__": + main()