← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~paul-lucas/zorba/pjl-misc into lp:zorba

 

Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/pjl-misc into lp:zorba.

Commit message:
Clean-up of file class and file module; added file:is-symlink().

Requested reviews:
  Paul J. Lucas (paul-lucas)

For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/pjl-misc/+merge/151861

Clean-up of file class and file module; added file:is-symlink().
-- 
https://code.launchpad.net/~paul-lucas/zorba/pjl-misc/+merge/151861
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'include/zorba/util/file.h'
--- include/zorba/util/file.h	2013-02-07 17:24:36 +0000
+++ include/zorba/util/file.h	2013-03-06 02:55:26 +0000
@@ -49,37 +49,36 @@
   typedef zorba::File::FileSize_t file_size_t;
 
 protected:
-  filetype type; 
-
-// file attributes
-  file_size_t size;          // size in bytes
-
-  void do_stat();
+  filetype do_stat( bool follow_symlinks = true, file_size_t *size = 0 ) const;
 
 public:
   file(const filesystem_path &path, int flags = 0);
 
 public: // common methods
   void set_path(std::string const& _path ) { *((filesystem_path *) this) = _path; }
-  void set_filetype(enum filetype _type ) { type = _type ; }
-  enum filetype get_filetype();
-
-  bool is_directory() const { return (type==type_directory); }  
-  bool is_file() const { return (type==type_file); }  
-  bool is_link() const { return (type==type_link); }  
-  bool is_volume() const { return (type==type_volume); }  
-
-  bool is_invalid() const { return (type==type_invalid); }  
-  bool exists() const { return (type!=type_non_existent && type!=type_invalid); }  
-
-  time_t lastModified();
+  void set_filetype(filetype)   { /* do nothing */ }  // deprecated
+  filetype get_filetype() const { return do_stat(); }
+
+  bool is_directory() const     { return do_stat() == type_directory; }  
+  bool is_file() const          { return do_stat() == type_file; }  
+  bool is_link() const          { return do_stat( false ) == type_link; }  
+  bool is_volume() const        { return do_stat() == type_volume; }  
+
+  bool is_invalid() const       { return false; }     // deprecated
+  bool exists() const           { return do_stat() != type_non_existent; }
+
+  time_t lastModified() const;
 
 public: // file methods
   void create();
   void remove(bool ignore = true);
   void rename(std::string const& newpath);
 
-  file_size_t get_size() const        { return size; }
+  file_size_t get_size() const {
+    file_size_t size;
+    do_stat( true, &size );
+    return size;
+  }
 
 public: // directory methods
   void mkdir();
@@ -90,7 +89,7 @@
   void chdir();
 #endif
 
-  bool is_empty() const { return (size == (file_size_t)0); }
+  bool is_empty() const { return get_size() == 0; }
 };
 
 

