From: Reid Spencer Date: Wed, 25 Aug 2004 06:20:07 +0000 (+0000) Subject: Initial implementation of the Path operating system concept. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=b89a2237ea79e0576fdb426b124f1940f53da159 Initial implementation of the Path operating system concept. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16048 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/System/LICENSE.TXT b/include/llvm/System/LICENSE.TXT new file mode 100644 index 00000000000..f569da20528 --- /dev/null +++ b/include/llvm/System/LICENSE.TXT @@ -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 index 00000000000..df699a3584e --- /dev/null +++ b/include/llvm/System/Path.h @@ -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 + +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 index 00000000000..5c73d0176a1 --- /dev/null +++ b/lib/System/Linux/Path.cpp @@ -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 index 00000000000..b4493ecf0a1 --- /dev/null +++ b/lib/System/Makefile @@ -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 index 00000000000..e32842dd188 --- /dev/null +++ b/lib/System/Path.cpp @@ -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 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 index 00000000000..9253f8c9f75 --- /dev/null +++ b/lib/System/Unix/Path.cpp @@ -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 +#include + +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 index 00000000000..9253f8c9f75 --- /dev/null +++ b/lib/System/Unix/Path.inc @@ -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 +#include + +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 index 00000000000..83d2865a11f --- /dev/null +++ b/lib/System/Unix/Unix.h @@ -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 +#include +#include +#include +#include +#include + +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 +}