From f4e3bd6180b043bd0eca37503fb616c33624192b Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Sat, 26 Feb 2022 16:44:28 +0100 Subject: [PATCH] Add enhanced gcc warnings --- CMakeLists.txt | 77 +++++++++++++++++++++------------------ src/lexer.cc | 16 +++++--- src/main.cc | 14 ++++--- src/mpreal-out.cc | 2 +- src/object.h | 8 ++-- src/program.cc | 12 ++++-- src/program.h | 52 +++++++++++++------------- src/rpn-branch.cc | 18 ++++----- src/rpn-general.cc | 1 - src/rpn-program.cc | 6 +-- src/rpn-stack.cc | 24 +++++++++--- src/rpn-store.cc | 3 +- src/rpn-test-framework.cc | 6 +-- src/rpn-test.cc | 2 +- src/rpn-time.cc | 3 -- 15 files changed, 134 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f96e47..ec7d5dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,16 +46,6 @@ set(RPN_LICENSE "LGPLv3") set(RPN_LICENSE_FILE "${PROJECT_SOURCE_DIR}/LICENSE") set(RPN_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") -# compiler options -if(CMAKE_COMPILER_IS_GNUCXX) - message(STATUS "Compiler type GNU: ${CMAKE_CXX_COMPILER}") - # TODO still up to date? - set(BASE_COMPILER_OPTIONS "-std=c++17 -Wl,--no-as-needed") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -s") -endif() - # custom linenoise-ng if(NOT EXISTS "${PROJECT_SOURCE_DIR}/linenoise-ng/.git") execute_process(command git submodule init ${PROJECT_SOURCE_DIR}/linenoise-ng) @@ -73,32 +63,47 @@ endif() # includes include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/linenoise-ng/include ${PROJECT_SOURCE_DIR}/mpreal) -# build -add_executable( - rpn - ${PROJECT_SOURCE_DIR}/src/main.cc - ${PROJECT_SOURCE_DIR}/src/object.cc - ${PROJECT_SOURCE_DIR}/src/mpreal-out.cc - ${PROJECT_SOURCE_DIR}/src/program.cc - ${PROJECT_SOURCE_DIR}/src/lexer.cc - ${PROJECT_SOURCE_DIR}/src/input.cc - ${PROJECT_SOURCE_DIR}/src/rpn-branch.cc - ${PROJECT_SOURCE_DIR}/src/rpn-complex.cc - ${PROJECT_SOURCE_DIR}/src/rpn-general.cc - ${PROJECT_SOURCE_DIR}/src/rpn-logs.cc - ${PROJECT_SOURCE_DIR}/src/rpn-program.cc - ${PROJECT_SOURCE_DIR}/src/rpn-real.cc - ${PROJECT_SOURCE_DIR}/src/rpn-stack.cc - ${PROJECT_SOURCE_DIR}/src/rpn-store.cc - ${PROJECT_SOURCE_DIR}/src/rpn-string.cc - ${PROJECT_SOURCE_DIR}/src/rpn-test.cc - ${PROJECT_SOURCE_DIR}/src/rpn-test-framework.cc - ${PROJECT_SOURCE_DIR}/src/rpn-time.cc - ${PROJECT_SOURCE_DIR}/src/rpn-trig.cc - ${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp - ${PROJECT_SOURCE_DIR}/linenoise-ng/src/linenoise.cpp - ${PROJECT_SOURCE_DIR}/linenoise-ng/src/wcwidth.cpp -) +# src +set(RPN_SRC_FILES + ${PROJECT_SOURCE_DIR}/src/main.cc + ${PROJECT_SOURCE_DIR}/src/object.cc + ${PROJECT_SOURCE_DIR}/src/mpreal-out.cc + ${PROJECT_SOURCE_DIR}/src/program.cc + ${PROJECT_SOURCE_DIR}/src/lexer.cc + ${PROJECT_SOURCE_DIR}/src/input.cc + ${PROJECT_SOURCE_DIR}/src/rpn-branch.cc + ${PROJECT_SOURCE_DIR}/src/rpn-complex.cc + ${PROJECT_SOURCE_DIR}/src/rpn-general.cc + ${PROJECT_SOURCE_DIR}/src/rpn-logs.cc + ${PROJECT_SOURCE_DIR}/src/rpn-program.cc + ${PROJECT_SOURCE_DIR}/src/rpn-real.cc + ${PROJECT_SOURCE_DIR}/src/rpn-stack.cc + ${PROJECT_SOURCE_DIR}/src/rpn-store.cc + ${PROJECT_SOURCE_DIR}/src/rpn-string.cc + ${PROJECT_SOURCE_DIR}/src/rpn-test.cc + ${PROJECT_SOURCE_DIR}/src/rpn-test-framework.cc + ${PROJECT_SOURCE_DIR}/src/rpn-time.cc + ${PROJECT_SOURCE_DIR}/src/rpn-trig.cc) + +set(LINENOISE_NG_SRC_FILES +${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp +${PROJECT_SOURCE_DIR}/linenoise-ng/src/linenoise.cpp +${PROJECT_SOURCE_DIR}/linenoise-ng/src/wcwidth.cpp) + +# compiler options +set_source_files_properties(${RPN_SRC_FILES} COMPILE_FLAGS # some harder warnings + "-Wall -Wextra -pedantic -Wno-missing-field-initializers") + +if(CMAKE_COMPILER_IS_GNUCXX) + message(STATUS "Compiler type GNU: ${CMAKE_CXX_COMPILER}") + # TODO still up to date? + set(BASE_COMPILER_OPTIONS "-std=c++17 -Wl,--no-as-needed") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -s") +endif() + +add_executable(rpn ${RPN_SRC_FILES} ${LINENOISE_NG_SRC_FILES}) target_link_libraries(rpn mpfr) target_link_libraries(rpn gmp) diff --git a/src/lexer.cc b/src/lexer.cc index 79cee56..41cce71 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -2,8 +2,11 @@ #include "lexer.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" // allow designated initializers + bool Lexer::Analyse(string& entry, map& keywords, vector& elements, - vector& errors) { + vector& errors) { size_t jump; for (size_t i = 0; i < entry.size(); i++) { if (isspace(entry[i])) continue; @@ -49,7 +52,7 @@ void Lexer::Trim(string& s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end()); } -bool Lexer::ParseString(string& entry, size_t idx, size_t& next_idx, vector& errors, +bool Lexer::ParseString(string& entry, size_t idx, size_t& next_idx, vector& errors __attribute__((unused)), vector& elements) { // here we are sure that entry[0] is at least '"' for (size_t i = idx + 1; i < entry.size(); i++) { @@ -66,7 +69,7 @@ bool Lexer::ParseString(string& entry, size_t idx, size_t& next_idx, vector& errors, +bool Lexer::ParseSymbol(string& entry, size_t idx, size_t& next_idx, vector& errors __attribute__((unused)), vector& elements) { // here we are sure that entry[0] is at least '\'' for (size_t i = idx + 1; i < entry.size(); i++) { @@ -81,7 +84,7 @@ bool Lexer::ParseSymbol(string& entry, size_t idx, size_t& next_idx, vector& errors, +bool Lexer::ParseProgram(string& entry, size_t idx, size_t& next_idx, vector& errors __attribute__((unused)), vector& elements) { // here we are sure that entry is at least "<<" // find last ">>" or "»" @@ -153,7 +156,6 @@ int Lexer::GetBaseAt(string& entry, size_t& next_idx, bool& positive) { bool Lexer::GetNUmberAt(string& entry, size_t idx, size_t& next_idx, int& base, mpreal** r, char delim) { stringstream ss; - int idxNumber = 0; string token; bool positive = true; @@ -193,7 +195,7 @@ bool Lexer::ParseNumber(string& entry, size_t idx, size_t& next_idx, vector& errors, +bool Lexer::ParseComplex(string& entry, size_t idx, size_t& next_idx, vector& errors __attribute__((unused)), vector& elements) { mpreal* re = nullptr; mpreal* im = nullptr; @@ -253,3 +255,5 @@ bool Lexer::ParseUnknown(string& entry, size_t idx, size_t& next_idx, vector 0) { out << '.'; - int remaining = MIN(strlen(print_from) - nexp - 1, digits) + 1; + int remaining = MIN(static_cast(strlen(print_from)) - nexp - 1, digits) + 1; for (int i = nexp; i < remaining + nexp; i++) out << print_from[i]; for (int i = 0; i < nexp + digits - len; i++) out << '0'; } diff --git a/src/object.h b/src/object.h index bf56f39..ba3e331 100644 --- a/src/object.h +++ b/src/object.h @@ -172,8 +172,8 @@ struct Symbol : Object { virtual Object* Clone() { return new Symbol(value, auto_eval); } virtual string Name() { return string("symbol"); } virtual ostream& Show(ostream& out) { return out << "'" << value << "'"; } - bool auto_eval; string value; + bool auto_eval; }; struct Keyword : Object { @@ -187,19 +187,19 @@ struct Keyword : Object { struct Branch : Object { Branch() : Object(kBranch) {} - explicit Branch(branch_fn_t fn__, const string& value__) : Object(kBranch) { - fn = fn__; + explicit Branch(branch_fn_t fn__, const string& value__) : Object(kBranch), fn(fn__), value(value__) { arg1 = static_cast(-1); arg2 = static_cast(-1); arg3 = static_cast(-1); arg_bool = 0; - value = value__; } explicit Branch(Branch& other) : Object(kBranch) { fn = other.fn; arg1 = other.arg1; arg2 = other.arg2; arg3 = other.arg3; + first_index = other.first_index; + last_index = other.last_index; arg_bool = other.arg_bool; value = other.value; } diff --git a/src/program.cc b/src/program.cc index 12e5ef4..df5f88e 100644 --- a/src/program.cc +++ b/src/program.cc @@ -3,6 +3,8 @@ #include "program.h" //< language reserved keywords (allowed types are kKeyword, kBranch or kUndef) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" // allow casting kBranch callbacks vector program::keywords_{ // GENERAL {kUndef, "", nullptr, "\nGENERAL"}, @@ -129,8 +131,7 @@ vector program::keywords_{ {kBranch, "else", (program_fn_t)&program::RpnElse, "used with if"}, {kBranch, "end", (program_fn_t)&program::RpnEnd, "used with various branch instructions"}, {kBranch, "start", (program_fn_t)&program::RpnStart, " start next| step"}, - {kBranch, "for", (program_fn_t)&program::RpnFor, - " for next| step"}, + {kBranch, "for", (program_fn_t)&program::RpnFor, " for next| step"}, {kBranch, "next", (program_fn_t)&program::RpnNext, "used with start and for"}, {kBranch, "step", (program_fn_t)&program::RpnStep, "used with start and for"}, {kKeyword, "ift", &program::RpnIft, "similar to if-then-end, ift"}, @@ -202,6 +203,7 @@ vector program::keywords_{ {kKeyword, "date", &program::RpnDate, "date in local format"}, {kKeyword, "ticks", &program::RpnTicks, "system tick in µs"}, }; +#pragma GCC diagnostic pop /// autocompletion vector for linenoise autocompletion vector& program::GetAutocompletionWords() { @@ -219,7 +221,6 @@ vector& program::GetAutocompletionWords() { RetValue program::Run() { bool go_out = false; RetValue ret = kOk; - ObjectType type; err_ = kOk; err_context_ = ""; @@ -598,7 +599,10 @@ RetValue program::Parse(string& entry) { push_back(new Keyword(element.fn, element.value)); break; case kBranch: +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" // allow casting kBranch callbacks push_back(new Branch((branch_fn_t)element.fn, element.value)); +#pragma GCC diagnostic pop break; default: ShowError(kUnknownError, "error creating program from entry"); @@ -637,8 +641,10 @@ RetValue program::ShowError() { case kInternalError: case kDeadlyError: ret = kDeadlyError; + break; default: ret = kOk; + break; } return ret; diff --git a/src/program.h b/src/program.h index cfe5827..865d701 100644 --- a/src/program.h +++ b/src/program.h @@ -213,7 +213,7 @@ class program : public deque, public Lexer { // test-core void RpnTest(); void RunTestFile(string test_filename, int& total_tests, int& total_tests_failed, int& total_steps, - int& total_steps_failed); + int& total_steps_failed); // test void RpnSup(void); @@ -248,42 +248,42 @@ class program : public deque, public Lexer { // convenience macros for rpn_xx function // carefull : some of these macros modify program flow -#define ERROR_CONTEXT(err) \ +#define ERROR_CONTEXT(err) \ do { \ err_ = (err); \ err_context_ = __FUNCTION__; \ } while (0) -#define MIN_ARGUMENTS(num) \ - do { \ - if ((num) >= 0 && stack_.size() < (num)) { \ - ERROR_CONTEXT(kMissingOperand); \ - return; \ - } \ +#define MIN_ARGUMENTS(num) \ + do { \ + if (stack_.size() < (num)) { \ + ERROR_CONTEXT(kMissingOperand); \ + return; \ + } \ } while (0) -#define MIN_ARGUMENTS_RET(num, ret) \ - do { \ - if ((num) >= 0 && stack_.size() < (num)) { \ - ERROR_CONTEXT(kMissingOperand); \ - return (ret); \ - } \ +#define MIN_ARGUMENTS_RET(num, ret) \ + do { \ + if (stack_.size() < (num)) { \ + ERROR_CONTEXT(kMissingOperand); \ + return (ret); \ + } \ } while (0) -#define ARG_MUST_BE_OF_TYPE(num, type) \ - do { \ - if ((num) >= 0 && stack_.at(num)->_type != (type)) { \ - ERROR_CONTEXT(kBadOperandType); \ - return; \ - } \ +#define ARG_MUST_BE_OF_TYPE(num, type) \ + do { \ + if (stack_.at(num)->_type != (type)) { \ + ERROR_CONTEXT(kBadOperandType); \ + return; \ + } \ } while (0) -#define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) \ - do { \ - if ((num) >= 0 && stack_.at(num)->_type != (type)) { \ - ERROR_CONTEXT(kBadOperandType); \ - return (ret); \ - } \ +#define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) \ + do { \ + if (stack_.at(num)->_type != (type)) { \ + ERROR_CONTEXT(kBadOperandType); \ + return (ret); \ + } \ } while (0) #endif // SRC_PROGRAM_HPP_ diff --git a/src/rpn-branch.cc b/src/rpn-branch.cc index e72d0cf..90e5912 100644 --- a/src/rpn-branch.cc +++ b/src/rpn-branch.cc @@ -83,7 +83,7 @@ size_t program::RpnEnd(Branch& myobj) { size_t ret = kStepOut; // arg1 = index of do+1 in case of do..unti..end - if (myobj.arg1 != -1) { + if (myobj.arg1 != kStepOut) { // in a template do..until..end MIN_ARGUMENTS_RET(1, kRtError); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError); @@ -106,7 +106,7 @@ size_t program::RpnEnd(Branch& myobj) { /// @return kStepOut next object to run in the current program is current + 1 /// @return kRtError something went wrong with preprocess, abort branch /// -size_t program::RpnDo(Branch& myobj) { +size_t program::RpnDo(Branch& myobj __attribute__((unused))) { // nothing return kStepOut; } @@ -118,7 +118,7 @@ size_t program::RpnDo(Branch& myobj) { /// @return kStepOut next object to run in the current program is current + 1 /// @return kRtError something went wrong with preprocess, abort Branch /// -size_t program::RpnUntil(Branch& myobj) { +size_t program::RpnUntil(Branch& myobj __attribute__((unused))) { // nothing return kStepOut; } @@ -170,7 +170,7 @@ void program::RpnIfte(void) { /// @return kStepOut next object to run in the current program is current + 1 /// @return kRtError something went wrong with preprocess, abort branch /// -size_t program::RpnWhile(Branch& myobj) { +size_t program::RpnWhile(Branch& myobj __attribute__((unused))) { // nothing return kStepOut; } @@ -298,8 +298,7 @@ size_t program::RpnNext(Branch& myobj) { mpfr_add(myobj.first_index.mpfr_ptr(), myobj.first_index.mpfr_srcptr(), mpreal(1).mpfr_srcptr(), MPFR_RNDD); // for command: increment symbol too - if (start_or_for->arg1 != -1) { - Object* obj; + if (start_or_for->arg1 != kStepOut) { Symbol* var; if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != kSymbol) { ERROR_CONTEXT(kMissingOperand); @@ -318,7 +317,7 @@ size_t program::RpnNext(Branch& myobj) { return kStepOut; } else { // for command: next instruction will be after symbol variable - if (start_or_for->arg1 != -1) return start_or_for->arg1 + 1; + if (start_or_for->arg1 != kStepOut) return start_or_for->arg1 + 1; // start command: next instruction will be after start command else return myobj.arg1 + 1; @@ -361,8 +360,7 @@ size_t program::RpnStep(Branch& myobj) { // carefull: round toward minus infinity to avoid missing last boundary (because growing step) mpfr_add(myobj.first_index.mpfr_ptr(), myobj.first_index.mpfr_srcptr(), step.mpfr_srcptr(), MPFR_RNDD); - if (start_or_for->arg1 != -1) { - Object* obj; + if (start_or_for->arg1 != kStepOut) { Symbol* var; // for command: increment symbol too @@ -382,7 +380,7 @@ size_t program::RpnStep(Branch& myobj) { ret = kStepOut; } else { // for command: next instruction will be after symbol variable - if (start_or_for->arg1 != -1) ret = start_or_for->arg1 + 1; + if (start_or_for->arg1 != kStepOut) ret = start_or_for->arg1 + 1; // start command: next instruction will be after start command else ret = myobj.arg1 + 1; diff --git a/src/rpn-general.cc b/src/rpn-general.cc index 7437f8f..2d1f09e 100644 --- a/src/rpn-general.cc +++ b/src/rpn-general.cc @@ -54,7 +54,6 @@ void program::RpnHelp() { cout << _syntax << endl; // keywords - unsigned int i = 0; for (auto& kw : keywords_) if (!kw.comment.empty()) { // titles in bold diff --git a/src/rpn-program.cc b/src/rpn-program.cc index c4d0199..d5e64bd 100644 --- a/src/rpn-program.cc +++ b/src/rpn-program.cc @@ -82,10 +82,10 @@ void program::RpnEval(void) { /// int program::RpnInprog(Branch& inprog_obj) { string context("->"); // for showing errors - int count_symbols = 0; + size_t count_symbols = 0; bool prog_found = false; - if (inprog_obj.arg1 == -1) { + if (inprog_obj.arg1 == kStepOut) { ERROR_CONTEXT(kUnknownError); return -1; } @@ -132,7 +132,7 @@ int program::RpnInprog(Branch& inprog_obj) { } // load variables - for (unsigned int i = inprog_obj.arg1 + count_symbols; i > inprog_obj.arg1; i--) { + for (size_t i = inprog_obj.arg1 + count_symbols; i > inprog_obj.arg1; i--) { local_heap_[reinterpret_cast(at(i))->value] = stack_.at(0)->Clone(); stack_.pop(); } diff --git a/src/rpn-stack.cc b/src/rpn-stack.cc index 92b2892..ee09d5a 100644 --- a/src/rpn-stack.cc +++ b/src/rpn-stack.cc @@ -31,7 +31,7 @@ void program::RpnDropn(void) { MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, kNumber); - int args = static_cast(stack_.value(0).toLong()); + size_t args = stack_.value(0).toULong(); MIN_ARGUMENTS(args + 1); stack_.erase(0, args + 1); } @@ -53,11 +53,15 @@ void program::RpnDupn(void) { MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, kNumber); - int args = static_cast(stack_.value(0).toLong()); + size_t args = stack_.value(0).toULong(); stack_.pop(); + if (args == 0) { + ERROR_CONTEXT(kOutOfRange); + return; + } MIN_ARGUMENTS(args); - for (int i = 0; i < args; i++) stack_.push_front(stack_.at(args - 1)->Clone()); + for (size_t i = 0; i < args; i++) stack_.push_front(stack_.at(args - 1)->Clone()); } /// @brief dup2 keyword implementation @@ -74,7 +78,7 @@ void program::RpnPick(void) { MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, kNumber); - int to_pick = static_cast(stack_.value(0).toLong()); + size_t to_pick = static_cast(stack_.value(0).toLong()); stack_.pop(); // treat stack_ depth errors @@ -105,9 +109,13 @@ void program::RpnRoll(void) { MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, kNumber); - int args = static_cast(stack_.value(0).toLong()); + size_t args = static_cast(stack_.value(0).toLong()); stack_.pop(); MIN_ARGUMENTS(args); + if (args == 0) { + ERROR_CONTEXT(kOutOfRange); + return; + } Object* tmp = stack_.at(args - 1); stack_.erase(args - 1, 1, false); @@ -120,9 +128,13 @@ void program::RpnRolld(void) { MIN_ARGUMENTS(2); ARG_MUST_BE_OF_TYPE(0, kNumber); - int args = static_cast(stack_.value(0).toLong()); + size_t args = static_cast(stack_.value(0).toLong()); stack_.pop(); MIN_ARGUMENTS(args); + if (args == 0) { + ERROR_CONTEXT(kOutOfRange); + return; + } Object* tmp = stack_.at(0); stack_.erase(0, 1, false); diff --git a/src/rpn-store.cc b/src/rpn-store.cc index 3e9c316..f1ca0ce 100644 --- a/src/rpn-store.cc +++ b/src/rpn-store.cc @@ -193,7 +193,6 @@ void program::RpnPurge(void) { /// @brief vars keyword implementation /// void program::RpnVars(void) { - Object* obj; program* parent = parent_; string name; int index = 1; @@ -214,7 +213,7 @@ void program::RpnVars(void) { while (parent != nullptr) { for (auto i : parent->local_heap_) { cout << "parent var " << index++ << ": name '" << i.first << "', type " << i.second->Name() << ", value "; - obj->Show(cout) << endl; + i.second->Show(cout) << endl; } parent = parent->parent_; } diff --git a/src/rpn-test-framework.cc b/src/rpn-test-framework.cc index f0e4742..7fc8482 100644 --- a/src/rpn-test-framework.cc +++ b/src/rpn-test-framework.cc @@ -117,9 +117,9 @@ void program::RunTestFile(string test_filename, int& total_tests, int& total_tes rpnstack stk; heap hp; bool failed = false; - bool is_first_step; - bool is_test_error_shown; - int last_err; + bool is_first_step = true; + bool is_test_error_shown = false; + int last_err = static_cast(kOk); stringstream cerr_buffer; streambuf* cerr_old_buffer; diff --git a/src/rpn-test.cc b/src/rpn-test.cc index fe610b0..76ab2a1 100644 --- a/src/rpn-test.cc +++ b/src/rpn-test.cc @@ -144,7 +144,7 @@ void program::RpnTestXor(void) { MIN_ARGUMENTS(2); ARG_MUST_BE_OF_TYPE(0, kNumber); ARG_MUST_BE_OF_TYPE(1, kNumber); - if (stack_.value(0) != 0 ^ stack_.value(1) != 0) + if ((stack_.value(0) != 0) ^ (stack_.value(1) != 0)) stack_.push(new Number(1)); else stack_.push(new Number(0)); diff --git a/src/rpn-time.cc b/src/rpn-time.cc index f763dba..e7afbc8 100644 --- a/src/rpn-time.cc +++ b/src/rpn-time.cc @@ -44,9 +44,6 @@ void program::RpnDate() { // date format = (M)M.DDYYYY date = static_cast(tm->tm_mon + 1) * 1000000.0 + static_cast(tm->tm_mday) * 10000.0 + static_cast(tm->tm_year + 1900); - - // push it - Number* num; // division after push for real precision stack_.push(new Number(date)); stack_.value(0) /= 1000000.0;