27 case ASMSX:
return "asMSX";
29 case HTC:
return "htc";
31 case NOICE:
return "NoICE";
32 case VASM:
return "vasm";
41 if (str ==
"asMSX")
return ASMSX;
42 if (str ==
"generic")
return GENERIC;
43 if (str ==
"htc")
return HTC;
44 if (str ==
"linkmap")
return LINKMAP;
45 if (str ==
"NoICE")
return NOICE;
46 if (str ==
"vasm")
return VASM;
52 : commandController(commandController_)
62 if (fname.ends_with(
".noi")) {
65 }
else if (fname.ends_with(
".map")) {
68 }
else if (fname.ends_with(
".sym")) {
71 if (line.starts_with(
"; Symbol table")) {
84 }
else if (fname.ends_with(
".symbol") || fname.ends_with(
".publics") || fname.ends_with(
".sys")) {
97 function_ref<std::optional<Symbol>(std::span<std::string_view>)> lineParser)
103 static constexpr std::string_view whitespace =
" \t\r";
108 view::take(StringOp::split_view<StringOp::EmptyParts::REMOVE>(line, whitespace), 3 + 1)};
109 if (
auto symbol = lineParser(tokens)) {
110 result.
symbols.push_back(std::move(*symbol));
119 if (str.ends_with(
'h') || str.ends_with(
'H')) {
120 str.remove_suffix(1);
121 return StringOp::stringToBase<16, uint16_t>(str);
123 if (str.starts_with(
'$') || str.starts_with(
'#')) {
124 str.remove_prefix(1);
125 return StringOp::stringToBase<16, uint16_t>(str);
127 if (str.starts_with(
'%')) {
128 str.remove_prefix(1);
129 return StringOp::stringToBase<2, uint16_t>(str);
135 return StringOp::stringTo<uint16_t>(str);
140 if (label.ends_with(
':')) label.remove_suffix(1);
141 if (label.empty())
return {};
143 return Symbol{std::string(label), value};
156 auto parseLine = [](std::span<std::string_view> tokens) -> std::optional<Symbol> {
157 if (tokens.size() != 3)
return {};
158 auto label = tokens[0];
159 auto equ = tokens[1];
160 auto value = tokens[2];
162 if (!cmp(equ,
"equ") &&
163 !cmp(equ,
"%equ"))
return {};
171 auto parseLine = [](std::span<std::string_view> tokens) -> std::optional<Symbol> {
172 if (tokens.size() != 3)
return {};
173 auto def = tokens[0];
174 auto label = tokens[1];
175 auto value = tokens[2];
185 auto parseLine = [](std::span<std::string_view> tokens) -> std::optional<Symbol> {
186 if (tokens.size() != 3)
return {};
187 auto label = tokens[0];
188 auto value = tokens[1];
191 auto val = StringOp::stringToBase<16, uint16_t>(value);
204 static constexpr std::string_view whitespace =
" \t\r";
205 bool skipLines =
true;
208 if (line.starts_with(
"Symbols by value:")) {
215 view::take(StringOp::split_view<StringOp::EmptyParts::REMOVE>(line, whitespace), 2 + 1)};
216 if (tokens.size() != 2)
continue;
217 auto value = tokens[0];
218 auto label = tokens[1];
220 if (
auto val = StringOp::stringToBase<16, uint16_t>(value)) {
222 result.
symbols.push_back(std::move(*symbol));
236 static constexpr std::string_view whitespace =
" \t\r";
237 bool symbolPart =
false;
239 if (line.starts_with(
';')) {
240 if (line.starts_with(
"; global and local")) {
242 }
else if (line.starts_with(
"; other")) {
247 if (!symbolPart)
continue;
254 view::take(StringOp::split_view<StringOp::EmptyParts::REMOVE>(line, whitespace), 2 + 1)};
255 if (tokens.size() != 2)
continue;
256 auto value = tokens[0];
257 auto label = tokens[1];
260 value = l.empty() ? f : l;
263 result.
symbols.push_back(std::move(*symbol));
272 if (
'0' <= c && c <=
'9')
return c -
'0';
273 if (
'A' <= c && c <=
'F')
return c -
'A' + 10;
274 if (
'a' <= c && c <=
'f')
return c -
'a' + 10;
279 if (s.size() != 4)
return {};
281 for (
int i = 0; i < 4; ++i) {
283 if (!digit)
return {};
284 value = (value << 4) | *digit;
286 return narrow<uint16_t>(value);
297 static constexpr std::string_view whitespace =
" \t\r";
298 bool symbolPart =
false;
301 if (line.find(
"Symbol Table") != std::string_view::npos) {
318 auto tokens = StringOp::split_view<StringOp::EmptyParts::REMOVE>(line, whitespace);
319 auto it = tokens.begin();
320 auto et = tokens.end();
327 result.
symbols.emplace_back(std::string(label), *val);
335 result.
symbols.emplace_back(std::string(label), *val);
345 auto buf = file.
mmap();
346 std::string_view buffer(std::bit_cast<const char*>(buf.data()), buf.size());
349 if (type == AUTO_DETECT) {
352 assert(type != AUTO_DETECT);
360 return loadHTC(filename, buffer);
371void SymbolManager::refresh()
374 lookupValueCache.clear();
379 interp.unsetVariable(arrayName.getString().c_str());
380 for (
const auto& file : files) {
381 for (
const auto& sym : file.symbols) {
396 files.push_back(std::move(file));
398 *it = std::move(file);
407 if (it == files.end())
return;
422 for (
const auto& file : files) {
424 it != file.symbols.end()) {
429 for (
const auto& file : files) {
431 return StringOp::casecmp{}(str, sym.name); });
432 it != file.symbols.end()) {
437 return parseValue(str);
440std::span<Symbol const * const> SymbolManager::lookupValue(uint16_t value)
442 if (lookupValueCache.empty()) {
443 for (
const auto& file : files) {
444 for (
const auto& sym : file.symbols) {
445 auto [it, inserted] = lookupValueCache.try_emplace(sym.value, std::vector<const Symbol*>{});
446 it->second.push_back(&sym);
450 if (
auto* sym =
lookup(lookupValueCache, value)) {
456std::string SymbolManager::getFileFilters()
458 return "Auto-detect file type (*){.*},"
459 "asMSX 0.x symbol files (*.sym){.sym},"
460 "HiTech C link map files (*.map){.map},"
461 "HiTech C symbol files (*.sym){.sym},"
462 "NoICE command files (*.noi){.noi},"
463 "pasmo symbol files (*.symbol *.publics *.sys){.symbol,.publics,.sys},"
464 "tniASM 0.x symbol files (*.sym){.sym},"
465 "tniASM 1.x symbol files (*.sym){.sym},"
466 "vasm symbol files (*.sym){.sym}";
472 if (filter.starts_with(
"Auto")) {
474 }
else if (filter.starts_with(
"asMSX")) {
476 }
else if (filter.starts_with(
"HiTechC link")) {
478 }
else if (filter.starts_with(
"HiTechC symbol")) {
480 }
else if (filter.starts_with(
"NoICE")) {
482 }
else if (filter.starts_with(
"vasm")) {
virtual Interpreter & getInterpreter()=0
std::span< const uint8_t > mmap()
Map file in memory.
static std::optional< unsigned > isHexDigit(char c)
bool reloadFile(const std::string &filename, LoadEmpty loadEmpty, SymbolFile::Type type)
static SymbolFile loadLines(std::string_view filename, std::string_view buffer, SymbolFile::Type type, function_ref< std::optional< Symbol >(std::span< std::string_view >)> lineParser)
static SymbolFile::Type detectType(std::string_view filename, std::string_view buffer)
static SymbolFile loadNoICE(std::string_view filename, std::string_view buffer)
static SymbolFile loadHTC(std::string_view filename, std::string_view buffer)
static SymbolFile loadSymbolFile(const std::string &filename, SymbolFile::Type type)
static SymbolFile loadGeneric(std::string_view filename, std::string_view buffer)
static SymbolFile loadVASM(std::string_view filename, std::string_view buffer)
static std::optional< uint16_t > is4DigitHex(std::string_view s)
void removeFile(std::string_view filename)
static std::optional< Symbol > checkLabel(std::string_view label, uint16_t value)
static SymbolFile loadASMSX(std::string_view filename, std::string_view buffer)
static std::optional< uint16_t > parseValue(std::string_view str)
std::optional< uint16_t > parseSymbolOrValue(std::string_view s) const
static SymbolFile loadLinkMap(std::string_view filename, std::string_view buffer)
SymbolManager(CommandController &commandController)
static std::optional< Symbol > checkLabelAndValue(std::string_view label, std::string_view value)
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
const Value * lookup(const hash_map< Key, Value, Hasher, Equal > &map, const Key2 &key)
std::pair< string_view, string_view > splitOnFirst(string_view str, string_view chars)
std::string toLower(std::string_view str)
bool containsCaseInsensitive(std::string_view haystack, std::string_view needle)
auto split_view(std::string_view str, Separators separators)
This file implemented 3 utility functions:
auto find_if(InputRange &&range, UnaryPredicate pred)
auto find(InputRange &&range, const T &value)
constexpr auto take(ForwardRange &&range, size_t n)
constexpr from_range_t from_range
static std::optional< Type > parseType(std::string_view str)
static zstring_view toString(Type type)
std::vector< Symbol > symbols
virtual void notifySymbolsChanged()=0