Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/pjl-misc into lp:zorba.
Requested reviews: Paul J. Lucas (paul-lucas) For more details, see: https://code.launchpad.net/~paul-lucas/zorba/pjl-misc/+merge/151674 Added "follow_symlink" to fs::get_type(). -- https://code.launchpad.net/~paul-lucas/zorba/pjl-misc/+merge/151674 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/runtime/full_text/thesauri/iso2788.cpp' --- src/runtime/full_text/thesauri/iso2788.cpp 2013-02-07 17:24:36 +0000 +++ src/runtime/full_text/thesauri/iso2788.cpp 2013-03-05 02:25:27 +0000 @@ -15,7 +15,7 @@ */ #include "stdafx.h" -#include <algorithm> /* for lower_bound() */ +#include <algorithm> /* for equal_range() */ #include <cstring> #include "util/less.h" === modified file 'src/util/file.cpp' --- src/util/file.cpp 2013-02-07 17:24:36 +0000 +++ src/util/file.cpp 2013-03-05 02:25:27 +0000 @@ -216,7 +216,7 @@ void file::do_stat() { #ifdef ZORBA_WITH_FILE_ACCESS - fs::size_type fs_size; + fs::size_type fs_size = 0; switch ( fs::get_type( c_str(), &fs_size ) ) { case fs::non_existent: type = type_non_existent; break; case fs::directory : type = type_directory; break; === modified file 'src/util/fs_util.cpp' --- src/util/fs_util.cpp 2013-02-07 17:24:36 +0000 +++ src/util/fs_util.cpp 2013-03-05 02:25:27 +0000 @@ -275,20 +275,25 @@ #endif /* ZORBA_WITH_FILE_ACCESS */ -type get_type( char const *path, size_type *size ) { +type get_type( char const *path, bool follow_symlink, size_type *size ) { #ifndef WIN32 struct stat st_buf; - if ( ::stat( path, &st_buf ) == -1 ) { + int const status = follow_symlink ? + ::stat( path, &st_buf ) : ::lstat( path, &st_buf ); + if ( status == -1 ) { if ( errno == ENOENT ) return non_existent; - throw ZORBA_IO_EXCEPTION( "stat()", path ); + throw ZORBA_IO_EXCEPTION( follow_symlink ? "stat()" : "lstat()", path ); } if ( S_ISDIR( st_buf.st_mode ) ) return directory; - if ( size ) - *size = st_buf.st_size; - if ( S_ISREG( st_buf.st_mode ) ) + if ( S_ISLNK( st_buf.st_mode ) ) + return link; + if ( S_ISREG( st_buf.st_mode ) ) { + if ( size ) + *size = st_buf.st_size; return file; + } return other; #else WCHAR wpath[ MAX_PATH ]; === modified file 'src/util/fs_util.h' --- src/util/fs_util.h 2013-02-07 17:24:36 +0000 +++ src/util/fs_util.h 2013-03-05 02:25:27 +0000 @@ -500,27 +500,37 @@ * Gets the type of the given file. * * @param path The full path to check. + * @param follow_symlink If \c true follows symbolic links. * @param size A pointer to a receive the size of the file in bytes. The size * is set only if it's not \c nullptr and the file's type is \c file. - * @return Returns said type. + * @return If \a path refers to a symbolic link and \a follow_symlink is + * \c true, the type returned is of that to which the link refers; if \a path + * refers to a symbolic and \a follow_symlink is \c false, returns \c link; if + * \a path does not refer to a symbolic link, returns the type of \a path. */ -type get_type( char const *path, size_type *size = nullptr ); +type get_type( char const *path, bool follow_symlink = true, + size_type *size = nullptr ); /** * Gets the type of the given file. * * @tparam PathStringType The \a path string type. * @param path The full path to check. + * @param follow_symlink If \c true follows symbolic links. * @param size A pointer to a receive the size of the file in bytes. The size * is set only if it's not \c nullptr and the file's type is \c file. - * @return Returns said type. + * @return If \a path refers to a symbolic link and \a follow_symlink is + * \c true, the type returned is of that to which the link refers; if \a path + * refers to a symbolic and \a follow_symlink is \c false, returns \c link; if + * \a path does not refer to a symbolic link, returns the type of \a path. */ template<class PathStringType> inline typename std::enable_if<ztd::has_c_str<PathStringType, char const* (PathStringType::*)() const>::value, type>::type -get_type( PathStringType const &path, size_type *size = nullptr ) { - return get_type( path.c_str(), size ); +get_type( PathStringType const &path, bool follow_symlink = true, + size_type *size = nullptr ) { + return get_type( path.c_str(), follow_symlink, size ); } /** === modified file 'src/util/string_util.cpp' --- src/util/string_util.cpp 2013-02-07 17:24:36 +0000 +++ src/util/string_util.cpp 2013-03-05 02:25:27 +0000 @@ -28,8 +28,8 @@ // Windows doesn't have these functions -- add them ourselves. - static float strtof( char const *s, char **end ) { - double const result = std::strtod( s, end ); + static float strtof( char const *s, char **last ) { + double const result = std::strtod( s, last ); if ( !errno ) { if ( result < std::numeric_limits<float>::min() || result > std::numeric_limits<float>::max() ) @@ -38,12 +38,12 @@ return static_cast<float>( result ); } - inline long long strtoll( char const *s, char **end, int base ) { - return ::_strtoi64( s, end, base ); + inline long long strtoll( char const *s, char **last, int base ) { + return ::_strtoi64( s, last, base ); } - inline unsigned long long strtoull( char const *s, char **end, int base ) { - return ::_strtoui64( s, end, base ); + inline unsigned long long strtoull( char const *s, char **last, int base ) { + return ::_strtoui64( s, last, base ); } } // namespace std @@ -56,43 +56,39 @@ /////////////////////////////////////////////////////////////////////////////// -static void no_digits( char const *buf ) { - throw std::invalid_argument( BUILD_STRING( '"', buf, "\": no digits" ) ); -} - -static void too_big_or_small( char const *buf, char const *end ) { - zstring const s( buf, end ); +static void too_big_or_small( char const *buf, char const *last ) { + zstring const s( buf, last ); throw std::range_error( BUILD_STRING( '"', s, "\": number too big/small" ) ); } -inline void check_errno( char const *buf, char const *end ) { +inline void check_errno( char const *buf, char const *last ) { if ( errno == ERANGE ) - too_big_or_small( buf, end ); + too_big_or_small( buf, last ); } -static void check_trailing_chars_impl( char const *end ) { - for ( ; *end; ++end ) // remaining characters, if any, ... - if ( !ascii::is_space( *end ) ) // ... may only be whitespace +static void check_trailing_chars_impl( char const *last ) { + for ( ; *last; ++last ) // remaining characters, if any, ... + if ( !ascii::is_space( *last ) ) // ... may only be whitespace throw std::invalid_argument( - BUILD_STRING( '\'', *end, "': invalid character" ) + BUILD_STRING( '\'', *last, "': invalid character" ) ); } -inline void check_parse_number( char const *buf, char const *end, +inline void check_parse_number( char const *buf, char const *last, bool check_trailing_chars ) { - if ( end == buf ) - no_digits( buf ); + if ( last == buf ) + throw std::invalid_argument( BUILD_STRING( '"', buf, "\": no digits" ) ); if ( check_trailing_chars ) - check_trailing_chars_impl( end ); + check_trailing_chars_impl( last ); } class aton_context { public: - aton_context( char const **&end ) { - if ( end ) { + aton_context( char const **&last ) { + if ( last ) { check_trailing_chars_ = false; } else { - end = &end_; + last = &last_; check_trailing_chars_ = true; } errno = 0; @@ -102,44 +98,44 @@ } private: bool check_trailing_chars_; - char const *end_; + char const *last_; }; /////////////////////////////////////////////////////////////////////////////// -double atod( char const *buf, char const **end ) { - aton_context const ctx( end ); - double const result = std::strtod( buf, (char**)end ); - check_parse_number( buf, *end, ctx.check_trailing_chars() ); - return result; -} - -float atof( char const *buf, char const **end ) { - aton_context const ctx( end ); - float const result = std::strtof( buf, (char**)end ); - check_parse_number( buf, *end, ctx.check_trailing_chars() ); - return result; -} - -long long atoll( char const *buf, char const **end ) { - aton_context const ctx( end ); - long long const result = std::strtoll( buf, (char**)end, 10 ); - check_errno( buf, *end ); - check_parse_number( buf, *end, ctx.check_trailing_chars() ); - return result; -} - -unsigned long long atoull( char const *buf, char const **end ) { - aton_context const ctx( end ); +double atod( char const *buf, char const **last ) { + aton_context const ctx( last ); + double const result = std::strtod( buf, (char**)last ); + check_parse_number( buf, *last, ctx.check_trailing_chars() ); + return result; +} + +float atof( char const *buf, char const **last ) { + aton_context const ctx( last ); + float const result = std::strtof( buf, (char**)last ); + check_parse_number( buf, *last, ctx.check_trailing_chars() ); + return result; +} + +long long atoll( char const *buf, char const **last ) { + aton_context const ctx( last ); + long long const result = std::strtoll( buf, (char**)last, 10 ); + check_errno( buf, *last ); + check_parse_number( buf, *last, ctx.check_trailing_chars() ); + return result; +} + +unsigned long long atoull( char const *buf, char const **last ) { + aton_context const ctx( last ); // // We have to check for '-' ourselves since strtoull(3) allows it (oddly). // buf = ascii::trim_start_whitespace( buf ); bool const minus = *buf == '-'; - unsigned long long const result = std::strtoull( buf, (char**)end, 10 ); - check_errno( buf, *end ); - check_parse_number( buf, *end, ctx.check_trailing_chars() ); + unsigned long long const result = std::strtoull( buf, (char**)last, 10 ); + check_errno( buf, *last ); + check_parse_number( buf, *last, ctx.check_trailing_chars() ); if ( minus && result ) { // @@ -153,6 +149,27 @@ return result; } +unsigned long long atoull( char const *buf, char const *end, + char const **last ) { + aton_context const ctx( last ); + unsigned long long n = 0; + char const *s = buf; + + for ( ; s < end && ascii::is_space( *s ); ++s ) + ; + for ( ; s < end && ascii::is_digit( *s ); ++s ) { + unsigned long long const n_prev = n; + n = n * 10 + *s - '0'; + if ( n < n_prev ) { + errno = ERANGE; + too_big_or_small( buf, end ); + } + } + *last = s; + check_parse_number( buf, *last, ctx.check_trailing_chars() ); + return n; +} + char* itoa( long long n, char *buf ) { // // This implementation is much faster than using sprintf(3). === modified file 'src/util/string_util.h' --- src/util/string_util.h 2013-02-07 17:24:36 +0000 +++ src/util/string_util.h 2013-03-05 02:25:27 +0000 @@ -410,7 +410,7 @@ * * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c double value. @@ -418,14 +418,14 @@ * leading/trailing whitespace, or contains no digits at all. * @throws range_error if the number overflows/underflows. */ -double atod( char const *buf, char const **end = nullptr ); +double atod( char const *buf, char const **last = nullptr ); /** * Parses the given string for a \c float. * * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c float value. @@ -433,14 +433,14 @@ * leading/trailing whitespace, or contains no digits at all. * @throws range_error if the number overflows/underflows. */ -float atof( char const *buf, char const **end = nullptr ); +float atof( char const *buf, char const **last = nullptr ); /** - * Parses the given string for a <code>long lomg</code>. + * Parses the given string for a <code>long long</code>. * * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the <code>long long</code> value. @@ -448,22 +448,39 @@ * leading/trailing whitespace, or contains no digits at all. * @throws range_error if the number overflows/underflows. */ -long long atoll( char const *buf, char const **end = nullptr ); +long long atoll( char const *buf, char const **last = nullptr ); /** - * Parses the given string for an <code>unsigned long lomg</code>. + * Parses the given string for an <code>unsigned long long</code>. * * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the - * last numeric character parsed; if \c null, characters past the last numeric - * character may only be whitespace. - * @return Returns the <code>unsigned long long</code> value. - * @throws invalid_argument if \a buf contains characters other than digits or - * leading/trailing whitespace, or contains no digits at all. - * @throws range_error if the number overflows/underflows. - */ -unsigned long long atoull( char const *buf, char const **end = nullptr ); + * @param last If not \c null, this is set to point to the character after the + * last numeric character parsed; if \c null, characters past the last numeric + * character may only be whitespace. + * @return Returns the <code>unsigned long long</code> value. + * @throws invalid_argument if \a buf contains characters other than digits or + * leading/trailing whitespace, or contains no digits at all. + * @throws range_error if the number overflows. + */ +unsigned long long atoull( char const *buf, char const **last = nullptr ); + +/** + * Parses the given string for an <code>unsigned long long</code>. + * + * @param buf The C string to parse; it need not be null-terminated. Leading + * and trailing whitespace is ignored. + * @param end A pointer to one past the last character to parse. + * @param last If not \c null, this is set to point to the character after the + * last numeric character parsed; if \c null, characters past the last numeric + * character may only be whitespace. + * @return Returns the <code>unsigned long long</code> value. + * @throws invalid_argument if \a buf contains characters other than digits or + * leading/trailing whitespace, or contains no digits at all. + * @throws range_error if the number overflows. + */ +unsigned long long atoull( char const *buf, char const *end, + char const **last ); /** * Parses the given string for a C++ signed integral type. @@ -471,7 +488,7 @@ * @tparam IntegralType The C++ signed integral type to parse for. * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c IntegralType value. @@ -488,8 +505,8 @@ typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value && ZORBA_TR1_NS::is_signed<IntegralType>::value, IntegralType>::type -aton( char const *buf, char const **end = nullptr ) { - long long const result = atoll( buf, end ); +aton( char const *buf, char const **last = nullptr ) { + long long const result = atoll( buf, last ); if ( result < std::numeric_limits<IntegralType>::min() || result > std::numeric_limits<IntegralType>::max() ) throw std::range_error( @@ -506,7 +523,7 @@ * whitespace is ignored. * @param low The lower acceptable bound. * @param high the higher acceptable bound. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c IntegralType value. @@ -524,8 +541,8 @@ && ZORBA_TR1_NS::is_signed<IntegralType>::value, IntegralType>::type aton( char const *buf, IntegralType low, IntegralType high, - char const **end = nullptr ) { - long long const result = atoll( buf, end ); + char const **last = nullptr ) { + long long const result = atoll( buf, last ); if ( result < low || result > high ) throw std::range_error( BUILD_STRING( @@ -541,7 +558,7 @@ * @tparam IntegralType The C++ unsigned integral type to parse for. * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c IntegralType value. @@ -552,8 +569,8 @@ template<typename IntegralType> inline typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, IntegralType>::type -aton( char const *buf, char const **end = nullptr ) { - unsigned long long const result = atoull( buf, end ); +aton( char const *buf, char const **last = nullptr ) { + unsigned long long const result = atoull( buf, last ); if ( result > std::numeric_limits<IntegralType>::max() ) throw std::range_error( BUILD_STRING( '"', result, "\": number too big" ) ); return static_cast<IntegralType>( result ); @@ -567,7 +584,7 @@ * whitespace is ignored. * @param low The lower acceptable bound. * @param high the higher acceptable bound. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c IntegralType value. @@ -579,8 +596,8 @@ typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, IntegralType>::type aton( char const *buf, IntegralType low, IntegralType high, - char const **end = nullptr ) { - unsigned long long const result = atoull( buf, end ); + char const **last = nullptr ) { + unsigned long long const result = atoull( buf, last ); if ( result < low || result > high ) throw std::range_error( BUILD_STRING( @@ -595,7 +612,7 @@ * * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c double value. @@ -607,8 +624,8 @@ template<typename NumericType> inline typename std::enable_if<ZORBA_TR1_NS::is_same<NumericType,double>::value, NumericType>::type -aton( char const *buf, char const **end = nullptr ) { - return atod( buf, end ); +aton( char const *buf, char const **last = nullptr ) { + return atod( buf, last ); } /** @@ -616,7 +633,7 @@ * * @param buf The null-terminated C string to parse. Leading and trailing * whitespace is ignored. - * @param end If not \c null, this is set to point to the character after the + * @param last If not \c null, this is set to point to the character after the * last numeric character parsed; if \c null, characters past the last numeric * character may only be whitespace. * @return Returns the \c float value. @@ -628,8 +645,8 @@ template<typename NumericType> inline typename std::enable_if<ZORBA_TR1_NS::is_same<NumericType,float>::value, NumericType>::type -aton( char const *buf, char const **end = nullptr ) { - return atof( buf, end ); +aton( char const *buf, char const **last = nullptr ) { + return atof( buf, last ); } ////////// To-string conversion ////////////////////////////////////////////////
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp