mirror of
https://github.com/denoland/deno.git
synced 2024-11-26 16:09:27 -05:00
libdeno: add file utilities Dirname() and ExePath()
This commit is contained in:
parent
ddddd50540
commit
26707446fc
3 changed files with 88 additions and 2 deletions
|
@ -1,10 +1,21 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "file_util.h"
|
#include "file_util.h"
|
||||||
|
|
||||||
namespace deno {
|
namespace deno {
|
||||||
|
@ -28,4 +39,52 @@ std::string Basename(std::string const& filename) {
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the directory component from a filename. The returned path always
|
||||||
|
// ends with a slash. This function does not understand Windows drive letters.
|
||||||
|
std::string Dirname(std::string const& filename) {
|
||||||
|
for (auto it = filename.rbegin(); it != filename.rend(); ++it) {
|
||||||
|
char ch = *it;
|
||||||
|
if (ch == '\\' || ch == '/') {
|
||||||
|
return std::string(filename.begin(), it.base());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::string("./");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the full path the currently running executable.
|
||||||
|
// This implementation is very basic. Caveats:
|
||||||
|
// * OS X: fails if buffer is too small, does not retry with a bigger buffer.
|
||||||
|
// * Windows: ANSI only, no unicode. Fails if path is longer than 260 chars.
|
||||||
|
bool ExePath(std::string* path) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Windows only.
|
||||||
|
char exe_buf[MAX_PATH];
|
||||||
|
DWORD len = GetModuleFileNameA(NULL, exe_buf, sizeof exe_buf);
|
||||||
|
if (len == 0 || len == sizeof exe_buf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// OS X only.
|
||||||
|
char link_buf[PATH_MAX * 2]; // Exe may be longer than MAX_PATH, says Apple.
|
||||||
|
uint32_t len = sizeof link_buf;
|
||||||
|
if (_NSGetExecutablePath(link_buf, &len) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Linux only.
|
||||||
|
static const char* link_buf = "/proc/self/exe";
|
||||||
|
#endif
|
||||||
|
// Linux and OS X.
|
||||||
|
char exe_buf[PATH_MAX];
|
||||||
|
char* r = realpath(link_buf, exe_buf);
|
||||||
|
if (r == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// All platforms.
|
||||||
|
path->assign(exe_buf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace deno
|
} // namespace deno
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
namespace deno {
|
namespace deno {
|
||||||
bool ReadFileToString(const char* fn, std::string* contents);
|
bool ReadFileToString(const char* fn, std::string* contents);
|
||||||
std::string Basename(std::string const& filename);
|
std::string Basename(std::string const& filename);
|
||||||
|
std::string Dirname(std::string const& filename);
|
||||||
|
bool ExePath(std::string* path);
|
||||||
} // namespace deno
|
} // namespace deno
|
||||||
|
|
||||||
#endif // FILE_UTIL_H_
|
#endif // FILE_UTIL_H_
|
||||||
|
|
|
@ -11,11 +11,36 @@ TEST(FileUtilTest, ReadFileToStringFileNotExist) {
|
||||||
TEST(FileUtilTest, Basename) {
|
TEST(FileUtilTest, Basename) {
|
||||||
EXPECT_EQ("foo.txt", deno::Basename("foo.txt"));
|
EXPECT_EQ("foo.txt", deno::Basename("foo.txt"));
|
||||||
EXPECT_EQ("foo.txt", deno::Basename("/foo.txt"));
|
EXPECT_EQ("foo.txt", deno::Basename("/foo.txt"));
|
||||||
|
EXPECT_EQ("", deno::Basename("/foo/"));
|
||||||
|
EXPECT_EQ("", deno::Basename("foo/"));
|
||||||
EXPECT_EQ("", deno::Basename("/"));
|
EXPECT_EQ("", deno::Basename("/"));
|
||||||
EXPECT_EQ("foo.txt", deno::Basename(".\\foo.txt"));
|
EXPECT_EQ("foo.txt", deno::Basename(".\\foo.txt"));
|
||||||
EXPECT_EQ("foo.txt", deno::Basename("/home/ryan/foo.txt"));
|
EXPECT_EQ("foo.txt", deno::Basename("/home/ryan/foo.txt"));
|
||||||
EXPECT_EQ("foo.txt", deno::Basename("C:\\home\\ryan\\foo.txt"));
|
EXPECT_EQ("foo.txt", deno::Basename("C:\\home\\ryan\\foo.txt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ry) success unit test. Needs a tempfile or fixture.
|
TEST(FileUtilTest, Dirname) {
|
||||||
// TEST(FileUtilTest, ReadFileToStringSuccess) { }
|
EXPECT_EQ("home/dank/", deno::Dirname("home/dank/memes.gif"));
|
||||||
|
EXPECT_EQ("/home/dank/", deno::Dirname("/home/dank/memes.gif"));
|
||||||
|
EXPECT_EQ("/home/dank/", deno::Dirname("/home/dank/"));
|
||||||
|
EXPECT_EQ("home/dank/", deno::Dirname("home/dank/memes.gif"));
|
||||||
|
EXPECT_EQ("/", deno::Dirname("/"));
|
||||||
|
EXPECT_EQ(".\\", deno::Dirname(".\\memes.gif"));
|
||||||
|
EXPECT_EQ("c:\\", deno::Dirname("c:\\stuff"));
|
||||||
|
EXPECT_EQ("./", deno::Dirname("nothing"));
|
||||||
|
EXPECT_EQ("./", deno::Dirname(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FileUtilTest, ExePath) {
|
||||||
|
std::string exe_path;
|
||||||
|
EXPECT_TRUE(deno::ExePath(&exe_path));
|
||||||
|
// Path is absolute.
|
||||||
|
EXPECT_TRUE(exe_path.find("/") == 0 || exe_path.find(":\\") == 1);
|
||||||
|
// FIlename is the name of the test binary.
|
||||||
|
std::string exe_filename = deno::Basename(exe_path);
|
||||||
|
EXPECT_EQ(exe_filename.find("test_cc"), 0);
|
||||||
|
// Path exists (also tests ReadFileToString).
|
||||||
|
std::string contents;
|
||||||
|
EXPECT_TRUE(deno::ReadFileToString(exe_path.c_str(), &contents));
|
||||||
|
EXPECT_NE(contents.find("Inception :)"), std::string::npos);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue