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

Reply via email to