mirror of https://github.com/vitalif/grive2
added backtrace
parent
9631031931
commit
66e7783a9c
|
@ -0,0 +1,13 @@
|
|||
find_library( DL_LIBRARY NAMES dl PATH /usr/lib /usr/lib64 )
|
||||
find_library( BFD_LIBRARY NAMES bfd PATH /usr/lib /usr/lib64 )
|
||||
|
||||
if ( DL_LIBRARY AND BFD_LIBRARY )
|
||||
set( BFD_FOUND TRUE )
|
||||
endif (DL_LIBRARY AND BFD_LIBRARY)
|
||||
|
||||
if ( BFD_FOUND )
|
||||
|
||||
message( STATUS "Found libbfd: ${BFD_LIBRARY}")
|
||||
|
||||
|
||||
endif ( BFD_FOUND )
|
|
@ -8,11 +8,20 @@ find_package(CURL REQUIRED)
|
|||
find_package(EXPAT REQUIRED)
|
||||
find_package(CppUnit)
|
||||
find_package(Boost REQUIRED)
|
||||
find_package(BFD)
|
||||
|
||||
IF ( CPPUNIT_FOUND )
|
||||
set( OPT_INCS ${CPPUNIT_INCLUDE_DIR} )
|
||||
ENDIF ( CPPUNIT_FOUND )
|
||||
|
||||
if ( BFD_FOUND )
|
||||
set( OPT_LIBS ${DL_LIBRARY} ${BFD_LIBRARY} )
|
||||
file( GLOB OPT_SRC
|
||||
src/bfd/*.cc
|
||||
)
|
||||
|
||||
endif ( BFD_FOUND )
|
||||
|
||||
include_directories(
|
||||
${libgrive_SOURCE_DIR}/src
|
||||
${libgrive_SOURCE_DIR}/test
|
||||
|
@ -45,12 +54,13 @@ file (GLOB LIBGRIVE_SRC
|
|||
|
||||
add_definitions( -DVERSION="${GRIVE_VERSION}" -DTEST_DATA="${libgrive_SOURCE_DIR}/test/data/" )
|
||||
|
||||
add_library( grive SHARED ${LIBGRIVE_SRC} )
|
||||
add_library( grive SHARED ${LIBGRIVE_SRC} ${OPT_SRC} )
|
||||
|
||||
target_link_libraries( grive
|
||||
${CURL_LIBRARIES}
|
||||
${JSONC_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${OPT_LIBS}
|
||||
expat
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2006 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace gr
|
||||
{
|
||||
typedef void* addr_t ;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2012 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "Backtrace.hh"
|
||||
|
||||
#include "SymbolInfo.hh"
|
||||
#include "util/CArray.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
namespace gr {
|
||||
|
||||
Backtrace::Backtrace( std::size_t skip ) :
|
||||
m_count( SymbolInfo::Instance()->Backtrace(m_stack, Count(m_stack) )),
|
||||
m_skip( std::min( skip, m_count ) )
|
||||
{
|
||||
}
|
||||
|
||||
Backtrace::Backtrace( const Backtrace& bt ) :
|
||||
m_count( bt.m_count ),
|
||||
m_skip( bt.m_skip )
|
||||
{
|
||||
std::memcpy( m_stack, bt.m_stack, m_count * sizeof(m_stack[0]) ) ;
|
||||
}
|
||||
|
||||
/*! \brief operator<< for printing backtraces
|
||||
\internal
|
||||
|
||||
This function will call SymbolInfo::PrintTrace() to print out a backtrace
|
||||
to the stream. It will use the SymbolInfo::Instance() singleton to get
|
||||
the symbol information.
|
||||
\param os The output stream.
|
||||
\param b The backtrace information.
|
||||
\sa SymbolInfo::Backtrace(), SymbolInfo::Instance()
|
||||
*/
|
||||
std::ostream& operator<<( std::ostream& os, const gr::Backtrace& b )
|
||||
{
|
||||
// the 1st function in the stack is SymbolInfo::Backtrace()
|
||||
// the 2nd one is the Backtrace() constructor
|
||||
// both are not interesting to user
|
||||
for ( std::size_t i = b.m_skip ; i < b.m_count ; i++ )
|
||||
SymbolInfo::Instance()->PrintTrace( b.m_stack[i], os, i - b.m_skip ) ;
|
||||
|
||||
return os ;
|
||||
}
|
||||
|
||||
std::string Backtrace::ToString( ) const
|
||||
{
|
||||
std::ostringstream oss ;
|
||||
oss << *this ;
|
||||
return oss.str( ) ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2012 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Addr.hh"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/// A shortcut to print out backtrace information
|
||||
/** \internal
|
||||
The sole reason for this class to exists is to provide the
|
||||
operator<< overload to allow:
|
||||
|
||||
\code
|
||||
std::cout << Backtrace() << std::endl ;
|
||||
\endcode
|
||||
|
||||
\sa SymbolInfo
|
||||
*/
|
||||
class Backtrace
|
||||
{
|
||||
public :
|
||||
explicit Backtrace( std::size_t skip = 2 ) ;
|
||||
Backtrace( const Backtrace& bt ) ;
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& os,
|
||||
const gr::Backtrace& bt ) ;
|
||||
|
||||
std::string ToString( ) const ;
|
||||
|
||||
private :
|
||||
addr_t m_stack[100] ;
|
||||
std::size_t m_count, m_skip ;
|
||||
} ;
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2006 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "Debug.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace gr {
|
||||
|
||||
std::string Demangle( const char *name )
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
assert( name != 0 ) ;
|
||||
|
||||
char *cname = abi::__cxa_demangle( name, 0, 0, 0 ) ;
|
||||
std::string result( name ) ;
|
||||
if ( cname != 0 )
|
||||
{
|
||||
result = cname ;
|
||||
std::free( cname ) ;
|
||||
}
|
||||
return result ;
|
||||
#else
|
||||
return std::string( ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::ostream& PrintHex( std::ostream& os, const void *buf, std::size_t size )
|
||||
{
|
||||
const unsigned char *raw = static_cast<const unsigned char*>( buf ) ;
|
||||
|
||||
for ( std::size_t i = 0 ; i < size ; i++ )
|
||||
{
|
||||
if ( i % 8 == 0 && i > 0 )
|
||||
os << std::endl ;
|
||||
|
||||
if ( i % 8 == 0 )
|
||||
os << std::hex << std::setw(8) << std::setfill('0') << i << " " ;
|
||||
|
||||
os << "0x" << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< (int)raw[i] << ", " ;
|
||||
}
|
||||
os << std::endl ;
|
||||
return os ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2006 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
namespace gr {
|
||||
|
||||
std::string Demangle( const char *name ) ;
|
||||
|
||||
std::ostream& PrintHex( std::ostream& os, const void *buf, std::size_t size ) ;
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2006 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "SymbolInfo.hh"
|
||||
#include "Debug.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <bfd.h>
|
||||
#include <execinfo.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
namespace gr {
|
||||
|
||||
struct SymbolInfo::Impl
|
||||
{
|
||||
bfd *m_bfd ;
|
||||
asymbol **m_symbols ;
|
||||
long m_symbol_count ;
|
||||
} ;
|
||||
|
||||
SymbolInfo::SymbolInfo( )
|
||||
: m_impl( new Impl )
|
||||
{
|
||||
m_impl->m_bfd = 0 ;
|
||||
m_impl->m_symbols = 0 ;
|
||||
m_impl->m_symbol_count = 0 ;
|
||||
|
||||
bfd_init( ) ;
|
||||
|
||||
// opening itself
|
||||
bfd *b = bfd_openr( "/proc/self/exe", 0 ) ;
|
||||
if ( b == NULL )
|
||||
{
|
||||
std::cerr << "cannot open executable: "
|
||||
<< bfd_errmsg( bfd_get_error() ) << std::endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
if ( bfd_check_format( b, bfd_archive ) )
|
||||
{
|
||||
bfd_close( b ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
char **matching ;
|
||||
if ( !bfd_check_format_matches( b, bfd_object, &matching ) )
|
||||
{
|
||||
std::cerr << "cannot read symbols from " << bfd_get_filename( b )
|
||||
<< ": " << bfd_errmsg( bfd_get_error() ) << std::endl ;
|
||||
|
||||
if ( bfd_get_error( ) == bfd_error_file_ambiguously_recognized )
|
||||
{
|
||||
std::cerr << bfd_get_filename( b ) << ": Matching formats: " ;
|
||||
for ( char **p = matching ; *p != 0 ; p++ )
|
||||
std::cerr << " " << *p ;
|
||||
|
||||
std::cerr << std::endl ;
|
||||
std::free( matching ) ;
|
||||
}
|
||||
bfd_close( b ) ;
|
||||
return ;
|
||||
}
|
||||
m_impl->m_bfd = b ;
|
||||
|
||||
long storage_needed = bfd_get_symtab_upper_bound( m_impl->m_bfd ) ;
|
||||
|
||||
m_impl->m_symbols = (asymbol**)std::malloc( storage_needed ) ;
|
||||
m_impl->m_symbol_count = bfd_canonicalize_symtab( b, m_impl->m_symbols ) ;
|
||||
}
|
||||
|
||||
SymbolInfo::~SymbolInfo( )
|
||||
{
|
||||
if ( m_impl->m_symbols != 0 )
|
||||
std::free( m_impl->m_symbols ) ;
|
||||
}
|
||||
|
||||
struct SymbolInfo::BacktraceInfo
|
||||
{
|
||||
const SymbolInfo *m_pthis ;
|
||||
void *m_addr ;
|
||||
const char *m_filename ;
|
||||
const char *m_func_name ;
|
||||
unsigned int m_lineno ;
|
||||
unsigned int m_is_found ;
|
||||
|
||||
static void Callback( bfd *abfd, asection *section, void* addr ) ;
|
||||
} ;
|
||||
|
||||
void SymbolInfo::BacktraceInfo::Callback( bfd *abfd, asection *section,
|
||||
void* data )
|
||||
{
|
||||
BacktraceInfo *info = (BacktraceInfo *)data ;
|
||||
if ((section->flags & SEC_ALLOC) == 0)
|
||||
return ;
|
||||
|
||||
bfd_vma vma = bfd_get_section_vma(abfd, section);
|
||||
|
||||
unsigned long address = (unsigned long)(info->m_addr);
|
||||
if ( address < vma )
|
||||
return;
|
||||
|
||||
bfd_size_type size = bfd_section_size(abfd, section);
|
||||
if ( address > (vma + size))
|
||||
return ;
|
||||
|
||||
const SymbolInfo *pthis = info->m_pthis ;
|
||||
info->m_is_found = bfd_find_nearest_line( abfd, section,
|
||||
pthis->m_impl->m_symbols,
|
||||
address - vma,
|
||||
&info->m_filename,
|
||||
&info->m_func_name,
|
||||
&info->m_lineno ) ;
|
||||
}
|
||||
|
||||
std::size_t SymbolInfo::Backtrace( void **stack, std::size_t count )
|
||||
{
|
||||
std::cerr << "begin backtrace" << std::endl ;
|
||||
std::size_t a = ::backtrace( stack, count ) ;
|
||||
std::cerr << "end backtrace" << std::endl ;
|
||||
|
||||
return a ;
|
||||
}
|
||||
|
||||
void SymbolInfo::PrintTrace( void *addr, std::ostream& os, std::size_t idx )
|
||||
{
|
||||
BacktraceInfo btinfo =
|
||||
{
|
||||
this, addr, 0, 0, 0, false
|
||||
} ;
|
||||
|
||||
std::cerr << "begin bfd" << std::endl ;
|
||||
Dl_info sym ;
|
||||
bfd_map_over_sections( m_impl->m_bfd,
|
||||
&SymbolInfo::BacktraceInfo::Callback,
|
||||
&btinfo ) ;
|
||||
std::cerr << "end bfd" << std::endl ;
|
||||
|
||||
if ( btinfo.m_is_found )
|
||||
{
|
||||
std::string filename = ( btinfo.m_filename == 0 ? std::string()
|
||||
: btinfo.m_filename ) ;
|
||||
#ifdef SRC_DIR
|
||||
std::size_t pos = filename.find( SRC_DIR ) ;
|
||||
if ( pos != std::string::npos )
|
||||
filename.erase( pos, std::strlen( SRC_DIR ) ) ;
|
||||
#endif
|
||||
os << "#" << idx << " " << addr << " "
|
||||
<< filename << ":" << btinfo.m_lineno
|
||||
<< " "
|
||||
<< (btinfo.m_func_name != 0 ? Demangle(btinfo.m_func_name) : "" )
|
||||
<< std::endl ;
|
||||
}
|
||||
else if ( dladdr( addr, &sym ) )
|
||||
os << "#" << idx << " " << addr << " "
|
||||
<< sym.dli_fname
|
||||
<< " "
|
||||
<< (sym.dli_sname != 0 ? Demangle( sym.dli_sname ) : "" )
|
||||
<< std::endl ;
|
||||
}
|
||||
|
||||
SymbolInfo* SymbolInfo::Instance( )
|
||||
{
|
||||
static SymbolInfo sthis ;
|
||||
return &sthis ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2006 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Addr.hh"
|
||||
|
||||
#include <memory>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/// ource code symbolic information
|
||||
/** \internal
|
||||
|
||||
This class represents symbolic information about the source code,
|
||||
e.g. function names and line numbers. It provides an interface to
|
||||
lookup these informations by address.
|
||||
*/
|
||||
class SymbolInfo
|
||||
{
|
||||
public :
|
||||
SymbolInfo( ) ;
|
||||
~SymbolInfo( ) ;
|
||||
|
||||
/*! \brief singleton function
|
||||
\internal
|
||||
|
||||
Returns the SymbolInfo singleton. Normally only one object
|
||||
of SymbolInfo is enough for one application, so a singleton
|
||||
is enough. This function will create the SymbolInfo object
|
||||
in the first call.
|
||||
*/
|
||||
static SymbolInfo* Instance( ) ;
|
||||
|
||||
std::size_t Backtrace( addr_t *stack, std::size_t count ) ;
|
||||
void PrintTrace( addr_t addr, std::ostream& os, std::size_t idx = 0 ) ;
|
||||
|
||||
private :
|
||||
struct Impl ;
|
||||
const std::auto_ptr<Impl> m_impl ;
|
||||
|
||||
struct BacktraceInfo ;
|
||||
friend struct BacktraceInfo ;
|
||||
} ;
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2012 Wan Wai Ho
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation version 2
|
||||
of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*! \brief get the begin iterator from an array
|
||||
\internal
|
||||
|
||||
This function returns the begin "iterator" of an array. It is useful to
|
||||
treat an array like an STL container.
|
||||
|
||||
For example:
|
||||
\code
|
||||
int array[10] = { 1, 2, 3, 4, 5 } ;
|
||||
std::vector<int> v ;
|
||||
std::copy( Begin(array), End(array), std::back_inserter( v ) ;
|
||||
\endcode
|
||||
|
||||
\param array reference to the array
|
||||
\return the begin iterator of the array. i.e. \a array itself
|
||||
\sa End(), Count()
|
||||
*/
|
||||
template <typename T, std::size_t n>
|
||||
T* Begin( T (&array)[n] )
|
||||
{
|
||||
return array ;
|
||||
}
|
||||
|
||||
/*! \brief get the end iterator from an array
|
||||
\internal
|
||||
|
||||
This function returns the end "iterator" of an array. It is useful to
|
||||
treat an array like an STL container.
|
||||
|
||||
\param array reference to the array
|
||||
\return the end iterator of the array. i.e. \a array+n
|
||||
\sa Begin(), Count()
|
||||
*/
|
||||
template <typename T, std::size_t n>
|
||||
T* End( T (&array)[n] )
|
||||
{
|
||||
return array + n ;
|
||||
}
|
||||
|
||||
/*! \brief get the number of elements in the array
|
||||
\internal
|
||||
|
||||
This function will return the number of elements in the array.
|
||||
\return the number of elements in the array
|
||||
\sa Begin(), End()
|
||||
*/
|
||||
template <typename T, std::size_t n>
|
||||
std::size_t Count( T (&array)[n] )
|
||||
{
|
||||
return n ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
|
@ -151,6 +151,7 @@ std::size_t NodeSet::size() const
|
|||
std::ostream& operator<<( std::ostream& os, const NodeSet& node )
|
||||
{
|
||||
std::copy( node.begin(), node.end(), std::ostream_iterator<Node>(os, " ") ) ;
|
||||
return os ;
|
||||
}
|
||||
|
||||
} } // end of namespace
|
||||
|
|
|
@ -48,7 +48,7 @@ void EntryTest::TestXml( )
|
|||
GRUT_ASSERT_EQUAL( "https://docs.google.com/feeds/default/private/full/folder%3A0B5KhdsbryVeGMl83OEV1ZVc3cUE",
|
||||
subject.SelfHref() ) ;
|
||||
|
||||
GRUT_ASSERT_EQUAL( 1, subject.ParentHrefs().size() ) ;
|
||||
GRUT_ASSERT_EQUAL( 1U, subject.ParentHrefs().size() ) ;
|
||||
GRUT_ASSERT_EQUAL( "https://docs.google.com/feeds/default/private/full/folder%3A0B5KhdsbryVeGNEZjdUxzZHl3Sjg",
|
||||
subject.ParentHrefs().front() ) ;
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ void NodeTest::TestParseFile( )
|
|||
}
|
||||
|
||||
NodeSet r = n["entry"]["link"] ;
|
||||
GRUT_ASSERT_EQUAL( 2, r.size() ) ;
|
||||
GRUT_ASSERT_EQUAL( 2U, r.size() ) ;
|
||||
}
|
||||
|
||||
} // end of namespace grut
|
||||
|
|
Loading…
Reference in New Issue