=== modified file 'modules/org/expath/ns/file.xq'
--- modules/org/expath/ns/file.xq	2013-02-07 17:24:36 +0000
+++ modules/org/expath/ns/file.xq	2013-03-06 02:55:26 +0000
@@ -228,7 +228,7 @@
 ) as empty-sequence()
 {
   if (file:exists($path)) then
-    if (file:is-directory($path)) then
+    if (not(file:is-symlink($path)) and file:is-directory($path)) then
       file:delete-directory-impl($path)
     else
       file:delete-file-impl($path)
@@ -275,32 +275,47 @@
 (:~
  : Tests if a path/URI is already used in the file system.
  :
- : @param $path The path/URI to test for existence.
- : @return true if the path/URI points to an existing file system item.
+ : @param $path The path/URI to test.
+ : @return true if <code>$path</code> points to an existing file system item;
+ : for symbolic links, retuns true if the symbolic link itself exists and not
+ : whether the linked-to item exists.
  :)
 declare %an:nondeterministic function file:exists(
   $path as xs:string
 ) as xs:boolean external;
 
 (:~
- : Tests if a path/URI points to a directory. On UNIX-based systems, the root
+ : Tests if a path/URI points to a directory. On Unix-based systems, the root
  : and the volume roots are considered directories.
  :
- : @param $dir The path/URI to test.
- : @return true if the path/URI points to a directory.
+ : @param $path The path/URI to test.
+ : @return true if <code>$path</code> points to a directory; for symbolic
+ : links, returns true if the linked-to item is a directory.
  :)
 declare %an:nondeterministic function file:is-directory(
-  $dir as xs:string
+  $path as xs:string
 ) as xs:boolean external;
 
 (:~
  : Tests if a path/URI points to a file.
  :
- : @param $dir The path/URI to test.
- : @return true if the path/URI points to a file.
+ : @param $path The path/URI to test.
+ : @return true if <code>$path</coe> points to a file; for symbolic links,
+ : returns true if the linked-to item is a file.
  :)
 declare %an:nondeterministic function file:is-file(
-  $file as xs:string
+  $path as xs:string
+) as xs:boolean external;
+
+(:~
+ : Tests if a path/URI points to symbolic link.  This works on all Unix-based
+ : systems as well as Windows Vista or later.
+ :
+ : @param $path The path/URI to test.
+ : @return true if <code>$path</code> points to a symbolic link.
+ :)
+declare %an:nondeterministic function file:is-symlink(
+  $path as xs:string
 ) as xs:boolean external;
 
 (:~
@@ -656,7 +671,7 @@
 
 (:~
  : This function returns the value of the operating system specific directory
- : separator. For example, <pre>/</pre> on UNIX-based systems and <pre>\</pre>
+ : separator. For example, <pre>/</pre> on Unix-based systems and <pre>\</pre>
  : on Windows systems.
  :
  : @return The operating system specific directory separator.
@@ -665,7 +680,7 @@
 
 (:~
  : This function returns the value of the operating system specific path
- : separator. For example, <pre>:</pre> on UNIX-based systems and <pre>;</pre>
+ : separator. For example, <pre>:</pre> on Unix-based systems and <pre>;</pre>
  : on Windows systems.
  :
  : @return The operating system specific path separator.

=== modified file 'modules/org/expath/ns/file.xq.src/file.cpp'
--- modules/org/expath/ns/file.xq.src/file.cpp	2013-02-26 04:12:43 +0000
+++ modules/org/expath/ns/file.xq.src/file.cpp	2013-03-06 02:55:26 +0000
@@ -415,6 +415,30 @@
 
 //*****************************************************************************
 
+IsSymlinkFunction::IsSymlinkFunction(const FileModule* aModule)
+  : FileFunction(aModule)
+{
+}
+
+ItemSequence_t
+IsSymlinkFunction::evaluate(
+  const ExternalFunction::Arguments_t& aArgs,
+  const StaticContext*                 aSctxCtx,
+  const DynamicContext*                aDynCtx) const
+{
+  bool   lResult = false;
+  String lFileStr = getFilePathString(aArgs, 0);
+
+  File_t lFile = File::createFile(lFileStr.c_str());
+  if (lFile->isLink()) {
+    lResult = true;
+  }
+  return ItemSequence_t(new SingletonItemSequence(
+      theModule->getItemFactory()->createBoolean(lResult)));
+}
+
+//*****************************************************************************
+
 CopyFileImplFunction::CopyFileImplFunction(const FileModule* aModule)
   : FileFunction(aModule)
 {

=== modified file 'modules/org/expath/ns/file.xq.src/file.h'
--- modules/org/expath/ns/file.xq.src/file.h	2013-02-07 17:24:36 +0000
+++ modules/org/expath/ns/file.xq.src/file.h	2013-03-06 02:55:26 +0000
@@ -162,6 +162,22 @@
 
 //*****************************************************************************
 
+  class IsSymlinkFunction : public FileFunction
+  {
+    public:
+      IsSymlinkFunction(const FileModule* aModule);
+
+      virtual String
+      getLocalName() const { return "is-symlink"; }
+  
+      virtual ItemSequence_t 
+      evaluate(const ExternalFunction::Arguments_t& args,
+               const StaticContext* aSctxCtx,
+               const DynamicContext* aDynCtx) const;
+  };
+
+//*****************************************************************************
+
   class LastModifiedFunction : public FileFunction
   {
     public:

=== modified file 'modules/org/expath/ns/file.xq.src/file_module.cpp'
--- modules/org/expath/ns/file.xq.src/file_module.cpp	2013-02-07 17:24:36 +0000
+++ modules/org/expath/ns/file.xq.src/file_module.cpp	2013-03-06 02:55:26 +0000
@@ -54,6 +54,8 @@
       lFunc = new IsDirectoryFunction(this);
     } else if (aLocalname == "is-file") {
       lFunc = new IsFileFunction(this);
+    } else if (aLocalname == "is-symlink") {
+      lFunc = new IsSymlinkFunction(this);
     } else if (aLocalname == "copy-file-impl") {
       lFunc = new CopyFileImplFunction(this);
     } else if (aLocalname == "write-text") {

=== modified file 'src/util/file.cpp'
--- src/util/file.cpp	2013-03-05 02:21:24 +0000
+++ src/util/file.cpp	2013-03-06 02:55:26 +0000
@@ -214,37 +214,34 @@
   return path;
 }
 
-void file::do_stat() {
+file::filetype file::do_stat( bool follow_symlinks, file_size_t *size ) const {
 #ifdef ZORBA_WITH_FILE_ACCESS
   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;
-    case fs::file        : type = type_file;         break;
-    case fs::link        : type = type_link;         break;
-    case fs::volume      : type = type_volume;       break;
-    case fs::other       : type = type_other;        break;
+  filetype ft;
+  switch ( fs::get_type( get_path(), follow_symlinks, &fs_size ) ) {
+    case fs::non_existent: ft = type_non_existent; break;
+    case fs::directory   : ft = type_directory;    break;
+    case fs::file        : ft = type_file;         break;
+    case fs::link        : ft = type_link;         break;
+    case fs::volume      : ft = type_volume;       break;
+    case fs::other       : ft = type_other;        break;
   }
-  size = fs_size;
+  if ( size )
+    *size = static_cast<file_size_t>( fs_size );
+  return ft;
 #else
-  type = type_non_existent;
-  size = 0;
+  if ( size )
+    *size = 0;
+  return type_non_existent;
 #endif
 }
 
 file::file( const filesystem_path &path_, int flags_ ) :
   filesystem_path( path_, flags_ )
 {
-  do_stat();
-}
-
-file::filetype file::get_filetype() {
-  if ( type == type_non_existent )
-    do_stat();
-  return type;
-}
-
-time_t file::lastModified() {
+}
+
+time_t file::lastModified() const {
 #ifdef ZORBA_WITH_FILE_ACCESS
   struct stat s;
   if ( ::stat( get_path().c_str(), &s ) == 0 )
@@ -256,8 +253,7 @@
 void file::create() {
 #ifdef ZORBA_WITH_FILE_ACCESS
   try {
-    fs::create( c_str() );
-    set_filetype( type_file );
+    fs::create( get_path() );
   }
   catch ( fs::exception const &e ) {
     throw ZORBA_IO_EXCEPTION( e.function(), e.path() );
@@ -268,8 +264,7 @@
 void file::mkdir() {
 #ifdef ZORBA_WITH_FILE_ACCESS
   try {
-    fs::mkdir( c_str() );
-    set_filetype( type_directory );
+    fs::mkdir( get_path() );
   }
   catch ( fs::exception const &e ) {
     throw ZORBA_IO_EXCEPTION( e.function(), e.path() );
@@ -280,10 +275,9 @@
 void file::lsdir(std::vector<std::string> &list) {
 #ifdef ZORBA_WITH_FILE_ACCESS
   try {
-    fs::iterator dir_iter( c_str() );
+    fs::iterator dir_iter( get_path() );
     while ( dir_iter.next() )
       list.push_back( dir_iter.entry_name() );
-    set_filetype( type_directory );
   }
   catch ( fs::exception const &e ) {
     throw ZORBA_IO_EXCEPTION( e.function(), e.path() );
@@ -298,18 +292,13 @@
     files.push_back( f );
   for ( int i = files.size() - 1; i >= 0; --i )
     files[i].mkdir();
-  set_filetype( type_directory );
 #endif
 }
 
 void file::remove( bool ignore ) {
 #ifdef ZORBA_WITH_FILE_ACCESS
-  if ( !fs::remove( c_str() ) ) {
-    if ( !ignore )
-      throw ZORBA_IO_EXCEPTION( "remove()", get_path() );
-    return;
-  }
-  set_filetype( type_non_existent );
+  if ( !fs::remove( get_path() ) && !ignore )
+    throw ZORBA_IO_EXCEPTION( "remove()", get_path() );
 #endif
 }
 
@@ -322,7 +311,7 @@
 void file::chdir() {
   if ( is_directory() ) {
     try {
-      fs::chdir( c_str() );
+      fs::chdir( get_path() );
     }
     catch ( fs::exception const &e ) {
       throw ZORBA_IO_EXCEPTION( e.function(), e.path() );
@@ -335,7 +324,7 @@
 void file::rename( std::string const& newpath ) {
 #ifdef ZORBA_WITH_FILE_ACCESS
   try {
-    fs::rename( c_str(), newpath );
+    fs::rename( get_path(), newpath );
   }
   catch ( fs::exception const &e ) {
     throw ZORBA_IO_EXCEPTION( e.function(), e.path() );

=== modified file 'src/util/fs_util.cpp'
--- src/util/fs_util.cpp	2013-03-05 02:22:37 +0000
+++ src/util/fs_util.cpp	2013-03-06 02:55:26 +0000
@@ -316,7 +316,7 @@
 #endif
 }
 
-iterator::iterator( char const *path ) : dir_path_( path ) {
+void iterator::ctor_impl() {
   make_absolute( dir_path_ );
 #ifndef WIN32
   if ( !(dir_ = ::opendir( dir_path_.c_str() )) )

=== modified file 'src/util/fs_util.h'
--- src/util/fs_util.h	2013-03-05 02:22:37 +0000
+++ src/util/fs_util.h	2013-03-06 02:55:26 +0000
@@ -168,16 +168,35 @@
 ////////// Directory iteration ////////////////////////////////////////////////
 
 /**
- * An fs::iterator iterates over the entries in a directory.
+ * An %fs::iterator iterates over the entries in a directory.
  */
 class iterator {
 public:
   /**
-   * Constructs an %itertor.
-   *
-   * @throws fs::exception if the construction failed, e.g., path not found.
-   */
-  iterator( char const *path );
+   * Constructs an %iterator.
+   *
+   * @param path The full path to the directory to iterate over.
+   * @throws fs::exception if the construction failed, e.g., path not found.
+   */
+  iterator( char const *path ) : dir_path_( path ) {
+    ctor_impl();
+  }
+
+  /**
+   * Constructs an %iterator.
+   *
+   * @tparam PathStringType The \a path string type.
+   * @param path The full path to the directory to iterate over.
+   * @throws fs::exception if the construction failed, e.g., path not found.
+   */
+  template<class PathStringType>
+  iterator( PathStringType const &path,
+            typename std::enable_if<
+              ztd::has_c_str<PathStringType,
+              char const* (PathStringType::*)() const>::value
+            >::type* = 0 ) : dir_path_( path.c_str() ) {
+    ctor_impl();
+  }
 
   /**
    * Destroys this %iterator.
@@ -244,6 +263,8 @@
   void win32_closedir();
 #endif /* WIN32 */
 
+  void ctor_impl();
+
   // forbid
   iterator( iterator const& );
   iterator& operator=( iterator const& );

=== modified file 'src/util/string_util.cpp'
--- src/util/string_util.cpp	2013-03-02 15:51:30 +0000
+++ src/util/string_util.cpp	2013-03-06 02:55:26 +0000
@@ -153,10 +153,8 @@
                            char const **last ) {
   aton_context const ctx( last );
   unsigned long long n = 0;
-  char const *s = buf;
+  char const *s = ascii::trim_start_whitespace( buf, end - 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';


Follow ups