/** * @file name_storage.h * Type-safe unique storage of global names (filenames and symbols) * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #ifndef NAME_STORAGE_H #define NAME_STORAGE_H #include <string> #include "unique_storage.h" class extra_images; /// store original name and processed name struct stored_name { stored_name(std::string const & n = std::string()) : name(n) {} bool operator<(stored_name const & rhs) const { return name < rhs.name; } std::string name; mutable std::string name_processed; }; /// partial specialization for unique storage of names template <typename I> struct name_storage : unique_storage<I, stored_name> { typedef typename unique_storage<I, stored_name>::id_value id_value; std::string const & name(id_value const & id) const { return unique_storage<I, stored_name>::get(id).name; } }; class debug_name_tag; /// a debug filename typedef name_storage<debug_name_tag>::id_value debug_name_id; /// class storing a set of shared debug name (source filename) struct debug_name_storage : name_storage<debug_name_tag> { /// return the basename for the given ID std::string const & basename(debug_name_id id) const; }; /// store original name and processed name struct stored_filename { stored_filename(std::string const & n = std::string()) : filename(n), extra_images_uid(0) {} bool operator<(stored_filename const & rhs) const { return filename < rhs.filename; } std::string filename; mutable std::string base_filename; mutable std::string real_filename; mutable std::string real_base_filename; mutable int extra_images_uid; }; /// partial specialization for unique storage of filenames template <typename I> struct filename_storage : unique_storage<I, stored_filename> { typedef typename unique_storage<I, stored_filename>::id_value id_value; std::string const & name(id_value const & id) const { return unique_storage<I, stored_filename>::get(id).filename; } }; class image_name_tag; /// an image name typedef filename_storage<image_name_tag>::id_value image_name_id; /// class storing a set of shared image name struct image_name_storage : filename_storage<image_name_tag> { enum image_name_type { /// image name based on the sample filename w/o path int_basename, /// image name based on the sample filename int_filename, /// real image name, can be different for module. int_real_basename, /// same as int_real_basename + the complete path, including an /// optionnal archive_path passed trough profile_spec int_real_filename, }; /** * @param id the image name id * @param type the image name type * @param extra extra locations where the image can be found * * If type == int_real_name (resp. int_real_filename) and the image * can't be located the return value is the same as if get_name() * was called with int_name (resp. int_filename). * * multiple call with the image_name_id and different extra parameter * will throw a runtime error, multiple extra_images are possible * with differential profile but the name. FIXME */ std::string const & get_name(image_name_id id, image_name_type type, extra_images const & extra) const; /// return the basename name for the given ID std::string const & basename(image_name_id) const; }; class symbol_name_tag; /// a (demangled) symbol typedef name_storage<symbol_name_tag>::id_value symbol_name_id; /// class storing a set of shared symbol name struct symbol_name_storage : name_storage<symbol_name_tag> { /// return the demangled name for the given ID std::string const & demangle(symbol_name_id id) const; }; /// for images extern image_name_storage image_names; /// for debug filenames i.e. source filename extern debug_name_storage debug_names; /// for symbols extern symbol_name_storage symbol_names; /** * debug name specialisation for comparison. * * We compare by name rather by id since what user will see are * filename and when the criteria "samples count" give identical * result it's better to obtain result sorted by the user visible * property filename rather than by an obscure, invisible from user * point of view, file identifier property */ template<> inline bool debug_name_id::operator<(debug_name_id const & rhs) const { return debug_names.name(*this) < debug_names.name(rhs); } #endif /* !NAME_STORAGE_H */