1// $Header$ 2// 3// Copyright (C) 2000 - 2004, by 4// 5// Carlo Wood, Run on IRC <carlo@alinoe.com> 6// RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 7// Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 8// 9// This file may be distributed under the terms of the Q Public License 10// version 1.0 as appearing in the file LICENSE.QPL included in the 11// packaging of this file. 12// 13 14#ifndef LIBCWD_CLASS_LOCATION_INL 15#define LIBCWD_CLASS_LOCATION_INL 16 17#ifndef LIBCWD_CONFIG_H 18#include <libcwd/config.h> 19#endif 20 21#if CWDEBUG_LOCATION 22 23#ifndef LIBCWD_LIBRARIES_DEBUG_H 24#include <libcwd/libraries_debug.h> 25#endif 26#ifndef LIBCWD_PRIVATE_ASSERT_H 27#include <libcwd/private_assert.h> 28#endif 29#ifndef LIBCWD_PRIVATE_THREADING_H 30#include <libcwd/private_threading.h> 31#endif 32#ifndef LIBCWD_CLASS_LOCATION_H 33#include <libcwd/class_location.h> 34#endif 35#ifndef LIBCW_STRING 36#define LIBCW_STRING 37#include <string> 38#endif 39 40namespace libcwd { 41 42/** 43 * \brief Construct a location for address \p addr. 44 */ 45inline 46location_ct::location_ct(void const* addr) : M_known(false) 47#if CWDEBUG_ALLOC 48 , M_hide(_private_::new_location) 49#endif 50{ 51 LIBCWD_TSD_DECLARATION; 52 M_pc_location(addr LIBCWD_COMMA_TSD); 53} 54 55#if LIBCWD_THREAD_SAFE 56/* 57 * Construct a location for address addr, 58 * taking a thread-specific-data argument. 59 */ 60inline 61location_ct::location_ct(void const* addr LIBCWD_COMMA_TSD_PARAM) : M_known(false) 62#if CWDEBUG_ALLOC 63 , M_hide(_private_::new_location) 64#endif 65{ 66 M_pc_location(addr LIBCWD_COMMA_TSD); 67} 68#endif 69 70/** 71 * \brief Destructor. 72 */ 73inline 74location_ct::~location_ct() 75{ 76 clear(); 77} 78 79inline 80location_ct::location_ct(void) : M_func(S_uninitialized_location_ct_c), M_object_file(NULL), M_known(false) 81#if CWDEBUG_ALLOC 82 , M_hide(_private_::new_location) 83#endif 84{ 85} 86 87/** 88 * \brief Point this location to a different program counter address. 89 */ 90inline 91void 92location_ct::pc_location(void const* addr) 93{ 94 clear(); 95 LIBCWD_TSD_DECLARATION; 96 M_pc_location(addr LIBCWD_COMMA_TSD); 97} 98 99inline 100bool 101location_ct::is_known(void) const 102{ 103 return M_known; 104} 105 106inline 107std::string 108location_ct::file(void) const 109{ 110#if CWDEBUG_DEBUGM 111 LIBCWD_TSD_DECLARATION; 112 LIBCWD_ASSERT( !__libcwd_tsd.internal ); // Returning a string, using a userspace allocator! 113#endif 114 LIBCWD_ASSERT( M_known ); 115 return M_filename; 116} 117 118inline 119unsigned int 120location_ct::line(void) const 121{ 122 LIBCWD_ASSERT( M_known ); 123 return M_line; 124} 125 126inline 127char const* 128location_ct::mangled_function_name(void) const 129{ 130 return M_func; 131} 132 133inline 134location_format_t 135location_format(location_format_t format) 136{ 137 LIBCWD_TSD_DECLARATION; 138 location_format_t ret = __libcwd_tsd.format; 139 __libcwd_tsd.format = format; 140 return ret; 141} 142 143namespace _private_ { 144 145template<class OSTREAM> 146 void print_location_on(OSTREAM& os, location_ct const& location) 147 { 148 if (location.M_known) 149 { 150 LIBCWD_TSD_DECLARATION; 151 if ((__libcwd_tsd.format & show_objectfile)) 152 os << location.M_object_file->filename() << ':'; 153 if ((__libcwd_tsd.format & show_function)) 154 os << location.M_func << ':'; 155 if ((__libcwd_tsd.format & show_path)) 156 os << location.M_filepath.get() << ':' << location.M_line; 157 else 158 os << location.M_filename << ':' << location.M_line; 159 } 160 else if (location.M_object_file) 161 os << location.M_object_file->filename() << ':' << location.M_func; 162 else 163 os << "<unknown object file> (at " << location.unknown_pc() << ')'; 164 } 165 166} // namespace _private_ 167 168#if !(__GNUC__ == 3 && __GNUC_MINOR__ < 4) // See class_location.h 169/** 170 * \brief Write \a location to ostream \a os. 171 * \ingroup group_locations 172 * 173 * Write the contents of a location_ct object to an ostream in the form <i>source-file</i>:<i>line-number</i>, 174 * or writes <i>objectfile</i>:<i>mangledfuncname</i> when the location is unknown. 175 * If the <i>source-file</i>:<i>line-number</i> is known, then it may be prepended by the object file 176 * and/or the mangled function name anyway if this was requested through \ref location_format. 177 * That function can also be used to cause the <i>source-file</i> to be printed with its full path. 178 */ 179inline 180std::ostream& 181operator<<(std::ostream& os, location_ct const& location) 182{ 183 _private_::print_location_on(os, location); 184 return os; 185} 186#endif 187 188} // namespace libcwd 189 190#endif // CWDEBUG_LOCATION 191#endif // LIBCWD_CLASS_LOCATION_INL 192