|  | /** | 
|  | * @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 */ |