From 1ac35ec473742158473c16010b028c5e517a3308 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 10 Dec 2019 22:43:11 -0500 Subject: [PATCH] workaround missing charconv. also: print ! for missing symbols, ? for unused symbols. --- link.cpp | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/link.cpp b/link.cpp index a7fbf01..5eb97f5 100644 --- a/link.cpp +++ b/link.cpp @@ -10,12 +10,14 @@ /* old version of stdlib have this stuff in utility */ #if __has_include() +#define HAVE_CHARCONV #include #endif #include #include #include +#include #include #include @@ -360,29 +362,39 @@ void finalize(void) { relocations.clear(); } +static void print_symbols2(void) { + + for (const auto &e : symbol_table) { + char q = ' '; + if (!e.count) q = '?'; + if (!e.defined) q = '!'; + fprintf(stdout, "%c %-20s=$%06x\n", q, e.name.c_str(), e.value); + } +} + void print_symbols(void) { if (symbol_table.empty()) return; /* alpha */ + fputs("\nSymbol table, alphabetical order:\n", stdout); std::sort(symbol_table.begin(), symbol_table.end(), [](const symbol &a, const symbol &b){ return a.name < b.name; }); - for (const auto &lab : symbol_table) { - fprintf(stdout, "%-20s: $%06x\n", lab.name.c_str(), lab.value); - } - fputs("\n", stdout); + print_symbols2(); + + fputs("\nSymbol table, numerical order:\n", stdout); + /* numeric */ std::sort(symbol_table.begin(), symbol_table.end(), [](const symbol &a, const symbol &b){ return a.value < b.value; }); - for (const auto &lab : symbol_table) { - fprintf(stdout, "%-20s: $%06x\n", lab.name.c_str(), lab.value); - } + print_symbols2(); + } @@ -393,6 +405,26 @@ void usage(int ex) { exit(ex); } +/* older std libraries lack charconv and std::from_chars */ +bool parse_number(const char *begin, const char *end, uint32_t &value, int base = 10) { + +#if defined(HAVE_CHARCONV) + auto r = std::from_chars(begin, end, value, base); + if (r.ec != std::errc() || r.ptr != end) return false; +#else + auto xerrno = errno; + errno = 0; + char *ptr = nullptr; + value = stroul(begin, &ptr, base); + std::swap(errno, xerrno); + if (xerrno || ptr != end) { + return false; + } +#endif + + return true; +} + static void add_define(std::string str) { /* -D key[=value] value = 0x, $, % or base 10 */ @@ -422,9 +454,7 @@ static void add_define(std::string str) { } break; } - auto end = str.data() + str.length(); - auto r = std::from_chars(str.data() + pos, end, value, base); - if (r.ec != std::errc() || r.ptr != end) + if (!parse_number(str.data() + pos, str.data() + str.length(), value, base)) usage(EX_USAGE); str.resize(ix-1);