OXYGENHUB
◆ main openmsx / src / debugger / SymbolManager.hh
4.5 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef SYMBOL_MANAGER_HH
2
#define SYMBOL_MANAGER_HH
3
4
#include "function_ref.hh"
5
#include "hash_map.hh"
6
#include "zstring_view.hh"
7
8
#include <cassert>
9
#include <cstdint>
10
#include <optional>
11
#include <span>
12
#include <string>
13
#include <string_view>
14
#include <vector>
15
16
namespace openmsx {
17
18
class CommandController;
19
20
struct Symbol
21
{
22
	std::string name;
23
	uint16_t value;
24
	std::optional<uint8_t> slot;
25
	std::optional<uint16_t> segment;
26
27
	auto operator<=>(const Symbol&) const = default;
28
};
29
30
struct SymbolFile
31
{
32
	enum class Type : uint8_t {
33
		FIRST = 0,
34
35
		AUTO_DETECT = FIRST,
36
		ASMSX,
37
		GENERIC, // includes PASMO, SJASM, TNIASM0, TNIASM1
38
		HTC,
39
		LINKMAP,
40
		NOICE,
41
		VASM,
42
		WLALINK_NOGMB,
43
44
		LAST,
45
	};
46
	[[nodiscard]] static zstring_view toString(Type type);
47
	[[nodiscard]] static std::optional<Type> parseType(std::string_view str);
48
	[[nodiscard]] auto& getSymbols() { return symbols; }
49
50
	std::optional<uint8_t> slot;
51
	std::optional<uint16_t> segment;
52
	std::string segmentStr = "-";
53
	std::string filename;
54
	std::vector<Symbol> symbols;
55
	Type type;
56
	bool hasSegmentInfo = false;
57
};
58
59
struct SymbolObserver
60
{
61
	virtual void notifySymbolsChanged() = 0;
62
};
63
64
class SymbolManager
65
{
66
public:
67
	explicit SymbolManager(CommandController& commandController);
68
69
	void setObserver(SymbolObserver* observer_) {
70
		assert(!observer || !observer_);
71
		observer = observer_;
72
	}
73
74
	// Load or reload a file.
75
	// * Throws on failure to read from file. In that case the existing file is left unchanged.
76
	// * Parse errors in the file are ignored.
77
	// * When the file contains no symbols and when 'allowEmpty=false' the
78
	//   existing file is not replaced and this method returns 'false'.
79
	//   Otherwise it return 'true'.
80
	enum class LoadEmpty : uint8_t { ALLOWED, NOT_ALLOWED };
81
	bool reloadFile(zstring_view filename, LoadEmpty loadEmpty, SymbolFile::Type type,
82
	                std::optional<uint8_t> slot, std::optional<uint16_t> segment);
83
84
	void removeFile(std::string_view filename);
85
	void removeAllFiles();
86
87
	[[nodiscard]] const auto& getFiles() const { return files; }
88
	[[nodiscard]] SymbolFile* findFile(std::string_view filename);
89
	[[nodiscard]] std::span<Symbol const * const> lookupValue(uint16_t value);
90
	[[nodiscard]] std::optional<uint16_t> lookupSymbol(std::string_view s) const;
91
	[[nodiscard]] std::optional<uint16_t> parseSymbolOrValue(std::string_view s) const;
92
93
	[[nodiscard]] static std::string getFileFilters();
94
	[[nodiscard]] static SymbolFile::Type getTypeForFilter(std::string_view filter);
95
96
//private:
97
	// These should not be called directly, except by the unittest
98
	[[nodiscard]] static std::optional<unsigned> isHexDigit(char c);
99
	[[nodiscard]] static std::optional<uint16_t> is4DigitHex(std::string_view s);
100
	template <typename T>
101
	[[nodiscard]] static std::optional<T> parseValue(std::string_view str);
102
	[[nodiscard]] static std::optional<Symbol> checkLabel(std::string_view label, uint32_t value);
103
	[[nodiscard]] static std::optional<Symbol> checkLabelAndValue(std::string_view label, std::string_view value);
104
	[[nodiscard]] static std::optional<Symbol> checkLabelSegmentAndValue(std::string_view label, std::string_view value);
105
	[[nodiscard]] static SymbolFile::Type detectType(std::string_view filename, std::string_view buffer);
106
	[[nodiscard]] static SymbolFile loadLines(
107
		std::string_view filename, std::string_view buffer, SymbolFile::Type type,
108
		function_ref<std::optional<Symbol>(std::span<std::string_view>)> lineParser);
109
	[[nodiscard]] static SymbolFile loadGeneric(std::string_view filename, std::string_view buffer);
110
	[[nodiscard]] static SymbolFile loadNoICE(std::string_view filename, std::string_view buffer);
111
	[[nodiscard]] static SymbolFile loadHTC(std::string_view filename, std::string_view buffer);
112
	[[nodiscard]] static SymbolFile loadVASM(std::string_view filename, std::string_view buffer);
113
	[[nodiscard]] static SymbolFile loadNoGmb(std::string_view filename, std::string_view buffer);
114
	[[nodiscard]] static SymbolFile loadASMSX(std::string_view filename, std::string_view buffer);
115
	[[nodiscard]] static SymbolFile loadLinkMap(std::string_view filename, std::string_view buffer);
116
	[[nodiscard]] static SymbolFile loadSymbolFile(
117
		zstring_view filename, SymbolFile::Type type,
118
		std::optional<uint8_t> slot, std::optional<uint16_t> segment);
119
120
private:
121
	void refresh();
122
123
private:
124
	CommandController& commandController;
125
	SymbolObserver* observer = nullptr; // only one for now, could become a vector later
126
	std::vector<SymbolFile> files;
127
	hash_map<uint16_t, std::vector<const Symbol*>> lookupValueCache; // calculated from 'files'
128
};
129
130
131
} // namespace openmsx
132
133
#endif