#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#if HAVE_UTIME_H
#include <utime.h>
#endif
extern const char sys::PathSeparator = ':';
+Path::Path(const std::string& p)
+ : path(p) {}
+
+Path::Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrLen) {}
+
bool
Path::isValid() const {
// Check some obvious things
}
+std::string Path::getDirname() const {
+ return getDirnameCharSep(path, '/');
+}
+
std::string
Path::getBasename() const {
// Find the last slash
- size_t slash = path.rfind('/');
+ std::string::size_type slash = path.rfind('/');
if (slash == std::string::npos)
slash = 0;
else
slash++;
- size_t dot = path.rfind('.');
+ std::string::size_type dot = path.rfind('.');
if (dot == std::string::npos || dot < slash)
return path.substr(slash);
else
return path.substr(slash, dot - slash);
}
+std::string
+Path::getSuffix() const {
+ // Find the last slash
+ std::string::size_type slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ std::string::size_type dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return std::string();
+ else
+ return path.substr(dot + 1);
+}
+
bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
assert(len < 1024 && "Request for magic string too long");
char* buf = (char*) alloca(1 + len);
return false;
}
+static bool createDirectoryHelper(char* beg, char* end, bool create_parents) {
+
+ if (access(beg, F_OK | R_OK | W_OK) == 0)
+ return false;
+
+ if (create_parents) {
+
+ char* c = end;
+
+ for (; c != beg; --c)
+ if (*c == '/') {
+
+ // Recurse to handling the parent directory.
+ *c = '\0';
+ bool x = createDirectoryHelper(beg, c, create_parents);
+ *c = '/';
+
+ // Return if we encountered an error.
+ if (x)
+ return true;
+
+ break;
+ }
+ }
+
+ return mkdir(beg, S_IRWXU | S_IRWXG) != 0;
+}
+
bool
Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) {
// Get a writeable copy of the path name
path.copy(pathname,MAXPATHLEN);
// Null-terminate the last component
- int lastchar = path.length() - 1 ;
- if (pathname[lastchar] == '/')
- pathname[lastchar] = 0;
- else
- pathname[lastchar+1] = 0;
-
- // If we're supposed to create intermediate directories
- if ( create_parents ) {
- // Find the end of the initial name component
- char * next = strchr(pathname,'/');
- if ( pathname[0] == '/')
- next = strchr(&pathname[1],'/');
-
- // Loop through the directory components until we're done
- while ( next != 0 ) {
- *next = 0;
- if (0 != access(pathname, F_OK | R_OK | W_OK))
- if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) {
- return MakeErrMsg(ErrMsg,
- std::string(pathname) + ": can't create directory");
- }
- char* save = next;
- next = strchr(next+1,'/');
- *save = '/';
- }
- }
-
- if (0 != access(pathname, F_OK | R_OK))
- if (0 != mkdir(pathname, S_IRWXU | S_IRWXG)) {
- return MakeErrMsg(ErrMsg,
- std::string(pathname) + ": can't create directory");
- }
+ size_t lastchar = path.length() - 1 ;
+
+ if (pathname[lastchar] != '/')
+ ++lastchar;
+
+ pathname[lastchar] = 0;
+
+ if (createDirectoryHelper(pathname, pathname+lastchar, create_parents))
+ return MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": can't create directory");
+
return false;
}
// Otherwise, try to just remove the one directory.
char pathname[MAXPATHLEN];
path.copy(pathname, MAXPATHLEN);
- int lastchar = path.length() - 1 ;
+ size_t lastchar = path.length() - 1;
if (pathname[lastchar] == '/')
pathname[lastchar] = 0;
else
return false;
}
-/// MapInFilePages - Not yet implemented on win32.
const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
- return 0;
+ int Flags = MAP_PRIVATE;
+#ifdef MAP_FILE
+ Flags |= MAP_FILE;
+#endif
+ void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, 0);
+ if (BasePtr == MAP_FAILED)
+ return 0;
+ return (const char*)BasePtr;
}
-/// MapInFilePages - Not yet implemented on win32.
-void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
- assert(0 && "NOT IMPLEMENTED");
+void Path::UnMapFilePages(const char *BasePtr, uint64_t FileSize) {
+ ::munmap((void*)BasePtr, FileSize);
}
} // end llvm namespace