1 #include "framebuffer-font2.hpp"
2 #include "memorywatch.hpp"
3 #include "memoryspace.hpp"
5 #include "mathexpr-error.hpp"
6 #include "mathexpr.hpp"
15 template<typename T
> T
* pointer_cast(char* ptr
)
17 return reinterpret_cast<T
*>(ptr
);
21 memread_oper::memread_oper()
22 : operinfo("(readmemory)")
26 memread_oper::~memread_oper() {}
28 void memread_oper::evaluate(mathexpr::value target
, std::vector
<std::function
<mathexpr::value()>> promises
)
30 if(promises
.size() != 1)
31 throw mathexpr::error(mathexpr::error::ARGCOUNT
, "Memory read operator takes 1 argument");
32 static const int system_endian
= memory_space::get_system_endian();
37 void* res
= val
._value
;
38 addr
= val
.type
->tounsigned(res
);
42 } catch(std::exception
& e
) {
43 throw mathexpr::error(mathexpr::error::ADDR
, e
.what());
46 throw mathexpr::error(mathexpr::error::SIZE
, "Memory read size out of range");
48 mspace
->read_range(addr
, buf
, bytes
);
49 //Endian swap if needed.
50 if(endianess
&& system_endian
!= endianess
)
51 for(unsigned i
= 0; i
< bytes
/ 2; i
++)
52 std::swap(buf
[i
], buf
[bytes
- i
- 1]);
56 throw mathexpr::error(mathexpr::error::SIZE
, "1 byte floats not supported");
58 target
.type
->parse_s(target
._value
, *(const int8_t*)buf
);
60 target
.type
->parse_u(target
._value
, *(const uint8_t*)buf
);
64 throw mathexpr::error(mathexpr::error::SIZE
, "2 byte floats not supported");
66 target
.type
->parse_s(target
._value
, *pointer_cast
<int16_t>(buf
));
68 target
.type
->parse_u(target
._value
, *pointer_cast
<uint16_t>(buf
));
72 throw mathexpr::error(mathexpr::error::SIZE
, "3 byte floats not supported");
74 target
.type
->parse_s(target
._value
, *pointer_cast
<ss_int24_t
>(buf
));
76 target
.type
->parse_u(target
._value
, *pointer_cast
<ss_uint24_t
>(buf
));
80 target
.type
->parse_f(target
._value
, *pointer_cast
<float>(buf
));
82 target
.type
->parse_s(target
._value
, *pointer_cast
<int32_t>(buf
));
84 target
.type
->parse_u(target
._value
, *pointer_cast
<uint32_t>(buf
));
88 target
.type
->parse_f(target
._value
, *pointer_cast
<double>(buf
));
90 target
.type
->parse_s(target
._value
, *pointer_cast
<int64_t>(buf
));
92 target
.type
->parse_u(target
._value
, *pointer_cast
<uint64_t>(buf
));
95 throw mathexpr::error(mathexpr::error::SIZE
, "Memory address size not supported");
98 target
.type
->scale(target
._value
, scale_div
);
103 bool is_terminal(char ch
)
105 if(ch
== '%') return true;
106 if(ch
== 'b') return true;
107 if(ch
== 'B') return true;
108 if(ch
== 'd') return true;
109 if(ch
== 'i') return true;
110 if(ch
== 'o') return true;
111 if(ch
== 's') return true;
112 if(ch
== 'u') return true;
113 if(ch
== 'x') return true;
114 if(ch
== 'X') return true;
118 std::string
get_placeholder(const std::string
& str
, size_t idx
)
120 std::ostringstream p
;
121 for(size_t i
= idx
; i
< str
.length(); i
++) {
123 if(is_terminal(str
[idx
]))
137 item_printer::~item_printer()
141 void item_printer::trace()
145 std::string
item::get_value()
149 mathexpr::_format fmt
;
150 fmt
.type
= mathexpr::_format::DEFAULT
;
151 mathexpr::value v
= expr
->evaluate();
152 return v
.type
->format(v
._value
, fmt
);
154 std::ostringstream out
;
155 for(size_t i
= 0; i
< format
.length(); i
++) {
159 //Format placeholder.
160 std::string p
= get_placeholder(format
, i
+ 1);
164 if(p
[p
.length() - 1] == '%') {
168 mathexpr::_format fmt
;
169 fmt
.showsign
= false;
170 fmt
.fillzeros
= false;
173 fmt
.uppercasehex
= false;
174 auto r
= regex("([+0]*)([1-9][0-9]*)?(\\.(0|[1-9][0-9]*))?([bBdiosuxX])", p
);
176 throw mathexpr::error(mathexpr::error::FORMAT
, "Bad format placeholder");
179 std::string flags
= r
[1];
181 for(i
= 0; i
< flags
.length(); i
++) {
185 fmt
.fillzeros
= true;
187 //The remaining part is width.precision.
190 fmt
.width
= parse_value
<int>(r
[2]);
194 fmt
.precision
= parse_value
<int>(r
[4]);
197 case 'b': fmt
.type
= mathexpr::_format::BINARY
; break;
198 case 'B': fmt
.type
= mathexpr::_format::BOOLEAN
; break;
199 case 'd': fmt
.type
= mathexpr::_format::DECIMAL
; break;
200 case 'i': fmt
.type
= mathexpr::_format::DECIMAL
; break;
201 case 'o': fmt
.type
= mathexpr::_format::OCTAL
; break;
202 case 's': fmt
.type
= mathexpr::_format::STRING
; break;
203 case 'u': fmt
.type
= mathexpr::_format::DECIMAL
; break;
204 case 'x': fmt
.type
= mathexpr::_format::HEXADECIMAL
; break;
205 case 'X': fmt
.type
= mathexpr::_format::HEXADECIMAL
; fmt
.uppercasehex
= true; break;
207 mathexpr::value v
= expr
->evaluate();
208 out
<< v
.type
->format(v
._value
, fmt
);
214 void item::show(const std::string
& n
)
219 } catch(std::bad_alloc
& e
) {
221 } catch(mathexpr::error
& e
) {
222 x
= e
.get_short_error();
223 } catch(std::runtime_error
& e
) {
239 for(auto& i
: roots
) {
241 i
.second
.printer
->reset();
242 i
.second
.expr
->reset();
249 i
.second
.expr
->reset();
251 i
.second
.show(i
.first
);
254 std::set
<std::string
> set::names_set()
256 std::set
<std::string
> r
;
262 item
& set::get(const std::string
& name
)
264 auto i
= get_soft(name
);
266 throw std::runtime_error("No such watch '" + name
+ "'");
270 item
* set::get_soft(const std::string
& name
)
272 if(!roots
.count(name
))
274 return &(roots
.find(name
)->second
);
277 item
* set::create(const std::string
& name
, item
& item
)
279 roots
.insert(std::make_pair(name
, item
));
280 return &(roots
.find(name
)->second
);
283 void set::destroy(const std::string
& name
)
285 if(!roots
.count(name
))
291 const std::string
& set::get_longest_name(std::function
<size_t(const std::string
& n
)> rate
)
293 static std::string empty
;
295 const std::string
* best
= &empty
;
296 for(auto& i
: roots
) {
297 size_t r
= rate(i
.first
);
306 size_t set::utflength_rate(const std::string
& n
)
308 return utf8::strlen(n
);
311 void set::foreach(std::function
<void(item
& item
)> cb
)
317 void set::swap(set
& s
) throw()
319 std::swap(roots
, s
.roots
);