#ifndef _library__memorywatch__hpp__included__ #define _library__memorywatch__hpp__included__ #include "mathexpr.hpp" #include #include #include #include class memory_space; namespace memorywatch { /** * Read memory operator. */ struct memread_oper : public mathexpr::operinfo { /** * Ctor */ memread_oper(); /** * Dtor */ ~memread_oper(); /** * Evaluate the operator. * * Note: The first promise is for the address. */ void evaluate(mathexpr::value target, std::vector> promises); //Fields. unsigned bytes; //Number of bytes to read. bool signed_flag; //Is signed? bool float_flag; //Is float? int endianess; //Endianess (-1 => little, 0 => host, 1 => Big). uint64_t scale_div; //Scale divisor. uint64_t addr_base; //Address base. uint64_t addr_size; //Address size (0 => All). memory_space* mspace; //Memory space to read. }; /** * Memory watch item printer. */ struct item_printer : public GC::item { /** * Dtor. */ virtual ~item_printer(); /** * Show the watched value. */ virtual void show(const std::string& iname, const std::string& val) = 0; /** * Reset the printer. */ virtual void reset() = 0; protected: void trace(); }; /** * Memory watch item. */ struct item { /** * Ctor. * * Parameter t: The type of the result. */ item(mathexpr::typeinfo& t) : expr(GC::obj_tag(), &t) { } /** * Get the value as string. */ std::string get_value(); /** * Print the value to specified printer. * * Parameter iname: The name of the watch. */ void show(const std::string& iname); //Fields. GC::pointer printer; //Printer to use. GC::pointer expr; //Expression to watch. std::string format; //Formatting to use. }; /** * A set of memory watches. */ struct set { /** * Dtor. */ ~set(); /** * Call reset on all items and their printers in the set. */ void reset(); /** * Call reset and then show on all items in the set. */ void refresh(); /** * Get the longest name (by UTF-8 length) in the set. * * Returns: The longest nontrivial name, or "" if none. */ const std::string& get_longest_name() { return get_longest_name(set::utflength_rate); } /** * Get the longest name (by arbitrary function) in the set. * * Parameter rate: Get length for name function. * Returns: The longest nontrivial name, or "" if none. */ const std::string& get_longest_name(std::function rate); /** * Get the set of memory watch names. */ std::set names_set(); /** * Get specified memory watch item. * * Parameter name: The name of the item. * Returns: The item. * Throws std::runtime_error: No such item in set. */ item& get(const std::string& name); /** * Get specified memory watch item (without throwing). * * Parameter name: The name of the item. * Returns: The item, or NULL if no such item exists. */ item* get_soft(const std::string& name); /** * Create a new memory watch item. * * Parameter name: The name of the new item. * Parameter item: The new item. All fields are shallow-copied. */ item* create(const std::string& name, item& item); /** * Destroy a memory watch item. * * Parameter name: The name of the item to destroy. */ void destroy(const std::string& name); /** * Call routine for all roots. */ void foreach(std::function cb); /** * Swap set with another. */ void swap(set& s) throw(); private: static size_t utflength_rate(const std::string& s); std::map roots; }; } #endif