1 #include "framebuffer-font2.hpp"
2 #include "memorywatch.hpp"
3 #include "memoryspace.hpp"
5 #include "mathexpr-error.hpp"
6 #include "mathexpr.hpp"
14 template<typename T
> T
* pointer_cast(char* ptr
)
16 return reinterpret_cast<T
*>(ptr
);
20 memread_oper::memread_oper()
21 : operinfo("(readmemory)")
25 memread_oper::~memread_oper() {}
27 void memread_oper::evaluate(mathexpr::value target
, std::vector
<std::function
<mathexpr::value()>> promises
)
29 if(promises
.size() != 1)
30 throw mathexpr::error(mathexpr::error::ARGCOUNT
, "Memory read operator takes 1 argument");
31 static const int system_endian
= memory_space::get_system_endian();
36 void* res
= val
._value
;
37 addr
= val
.type
->tounsigned(res
);
41 } catch(std::exception
& e
) {
42 throw mathexpr::error(mathexpr::error::ADDR
, e
.what());
45 throw mathexpr::error(mathexpr::error::SIZE
, "Memory read size out of range");
47 mspace
->read_range(addr
, buf
, bytes
);
48 //Endian swap if needed.
49 if(system_endian
!= endianess
)
50 for(unsigned i
= 0; i
< bytes
/ 2; i
++)
51 std::swap(buf
[i
], buf
[bytes
- i
- 1]);
55 throw mathexpr::error(mathexpr::error::SIZE
, "1 byte floats not supported");
57 target
.type
->parse_s(target
._value
, *(const int8_t*)buf
);
59 target
.type
->parse_u(target
._value
, *(const uint8_t*)buf
);
63 throw mathexpr::error(mathexpr::error::SIZE
, "2 byte floats not supported");
65 target
.type
->parse_s(target
._value
, *pointer_cast
<int16_t>(buf
));
67 target
.type
->parse_u(target
._value
, *pointer_cast
<uint16_t>(buf
));
71 throw mathexpr::error(mathexpr::error::SIZE
, "3 byte floats not supported");
73 target
.type
->parse_s(target
._value
, *pointer_cast
<ss_int24_t
>(buf
));
75 target
.type
->parse_u(target
._value
, *pointer_cast
<ss_uint24_t
>(buf
));
79 target
.type
->parse_f(target
._value
, *pointer_cast
<float>(buf
));
81 target
.type
->parse_s(target
._value
, *pointer_cast
<int32_t>(buf
));
83 target
.type
->parse_u(target
._value
, *pointer_cast
<uint32_t>(buf
));
87 target
.type
->parse_f(target
._value
, *pointer_cast
<double>(buf
));
89 target
.type
->parse_s(target
._value
, *pointer_cast
<int64_t>(buf
));
91 target
.type
->parse_u(target
._value
, *pointer_cast
<uint64_t>(buf
));
94 throw mathexpr::error(mathexpr::error::SIZE
, "Memory address size not supported");
97 target
.type
->scale(target
._value
, scale_div
);
102 bool is_terminal(char ch
)
104 if(ch
== '%') return true;
105 if(ch
== 'b') return true;
106 if(ch
== 'B') return true;
107 if(ch
== 'd') return true;
108 if(ch
== 'i') return true;
109 if(ch
== 'o') return true;
110 if(ch
== 's') return true;
111 if(ch
== 'u') return true;
112 if(ch
== 'x') return true;
113 if(ch
== 'X') return true;
117 std::string
get_placeholder(const std::string
& str
, size_t idx
)
119 std::ostringstream p
;
120 for(size_t i
= idx
; i
< str
.length(); i
++) {
122 if(is_terminal(str
[idx
]))
136 item_printer::~item_printer()
140 void item_printer::trace()
144 std::string
item::get_value()
148 mathexpr::_format fmt
;
149 fmt
.type
= mathexpr::_format::DEFAULT
;
150 mathexpr::value v
= expr
->evaluate();
151 return v
.type
->format(v
._value
, fmt
);
153 std::ostringstream out
;
154 for(size_t i
= 0; i
< format
.length(); i
++) {
158 //Format placeholder.
159 std::string p
= get_placeholder(format
, i
+ 1);
163 if(p
[p
.length() - 1] == '%') {
167 mathexpr::_format fmt
;
168 fmt
.showsign
= false;
169 fmt
.fillzeros
= false;
172 fmt
.uppercasehex
= false;
173 auto r
= regex("([+0]*)([1-9][0-9]*)?(\\.(0|[1-9][0-9]*))?([bBdiosuxX])", p
);
175 throw mathexpr::error(mathexpr::error::FORMAT
, "Bad format placeholder");
178 std::string flags
= r
[1];
180 for(i
= 0; i
< flags
.length(); i
++) {
184 fmt
.fillzeros
= true;
186 //The remaining part is width.precision.
189 fmt
.width
= parse_value
<int>(r
[2]);
193 fmt
.precision
= parse_value
<int>(r
[4]);
196 case 'b': fmt
.type
= mathexpr::_format::BINARY
; break;
197 case 'B': fmt
.type
= mathexpr::_format::BOOLEAN
; break;
198 case 'd': fmt
.type
= mathexpr::_format::DECIMAL
; break;
199 case 'i': fmt
.type
= mathexpr::_format::DECIMAL
; break;
200 case 'o': fmt
.type
= mathexpr::_format::OCTAL
; break;
201 case 's': fmt
.type
= mathexpr::_format::STRING
; break;
202 case 'u': fmt
.type
= mathexpr::_format::DECIMAL
; break;
203 case 'x': fmt
.type
= mathexpr::_format::HEXADECIMAL
; break;
204 case 'X': fmt
.type
= mathexpr::_format::HEXADECIMAL
; fmt
.uppercasehex
= true; break;
206 mathexpr::value v
= expr
->evaluate();
207 out
<< v
.type
->format(v
._value
, fmt
);
213 void item::show(const std::string
& n
)
218 } catch(std::bad_alloc
& e
) {
220 } catch(mathexpr::error
& e
) {
221 x
= e
.get_short_error();
222 } catch(std::runtime_error
& e
) {
238 for(auto& i
: roots
) {
240 i
.second
.printer
->reset();
241 i
.second
.expr
->reset();
248 i
.second
.expr
->reset();
250 i
.second
.show(i
.first
);
253 std::set
<std::string
> set::names_set()
255 std::set
<std::string
> r
;
261 item
& set::get(const std::string
& name
)
263 auto i
= get_soft(name
);
265 throw std::runtime_error("No such watch '" + name
+ "'");
269 item
* set::get_soft(const std::string
& name
)
271 if(!roots
.count(name
))
273 return &(roots
.find(name
)->second
);
276 item
* set::create(const std::string
& name
, item
& item
)
278 roots
.insert(std::make_pair(name
, item
));
279 return &(roots
.find(name
)->second
);
282 void set::destroy(const std::string
& name
)
284 if(!roots
.count(name
))
290 const std::string
& set::get_longest_name(std::function
<size_t(const std::string
& n
)> rate
)
292 static std::string empty
;
294 const std::string
* best
= &empty
;
295 for(auto& i
: roots
) {
296 size_t r
= rate(i
.first
);
305 size_t set::utflength_rate(const std::string
& n
)
307 return utf8::strlen(n
);
310 void set::foreach(std::function
<void(item
& item
)> cb
)
316 void set::swap(set
& s
) throw()
318 std::swap(roots
, s
.roots
);