Initial implementation of the Path operating system concept.
authorReid Spencer <rspencer@reidspencer.com>
Wed, 25 Aug 2004 06:20:07 +0000 (06:20 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Wed, 25 Aug 2004 06:20:07 +0000 (06:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16048 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/LICENSE.TXT [new file with mode: 0644]
include/llvm/System/Path.h [new file with mode: 0644]
lib/System/Linux/Path.cpp [new file with mode: 0644]
lib/System/Makefile [new file with mode: 0644]
lib/System/Path.cpp [new file with mode: 0644]
lib/System/Unix/Path.cpp [new file with mode: 0644]
lib/System/Unix/Path.inc [new file with mode: 0644]
lib/System/Unix/Unix.h [new file with mode: 0644]

diff --git a/include/llvm/System/LICENSE.TXT b/include/llvm/System/LICENSE.TXT
new file mode 100644 (file)
index 0000000..f569da2
--- /dev/null
@@ -0,0 +1,6 @@
+LLVM System Interface Library
+-------------------------------------------------------------------------------
+The LLVM System Interface Library is licensed under the Illinois Open Source 
+License and has the following additional copyright:
+
+Copyright (C) 2004 eXtensible Systems, Inc.
diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h
new file mode 100644 (file)
index 0000000..df699a3
--- /dev/null
@@ -0,0 +1,160 @@
+//===- llvm/System/Path.h ---------------------------------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PATH_H
+#define LLVM_SYSTEM_PATH_H
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+  /// This class provides an abstraction for the name of a path
+  /// to a file or directory in the filesystem and various basic operations
+  /// on it.
+  /// @since 1.4
+  /// @brief An abstraction for operating system paths.
+  class Path : public std::string {
+  /// @name Constructors
+  /// @{
+  public:
+    /// Creates a null (empty) path
+    /// @brief Default Constructor
+    Path () : std::string() {}
+
+    /// Creates a path from char*
+    /// @brief char* converter
+    Path ( const char * name ) : std::string(name) {
+      assert(is_valid());
+    }
+
+    /// @brief std::string converter
+    Path ( const std::string& name ) : std::string(name){
+      assert(is_valid());
+    };
+
+    /// Copies the path with copy-on-write semantics. The \p this Path
+    /// will reference \p the that Path until one of them is modified
+    /// at which point a full copy is taken before the write.
+    /// @brief Copy Constructor
+    Path ( const Path & that ) : std::string(that) {}
+
+    /// Releases storage associated with the Path object
+    /// @brief Destructor
+    ~Path ( void ) {};
+
+  /// @}
+  /// @name Operators
+  /// @{
+  public:
+    /// Makes a copy of \p that to \p this with copy-on-write semantics.
+    /// @returns \p this
+    /// @brief Assignment Operator
+    Path & operator = ( const Path & that ) {
+      this->assign (that);
+      return *this;
+    }
+
+    /// Comparies \p this Path with \p that Path for equality.
+    /// @returns true if \p this and \p that refer to the same item.
+    /// @brief Equality Operator
+    bool operator ==( const Path & that ) const {
+      return 0 == this->compare( that ) ;
+    }
+
+    /// Comparies \p this Path with \p that Path for inequality.
+    /// @returns true if \p this and \p that refer to different items.
+    /// @brief Inequality Operator
+    bool operator !=( const Path & that ) const {
+      return 0 != this->compare( that );
+    }
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    /// @returns true if the path is valid
+    /// @brief Determines if the path is valid (properly formed) or not.
+    bool is_valid() const;
+
+    /// @returns true if the path could reference a file
+    /// @brief Determines if the path is valid for a file reference.
+    bool is_file() const;
+
+    /// @returns true if the path could reference a directory
+    /// @brief Determines if the path is valid for a directory reference.
+    bool is_directory() const;
+
+    /// @brief Fills and zero terminates a buffer with the path
+    void fill( char* buffer, unsigned len ) const;
+
+  /// @}
+  /// @name Mutators
+  /// @{
+  public:
+      /// This ensures that the pathname is terminated with a /
+      /// @brief Make the path reference a directory.
+      void make_directory();
+
+      /// This ensures that the pathname is not terminated with a /
+      /// @brief Makes the path reference a file.
+      void make_file();
+
+      /// the file system.
+      /// @returns true if the pathname references an existing file.
+      /// @brief Determines if the path is a file or directory in
+      bool exists();
+
+      /// The \p dirname is added to the end of the Path.
+      /// @param dirname A string providing the directory name to
+      /// be appended to the path.
+      /// @brief Appends the name of a directory.
+      void append_directory( const std::string& dirname ) {
+        this->append( dirname );
+        make_directory();
+      }
+
+      /// The \p filename is added to the end of the Path.
+      /// @brief Appends the name of a file.
+      void append_file( const std::string& filename ) {
+        this->append( filename );
+      }
+
+      /// Directories will have no entries. Files will be zero length. If
+      /// the file or directory already exists, no error results.
+      /// @throws SystemException if any error occurs.
+      /// @brief Causes the file or directory to exist in the filesystem.
+      void create( bool create_parents = false );
+
+      void create_directory( void );
+      void create_directories( void );
+      void create_file( void );
+
+      /// Directories must be empty before they can be removed. If not,
+      /// an error will result. Files will be unlinked, even if another
+      /// process is using them.
+      /// @brief Removes the file or directory from the filesystem.
+      void remove( void );
+      void remove_directory( void );
+      void remove_file( void ); 
+
+      /// Find library.
+      void find_lib( const char * file );
+  /// @}
+  };
+}
+}
+
+// vim: sw=2
+
+#endif
diff --git a/lib/System/Linux/Path.cpp b/lib/System/Linux/Path.cpp
new file mode 100644 (file)
index 0000000..5c73d01
--- /dev/null
@@ -0,0 +1,20 @@
+//===- llvm/System/Linux/Path.cpp - Linux Path Implementation ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Linux specific implementation of the Path class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Linux specific code 
+//===          and must not be generic UNIX code (see ../Unix)
+//===----------------------------------------------------------------------===//
+
+// Th..Th..Th..Tha's All Folks!
+#include "../Unix/Path.cpp"
diff --git a/lib/System/Makefile b/lib/System/Makefile
new file mode 100644 (file)
index 0000000..b4493ec
--- /dev/null
@@ -0,0 +1,13 @@
+##===- lib/Bytecode/Reader/Makefile ------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+LIBRARYNAME = system
+BUILD_ARCHIVE = 1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/System/Path.cpp b/lib/System/Path.cpp
new file mode 100644 (file)
index 0000000..e32842d
--- /dev/null
@@ -0,0 +1,60 @@
+//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+//  This header file implements the operating system Path concept.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/System/Path.h"
+
+namespace llvm {
+namespace sys {
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//===          independent code. 
+//===----------------------------------------------------------------------===//
+
+bool
+Path::is_valid() const {
+  if ( empty() ) return false;
+  return true;
+}
+
+void 
+Path::fill( char* buffer, unsigned bufflen ) const {
+  unsigned pathlen = length();
+  assert( bufflen > pathlen && "Insufficient buffer size" );
+  unsigned copylen = pathlen <? (bufflen - 1);
+  this->copy(buffer, copylen, 0 );
+  buffer[ copylen ] = 0;
+}
+
+void
+Path::make_directory() {
+  char end[2];
+  end[0] = '/';
+  end[1] = 0;
+  if ( empty() )
+    this->assign( end );
+  else if ( (*this)[length()-1] != '/')
+    this->append( end );
+}
+
+void
+Path::make_file() {
+  if ( (*this)[length()-1] == '/')
+    this->erase( this->length()-1, 1 );
+}
+
+// Include the truly platform-specific parts of this class.
+#include "platform/Path.cpp"
+}
+}
+
+// vim: sw=2
diff --git a/lib/System/Unix/Path.cpp b/lib/System/Unix/Path.cpp
new file mode 100644 (file)
index 0000000..9253f8c
--- /dev/null
@@ -0,0 +1,138 @@
+//===- llvm/System/Unix/Path.cpp - Unix Path Implementation -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Path class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on all UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+
+bool
+Path::is_file() const {
+  if (!empty() && ((*this)[length()-1] !=  '/'))
+    return true;
+  return false;
+}
+
+bool
+Path::is_directory() const {
+  if ((!empty()) && ((*this)[length()-1] ==  '/'))
+    return true;
+  return false;
+}
+
+void
+Path::create( bool create_parents) {
+  if ( is_directory() ) {
+    if ( create_parents )
+      this->create_directories( );
+    this->create_directory( );
+  } else if ( is_file() ) {
+    if ( create_parents )
+      this->create_directories( );
+    this->create_file( );
+  }
+}
+
+void
+Path::remove() {
+  if ( is_directory() ) {
+    if ( exists() )
+      this->remove_directory( );
+  } else if ( is_file() )
+    if ( exists() ) 
+      this->remove_file( );
+}
+
+bool
+Path::exists() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  return 0 == access(pathname, F_OK );
+}
+
+void
+Path::create_directory( ) {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if (0 != mkdir(pathname, S_IRWXU | S_IRWXG))
+    ThrowErrno(pathname);
+}
+
+void
+Path::create_directories() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+
+  char * next = index(pathname,'/');
+  if ( pathname[0] == '/') 
+    next = index(&pathname[1],'/');
+  while ( next != 0 )
+  {
+    *next = 0;
+    if (0 != access(pathname, F_OK | R_OK))
+      if (0 != mkdir(pathname, S_IRWXU | S_IRWXG))
+        ThrowErrno(pathname);
+    char* save = next;
+    next = index(pathname,'/');
+    *save = '/';
+  }
+}
+
+void
+Path::remove_directory()
+{
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if ( 0 != rmdir(pathname))
+    ThrowErrno(pathname);
+}
+
+void
+Path::create_file() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if (0 != creat(pathname, S_IRUSR | S_IWUSR))
+    ThrowErrno(pathname);
+}
+
+void
+Path::remove_file() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if (0 != unlink(pathname))
+    ThrowErrno(pathname);
+}
+
+// vim: sw=2
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc
new file mode 100644 (file)
index 0000000..9253f8c
--- /dev/null
@@ -0,0 +1,138 @@
+//===- llvm/System/Unix/Path.cpp - Unix Path Implementation -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Path class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on all UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+
+bool
+Path::is_file() const {
+  if (!empty() && ((*this)[length()-1] !=  '/'))
+    return true;
+  return false;
+}
+
+bool
+Path::is_directory() const {
+  if ((!empty()) && ((*this)[length()-1] ==  '/'))
+    return true;
+  return false;
+}
+
+void
+Path::create( bool create_parents) {
+  if ( is_directory() ) {
+    if ( create_parents )
+      this->create_directories( );
+    this->create_directory( );
+  } else if ( is_file() ) {
+    if ( create_parents )
+      this->create_directories( );
+    this->create_file( );
+  }
+}
+
+void
+Path::remove() {
+  if ( is_directory() ) {
+    if ( exists() )
+      this->remove_directory( );
+  } else if ( is_file() )
+    if ( exists() ) 
+      this->remove_file( );
+}
+
+bool
+Path::exists() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  return 0 == access(pathname, F_OK );
+}
+
+void
+Path::create_directory( ) {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if (0 != mkdir(pathname, S_IRWXU | S_IRWXG))
+    ThrowErrno(pathname);
+}
+
+void
+Path::create_directories() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+
+  char * next = index(pathname,'/');
+  if ( pathname[0] == '/') 
+    next = index(&pathname[1],'/');
+  while ( next != 0 )
+  {
+    *next = 0;
+    if (0 != access(pathname, F_OK | R_OK))
+      if (0 != mkdir(pathname, S_IRWXU | S_IRWXG))
+        ThrowErrno(pathname);
+    char* save = next;
+    next = index(pathname,'/');
+    *save = '/';
+  }
+}
+
+void
+Path::remove_directory()
+{
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if ( 0 != rmdir(pathname))
+    ThrowErrno(pathname);
+}
+
+void
+Path::create_file() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if (0 != creat(pathname, S_IRUSR | S_IWUSR))
+    ThrowErrno(pathname);
+}
+
+void
+Path::remove_file() {
+  char pathname[MAXPATHLEN];
+  this->fill(pathname,MAXPATHLEN);
+  int lastchar = this->length() - 1 ; 
+  if (pathname[lastchar] == '/') 
+    pathname[lastchar] = 0;
+  if (0 != unlink(pathname))
+    ThrowErrno(pathname);
+}
+
+// vim: sw=2
diff --git a/lib/System/Unix/Unix.h b/lib/System/Unix/Unix.h
new file mode 100644 (file)
index 0000000..83d2865
--- /dev/null
@@ -0,0 +1,34 @@
+//===- llvm/System/Unix/Unix.h - Common Unix Include File -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file defines things specific to Unix implementations.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on all UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+
+inline void ThrowErrno(const std::string& prefix) {
+#if defined __USE_XOPEN2K || defined __USE_MISC
+    char buffer[MAXPATHLEN];
+    strerror_r(errno,buffer, MAXPATHLEN);
+    throw prefix + ": " + buffer;
+#else
+    throw prefix + ": " + strerror(errno);
+#endif
+}