diff --git a/src/formula.cpp b/src/formula.cpp index a9fb6b4a8..0564f5c94 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -34,6 +34,7 @@ #include #include "asserts.hpp" +#include "logger.hpp" #include "formatter.hpp" #include "formula.hpp" #include "formula_callable.hpp" @@ -1028,13 +1029,25 @@ namespace { } std::sort(known_v.begin(), known_v.end()); - std::string known; + + std::string some_known = ""; + std::string all_known = ""; + + const uint_fast8_t some_known_limit = 3; + uint_fast8_t some_known_index = 0; // Suggest a correction boost::optional candidate_match; size_t candidate_value = std::min(static_cast(4), id_.size()); for(const std::string& k : known_v) { - known += k + " \n"; + + all_known += k + '\n'; + + if (some_known_index < some_known_limit) { + + some_known += k + '\n'; + some_known_index++; + } size_t d = edit_distance_calculator(id_, k)(); if (candidate_value > d) { @@ -1049,11 +1062,37 @@ namespace { if (candidate_match) { suggested_match = "\nMaybe you meant '" + *candidate_match + "'?\n"; } + if(callable_def_->getTypeName() != nullptr) { - STRICT_ERROR("Unknown symbol '" << id_ << "' in " << *callable_def_->getTypeName() << " " << debugPinpointLocation() << suggested_match << "\nKnown symbols: (excluding built-in functions)\n" << known << "\n"); + LOG_WARN_WO_SDL( + "Unknown symbol '" << id_ << "' in " << + * callable_def_->getTypeName() << ' ' << + debugPinpointLocation() << suggested_match << + "\nKnown symbols: (excluding built-in functions)\n" << + all_known << '\n'); + + STRICT_ERROR( + "Unknown symbol '" << id_ << "' in " << + * callable_def_->getTypeName() << ' ' << + debugPinpointLocation() << suggested_match << + "\nThere are " << known_v.size() << " known symbols (excluding " << + "built-in functions), check recent console output to find the " << + "list of known symbols.\n"); } else { - STRICT_ERROR("Unknown identifier '" << id_ << "' " << debugPinpointLocation() << suggested_match << "\nIdentifiers that are valid in this scope:\n" << known << "\n"); + LOG_WARN_WO_SDL( + "Unknown identifier '" << id_ << "' " << + debugPinpointLocation() << suggested_match << + "\nIdentifiers that are valid in this scope:\n" << + all_known << '\n'); + + STRICT_ERROR( + "Unknown identifier '" << id_ << "' " << + debugPinpointLocation() << suggested_match << + "\nThere are " << known_v.size() << " known identifiers valid " << + "in this scope, check recent console output to find the list " << + "of valid identifiers.\n"); } + } else if(callable_def_) { std::string type_name = "unk"; if(callable_def_->getTypeName()) { diff --git a/src/logger.cpp b/src/logger.cpp index c7e0b8333..e20c019d4 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -21,6 +21,8 @@ distribution. */ +#include + #include "logger.hpp" namespace @@ -41,3 +43,13 @@ void log_internal(SDL_LogPriority priority, const std::string& str) } } +/** + * Helps the fact that a very large message can not be logged using + * `SDL_LogMessage(4)`. + */ +void log_internal_wo_SDL( + const SDL_LogPriority priority, const std::string & str) +{ + // XXX Change for something more worked, such as `https://github.com/xeekworx/logger`. + std::cout << str; /* XXX */ +} diff --git a/src/logger.hpp b/src/logger.hpp index 845e83353..d12f3534b 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -44,6 +44,12 @@ void log_internal(SDL_LogPriority priority, const std::string& s); +/** + * Logs without resorting to SDL. This way very large messages can be + * logged. SDL truncates log messages larger than 4.096 characters. + */ +void log_internal_wo_SDL(SDL_LogPriority priority, const std::string & s); + #define LOG_VERBOSE(_a) \ do { \ std::ostringstream _s; \ @@ -72,6 +78,16 @@ void log_internal(SDL_LogPriority priority, const std::string& s); log_internal(SDL_LOG_PRIORITY_WARN, _s.str()); \ } while(0) +/** + * Logs without resorting to SDL. This way very large messages can be + * logged. SDL truncates log messages larger than 4.096 characters. + */ +#define LOG_WARN_WO_SDL(_a) if (true) { \ + std::ostringstream _s; \ + _s << __SHORT_FORM_OF_FILE__ << ':' << __LINE__ << \ + " : " << _a; \ + log_internal_wo_SDL(SDL_LOG_PRIORITY_WARN, _s.str()); } + #define LOG_ERROR(_a) \ do { \ std::ostringstream _s; \