diff options
author | kanreki <32443233+kanreki@users.noreply.github.com> | 2021-09-14 12:15:53 -0700 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2021-12-08 16:17:17 -0800 |
commit | 586abd208221761a6c93bc4568513e9cd4dc287d (patch) | |
tree | d3d6c8da7e4584665bb705c25a91c5c66083de65 /src | |
parent | ed5886921bcce0d1a261a37aa83bf135259b7d21 (diff) | |
download | fork-ledger-586abd208221761a6c93bc4568513e9cd4dc287d.tar.gz fork-ledger-586abd208221761a6c93bc4568513e9cd4dc287d.tar.bz2 fork-ledger-586abd208221761a6c93bc4568513e9cd4dc287d.zip |
Use correct int return type for stream input operations
This makes it safe to compare results to -1 to indicate EOF,
regardless of whether char is considered signed or unsigned;
and so eliminates compiler warnings on platforms such as ARM.
Fixes bug #2058.
Diffstat (limited to 'src')
-rw-r--r-- | src/amount.cc | 8 | ||||
-rw-r--r-- | src/annotate.cc | 34 | ||||
-rw-r--r-- | src/commodity.cc | 29 | ||||
-rw-r--r-- | src/query.cc | 32 | ||||
-rw-r--r-- | src/query.h | 3 | ||||
-rw-r--r-- | src/times.cc | 15 | ||||
-rw-r--r-- | src/token.cc | 105 | ||||
-rw-r--r-- | src/token.h | 2 | ||||
-rw-r--r-- | src/utils.h | 24 |
9 files changed, 107 insertions, 145 deletions
diff --git a/src/amount.cc b/src/amount.cc index 4eacdd09..0527c979 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -970,13 +970,13 @@ namespace { void parse_quantity(std::istream& in, string& value) { char buf[256]; - char c = peek_next_nonws(in); + int c = peek_next_nonws(in); int max = 255; char *p = buf; if (c == '-') { *p++ = c; max--; - in.get(c); + in.get(); } READ_INTO(in, p, max, c, std::isdigit(c) || c == '.' || c == ','); @@ -1005,10 +1005,10 @@ bool amount_t::parse(std::istream& in, const parse_flags_t& flags) commodity_t::flags_t comm_flags = COMMODITY_STYLE_DEFAULTS; - char c = peek_next_nonws(in); + int c = peek_next_nonws(in); if (c == '-') { negative = true; - in.get(c); + in.get(); c = peek_next_nonws(in); } diff --git a/src/annotate.cc b/src/annotate.cc index 27261f57..e0fb0d08 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -86,33 +86,33 @@ void annotation_t::parse(std::istream& in) return; char buf[256]; - char c = peek_next_nonws(in); + int c = peek_next_nonws(in); if (c == '{') { if (price) throw_(amount_error, _("Commodity specifies more than one price")); - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '{') { - in.get(c); + in.get(); add_flags(ANNOTATION_PRICE_NOT_PER_UNIT); } c = peek_next_nonws(in); if (c == '=') { - in.get(c); + in.get(); add_flags(ANNOTATION_PRICE_FIXATED); } READ_INTO(in, buf, 255, c, c != '}'); if (c == '}') { - in.get(c); + in.get(); if (has_flags(ANNOTATION_PRICE_NOT_PER_UNIT)) { - c = static_cast<char>(in.peek()); + c = in.peek(); if (c != '}') throw_(amount_error, _("Commodity lot price lacks double closing brace")); else - in.get(c); + in.get(); } } else { throw_(amount_error, _("Commodity lot price lacks closing brace")); @@ -128,18 +128,18 @@ void annotation_t::parse(std::istream& in) if (date) throw_(amount_error, _("Commodity specifies more than one date")); - in.get(c); + in.get(); READ_INTO(in, buf, 255, c, c != ']'); if (c == ']') - in.get(c); + in.get(); else throw_(amount_error, _("Commodity date lacks closing bracket")); date = parse_date(buf); } else if (c == '(') { - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '@') { in.clear(); in.seekg(pos, std::ios::beg); @@ -150,13 +150,13 @@ void annotation_t::parse(std::istream& in) throw_(amount_error, _("Commodity specifies more than one valuation expresion")); - in.get(c); + in.get(); READ_INTO(in, buf, 255, c, c != ')'); if (c == ')') { - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == ')') - in.get(c); + in.get(); else throw_(amount_error, _("Commodity valuation expression lacks closing parentheses")); @@ -172,7 +172,7 @@ void annotation_t::parse(std::istream& in) READ_INTO(in, buf, 255, c, c != ')'); if (c == ')') - in.get(c); + in.get(); else throw_(amount_error, _("Commodity tag lacks closing parenthesis")); diff --git a/src/commodity.cc b/src/commodity.cc index ebe388c8..29c04e59 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -297,12 +297,12 @@ void commodity_t::parse_symbol(std::istream& in, string& symbol) std::istream::pos_type pos = in.tellg(); char buf[256]; - char c = peek_next_nonws(in); + int c = peek_next_nonws(in); if (c == '"') { - in.get(c); + in.get(); READ_INTO(in, buf, 255, c, c != '"'); if (c == '"') - in.get(c); + in.get(); else throw_(amount_error, _("Quoted commodity symbol lacks closing quote")); } else { @@ -310,46 +310,45 @@ void commodity_t::parse_symbol(std::istream& in, string& symbol) while (_p - buf < 255 && in.good() && ! in.eof() && c != '\n') { std::size_t bytes = 0; std::ptrdiff_t size = _p - buf; - unsigned char d = static_cast<unsigned char>(c); // Check for the start of a UTF-8 multi-byte encoded string - if (d >= 192 && d <= 223 && size < 254) + if (c >= 192 && c <= 223 && size < 254) bytes = 2; - else if (d >= 224 && d <= 239 && size < 253) + else if (c >= 224 && c <= 239 && size < 253) bytes = 3; - else if (d >= 240 && d <= 247 && size < 252) + else if (c >= 240 && c <= 247 && size < 252) bytes = 4; - else if (d >= 248 && d <= 251 && size < 251) + else if (c >= 248 && c <= 251 && size < 251) bytes = 5; - else if (d >= 252 && d <= 253 && size < 250) + else if (c >= 252 && c <= 253 && size < 250) bytes = 6; - else if (d >= 254) // UTF-8 encoding error + else if (c >= 254) // UTF-8 encoding error break; if (bytes > 0) { // we're looking at a UTF-8 encoding for (std::size_t i = 0; i < bytes; i++) { - in.get(c); + c = in.get(); if (in.bad() || in.eof()) throw_(amount_error, _("Invalid UTF-8 encoding for commodity name")); *_p++ = c; } } - else if (invalid_chars[static_cast<unsigned char>(c)]) { + else if (invalid_chars[c]) { break; } else { - in.get(c); + c = in.get(); if (in.eof()) break; if (c == '\\') { - in.get(c); + c = in.get(); if (in.eof()) throw_(amount_error, _("Backslash at end of commodity name")); } *_p++ = c; } - c = static_cast<char>(in.peek()); + c = in.peek(); } *_p = '\0'; diff --git a/src/query.cc b/src/query.cc index 883bea40..0eb7dd85 100644 --- a/src/query.cc +++ b/src/query.cc @@ -220,37 +220,9 @@ test_ident: return token_t(token_t::UNKNOWN); } -void query_t::lexer_t::token_t::unexpected() +void query_t::lexer_t::token_t::expected(char wanted) { - kind_t prev_kind = kind; - - kind = UNKNOWN; - - switch (prev_kind) { - case END_REACHED: - throw_(parse_error, _("Unexpected end of expression")); - case TERM: - throw_(parse_error, _f("Unexpected string '%1%'") % *value); - default: - throw_(parse_error, _f("Unexpected token '%1%'") % symbol()); - } -} - -void query_t::lexer_t::token_t::expected(char wanted, char c) -{ - kind = UNKNOWN; - - if (c == '\0' || c == -1) { - if (wanted == '\0' || wanted == -1) - throw_(parse_error, _("Unexpected end")); - else - throw_(parse_error, _f("Missing '%1%'") % wanted); - } else { - if (wanted == '\0' || wanted == -1) - throw_(parse_error, _f("Invalid char '%1%'") % c); - else - throw_(parse_error, _f("Invalid char '%1%' (wanted '%2%')") % c % wanted); - } + throw_(parse_error, _f("Missing '%1%'") % wanted); } expr_t::ptr_op_t diff --git a/src/query.h b/src/query.h index f7d48d32..3297cbd6 100644 --- a/src/query.h +++ b/src/query.h @@ -191,8 +191,7 @@ public: #endif } - void unexpected(); - void expected(char wanted, char c = '\0'); + void expected(char wanted); }; token_t token_cache; diff --git a/src/times.cc b/src/times.cc index bab4e0de..127cdd69 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1621,17 +1621,10 @@ void date_parser_t::lexer_t::token_t::unexpected() void date_parser_t::lexer_t::token_t::expected(char wanted, char c) { - if (c == '\0' || c == -1) { - if (wanted == '\0' || wanted == -1) - throw_(date_error, _("Unexpected end")); - else - throw_(date_error, _f("Missing '%1%'") % wanted); - } else { - if (wanted == '\0' || wanted == -1) - throw_(date_error, _f("Invalid char '%1%'") % c); - else - throw_(date_error, _f("Invalid char '%1%' (wanted '%2%')") % c % wanted); - } + if (wanted == '\0') + throw_(date_error, _f("Invalid char '%1%'") % c); + else + throw_(date_error, _f("Invalid char '%1%' (wanted '%2%')") % c % wanted); } namespace { diff --git a/src/token.cc b/src/token.cc index 76bf5106..63865829 100644 --- a/src/token.cc +++ b/src/token.cc @@ -38,7 +38,7 @@ namespace ledger { int expr_t::token_t::parse_reserved_word(std::istream& in) { - char c = static_cast<char>(in.peek()); + int c = in.peek(); if (c == 'a' || c == 'd' || c == 'e' || c == 'f' || c == 'i' || c == 'o' || c == 'n' || c == 't') { @@ -131,7 +131,8 @@ void expr_t::token_t::parse_ident(std::istream& in) kind = IDENT; length = 0; - char c, buf[256]; + int c; + char buf[256]; READ_INTO_(in, buf, 255, c, length, std::isalnum(c) || c == '_'); value.set_string(buf); @@ -146,9 +147,9 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) if (! in.good()) throw_(parse_error, _("Input stream no longer valid")); - char c = peek_next_nonws(in); + int c = peek_next_nonws(in); - if (in.eof() || c == -1) { + if (in.eof()) { kind = TOK_EOF; return; } @@ -162,10 +163,10 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) switch (c) { case '&': - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '&') { - in.get(c); + in.get(); kind = KW_AND; length = 2; break; @@ -173,10 +174,10 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) kind = KW_AND; break; case '|': - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '|') { - in.get(c); + in.get(); kind = KW_OR; length = 2; break; @@ -185,23 +186,23 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; case '(': - in.get(c); + in.get(); kind = LPAREN; break; case ')': - in.get(c); + in.get(); kind = RPAREN; break; case '[': { - in.get(c); + in.get(); char buf[256]; READ_INTO_(in, buf, 255, c, length, c != ']'); if (c != ']') expected(']', c); - in.get(c); + in.get(); length++; date_interval_t timespan(buf); @@ -222,7 +223,7 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) READ_INTO_(in, buf, 4095, c, length, c != delim); if (c != delim) expected(delim, c); - in.get(c); + in.get(); length++; kind = VALUE; value.set_string(buf); @@ -230,10 +231,10 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) } case '{': { - in.get(c); + in.get(); amount_t temp; temp.parse(in, PARSE_NO_MIGRATE); - in.get(c); + c = in.get(); if (c != '}') expected('}', c); length++; @@ -243,10 +244,10 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) } case '!': - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '=') { - in.get(c); + in.get(); symbol[1] = c; symbol[2] = '\0'; kind = NEQUAL; @@ -254,7 +255,7 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; } else if (c == '~') { - in.get(c); + in.get(); symbol[1] = c; symbol[2] = '\0'; kind = NMATCH; @@ -265,10 +266,10 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; case '-': - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '>') { - in.get(c); + in.get(); symbol[1] = c; symbol[2] = '\0'; kind = ARROW; @@ -278,27 +279,26 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) kind = MINUS; break; case '+': - in.get(c); + in.get(); kind = PLUS; break; case '*': - in.get(c); + in.get(); kind = STAR; break; case '?': - in.get(c); + in.get(); kind = QUERY; break; case ':': - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); kind = COLON; break; case '/': { - in.get(c); + in.get(); if (pflags.has_flags(PARSE_OP_CONTEXT)) { // operator context kind = SLASH; } else { // terminal context @@ -307,7 +307,7 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) READ_INTO_(in, buf, 4095, c, length, c != '/'); if (c != '/') expected('/', c); - in.get(c); + in.get(); length++; kind = VALUE; @@ -317,10 +317,10 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) } case '=': - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); if (c == '~') { - in.get(c); + in.get(); symbol[1] = c; symbol[2] = '\0'; kind = MATCH; @@ -328,7 +328,7 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; } else if (c == '=') { - in.get(c); + in.get(); symbol[1] = c; symbol[2] = '\0'; kind = EQUAL; @@ -339,10 +339,9 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; case '<': - in.get(c); - if (static_cast<char>(in.peek()) == '=') { - in.get(c); - symbol[1] = c; + in.get(); + if (in.peek() == '=') { + symbol[1] = in.get(); symbol[2] = '\0'; kind = LESSEQ; length = 2; @@ -352,10 +351,9 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; case '>': - in.get(c); - if (static_cast<char>(in.peek()) == '=') { - in.get(c); - symbol[1] = c; + in.get(); + if (in.peek() == '=') { + symbol[1] = in.get(); symbol[2] = '\0'; kind = GREATEREQ; length = 2; @@ -365,17 +363,17 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) break; case '.': - in.get(c); + in.get(); kind = DOT; break; case ',': - in.get(c); + in.get(); kind = COMMA; break; case ';': - in.get(c); + in.get(); kind = SEMI; break; @@ -420,7 +418,7 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) if (in.fail() || ! in.good()) throw_(parse_error, _("Failed to reset input stream")); - c = static_cast<char>(in.peek()); + c = in.peek(); if (c != -1) { if (! std::isalpha(c) && c != '_') expected('\0', c); @@ -503,19 +501,20 @@ void expr_t::token_t::unexpected(const char wanted) } } -void expr_t::token_t::expected(const char wanted, char c) +void expr_t::token_t::expected(const char wanted, const int c) { - if (c == '\0' || c == -1) { - if (wanted == '\0' || wanted == -1) + if (c == -1) { + if (wanted == '\0') throw_(parse_error, _("Unexpected end")); else throw_(parse_error, _f("Missing '%1%'") % wanted); } else { - if (wanted == '\0' || wanted == -1) - throw_(parse_error, _f("Invalid char '%1%'") % c); + char ch = c; + if (wanted == '\0') + throw_(parse_error, _f("Invalid char '%1%'") % ch); else throw_(parse_error, - _f("Invalid char '%1%' (wanted '%2%')") % c % wanted); + _f("Invalid char '%1%' (wanted '%2%')") % ch % wanted); } } diff --git a/src/token.h b/src/token.h index 5d9f1fac..db592475 100644 --- a/src/token.h +++ b/src/token.h @@ -126,7 +126,7 @@ struct expr_t::token_t : public noncopyable void next(std::istream& in, const parse_flags_t& flags); void rewind(std::istream& in); void unexpected(const char wanted = '\0'); - void expected(const char wanted, const char c = '\0'); + void expected(const char wanted, const int c); void expected(const kind_t wanted); }; diff --git a/src/utils.h b/src/utils.h index c9146dd7..9af1251a 100644 --- a/src/utils.h +++ b/src/utils.h @@ -540,25 +540,25 @@ inline char * next_element(char * buf, bool variable = false) { return NULL; } -inline char peek_next_nonws(std::istream& in) { - char c = static_cast<char>(in.peek()); +inline int peek_next_nonws(std::istream& in) { + int c = in.peek(); while (in.good() && ! in.eof() && std::isspace(c)) { - in.get(c); - c = static_cast<char>(in.peek()); + in.get(); + c = in.peek(); } return c; } #define READ_INTO(str, targ, size, var, cond) { \ char * _p = targ; \ - var = static_cast<char>(str.peek()); \ + var = str.peek(); \ while (str.good() && ! str.eof() && var != '\n' && \ (cond) && _p - targ < size) { \ - str.get(var); \ + var = str.get(); \ if (str.eof()) \ break; \ if (var == '\\') { \ - str.get(var); \ + var = str.get(); \ if (in.eof()) \ break; \ switch (var) { \ @@ -572,22 +572,22 @@ inline char peek_next_nonws(std::istream& in) { } \ } \ *_p++ = var; \ - var = static_cast<char>(str.peek()); \ + var = str.peek(); \ } \ *_p = '\0'; \ } #define READ_INTO_(str, targ, size, var, idx, cond) { \ char * _p = targ; \ - var = static_cast<char>(str.peek()); \ + var = str.peek(); \ while (str.good() && ! str.eof() && var != '\n' && \ (cond) && _p - targ < size) { \ - str.get(var); \ + var = str.get(); \ if (str.eof()) \ break; \ idx++; \ if (var == '\\') { \ - str.get(var); \ + var = str.get(); \ if (in.eof()) \ break; \ switch (var) { \ @@ -602,7 +602,7 @@ inline char peek_next_nonws(std::istream& in) { idx++; \ } \ *_p++ = var; \ - var = static_cast<char>(str.peek()); \ + var = str.peek(); \ } \ *_p = '\0'; \ } |