Skip to content

Commit

Permalink
Update.
Browse files Browse the repository at this point in the history
  • Loading branch information
egorpugin committed Feb 21, 2024
1 parent 0478d92 commit b362215
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 255 deletions.
240 changes: 3 additions & 237 deletions src/sw/helpers/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#pragma once

#include "../sys/string.h"

#include "../sys/fs2.h"
#include "../crypto/common.h"

#include <algorithm>
Expand Down Expand Up @@ -62,37 +65,12 @@ using fmt::format;
#error "compiler is not working or not tested"
#endif

namespace sw {

namespace fs = std::filesystem;
using path = fs::path;

} // namespace sw

template <>
struct fmt::formatter<std::source_location> : formatter<std::string> {
auto format(const std::source_location &p, format_context &ctx) const {
return fmt::formatter<std::string>::format(fmt::format("{}:{}", p.file_name(), p.line()), ctx);
}
};
template <>
struct fmt::formatter<sw::path> : formatter<std::string> {
auto format(const sw::path &p, format_context &ctx) const {
return fmt::formatter<std::string>::format(p.string(), ctx);
}
};

//#define SW_BINARY_DIR ".sw"

namespace sw {

namespace fs = std::filesystem;
using path = fs::path;
using std::string;
using std::string_view;
using std::variant;
using std::vector;
using namespace std::literals;

template <typename ... Types>
using uptr = std::unique_ptr<Types...>;
Expand Down Expand Up @@ -173,99 +151,6 @@ static constexpr bool contains(Container<Types...> **) {
return contains<T, Types...>();
}

[[nodiscard]]
inline std::string replace(const std::string &str, const std::string &oldstr, const std::string &newstr,
int count = -1) {
int sofar = 0;
int cursor = 0;
string s(str);
string::size_type oldlen = oldstr.size(), newlen = newstr.size();
cursor = s.find(oldstr, cursor);
while (cursor != -1 && cursor <= (int)s.size()) {
if (count > -1 && sofar >= count) {
break;
}
s.replace(cursor, oldlen, newstr);
cursor += (int)newlen;
if (oldlen != 0) {
cursor = s.find(oldstr, cursor);
} else {
++cursor;
}
++sofar;
}
return s;
}

struct abspath : path {
using base = path;

abspath() = default;
abspath(const base &p) : base{p} {
init();
}
abspath(auto &&p) : base{p} {
init();
}
abspath(const abspath &) = default;

void init() {
// we need target os concept and do this when needed
/*#ifdef _WIN32
std::wstring s = fs::absolute(p);
std::transform(s.begin(), s.end(), s.begin(), towlower);
base::operator=(s);
#else*/
base::operator=(fs::absolute(*this));
base::operator=(fs::absolute(*this).lexically_normal()); // on linux absolute does not remove last '.'?
//#endif
}
};

struct unimplemented_exception : std::runtime_error {
unimplemented_exception(std::source_location sl = std::source_location::current())
: runtime_error{format("unimplemented: {}", sl)} {}
};
#define SW_UNIMPLEMENTED throw unimplemented_exception{}

string &&normalize_path(string &&s) {
std::replace(s.begin(), s.end(), '\\', '/');
return std::move(s);
}
void lower_drive_letter(string &s) {
if (!s.empty()) {
s[0] = tolower(s[0]);
}
}
void mingw_drive_letter(string &s) {
if (s.size() > 1 && s[1] == ':') {
s[0] = tolower(s[0]);
s = "/"s + s[0] + s.substr(2);
}
}
auto normalize_path(const path &p) {
auto fn = p.string();
std::replace(fn.begin(), fn.end(), '\\', '/');
return fn;
}
auto normalize_path_and_drive(const path &p) {
auto fn = normalize_path(p);
lower_drive_letter(fn);
return fn;
}

template<std::size_t N>
struct static_string {
char p[N]{};
constexpr static_string(char const(&pp)[N]) {
std::ranges::copy(pp, p);
}
operator auto() const { return &p[0]; }
operator string_view() const { return string_view{p, N-1}; }
};
template<static_string s>
constexpr auto operator""_s() { return s; }

static bool is_mingw_shell() {
static auto b = getenv("MSYSTEM");
return b;
Expand Down Expand Up @@ -299,30 +184,6 @@ struct swap_and_restore {
swap_and_restore &operator=(const swap_and_restore &) = delete;
};

auto read_file(const path &fn) {
auto sz = fs::file_size(fn);
string s(sz, 0);
FILE *f = fopen(fn.string().c_str(), "rb");
fread(s.data(), s.size(), 1, f);
fclose(f);
return s;
}

void write_file(const path &fn, const string &s = {}) {
fs::create_directories(fn.parent_path());

FILE *f = fopen(fn.string().c_str(), "wb");
fwrite(s.data(), s.size(), 1, f);
fclose(f);
}

void write_file_if_different(const path &fn, const string &s) {
if (fs::exists(fn) && read_file(fn) == s) {
return;
}
write_file(fn, s);
}

size_t fnv1a(auto &&in) {
auto hash = 0xcbf29ce484222325ULL;
for (auto &&byte : in) {
Expand All @@ -345,106 +206,11 @@ inline size_t hash_combine(size_t &seed, const T &v) {
return std::rotl(seed, std::numeric_limits<size_t>::digits / 3) ^ distribute(std::hash<T>{}(v));
}

string to_upper_copy(string in) {
std::transform(in.begin(), in.end(), in.begin(), ::toupper);
return std::move(in);
}

void write_file_once(const path &fn, const string &content, const path &lock_dir) {
auto sha3 = [](auto &&d) {
return digest<crypto::sha3<256>>(d);
};

auto h = sha3(content);

auto hf = sha3(normalize_path(fn));
const auto once = lock_dir / (hf + ".once");
const auto lock = lock_dir / hf;

if (!fs::exists(once) || h != read_file(once) || !fs::exists(fn)) {
//ScopedFileLock fl(lock);
write_file_if_different(fn, content);
write_file_if_different(once, h);
}
}

path resolve_executable(auto &&exe) {
#ifdef _WIN32
auto p = getenv("Path");
auto delim = ';';
auto exts = {".exe", ".bat", ".cmd", ".com"};
#else
auto p = getenv("PATH");
auto delim = ':';
auto exts = {""};
#endif
if (!p) {
return {};
}
string p2 = p;
for (const auto word : std::views::split(p2, delim) | std::views::transform([](auto &&word) {
return std::string_view{word.begin(), word.end()};
})) {
auto p = path{word} / exe;
for (auto &e : exts) {
if (fs::exists(path{p} += e)) {
return path{p} += e;
}
}
}
return {};
}

void append_vector(auto &&to, auto &&from) {
to.reserve(to.size() + from.size());
for (auto &&v : from) {
to.push_back(v);
}
}

inline auto is_c_file(const path &fn) {
static std::set<string> exts{".c", ".m"}; // with obj-c, separate call?
return exts.contains(fn.extension().string());
}
inline auto is_cpp_file(const path &fn) {
static std::set<string> exts{".cpp", ".cxx", ".mm"}; // with obj-c++, separate call?
return exts.contains(fn.extension().string());
}

inline path get_home_directory() {
#ifdef _WIN32
wchar_t *w;
size_t len;
auto err = _wdupenv_s(&w, &len, L"USERPROFILE");
if (err) {
std::cerr << "Cannot get user's home directory (%USERPROFILE%)\n";
return "";
}
path home = w;
free(w);
#else
// prefer this way
auto p = getpwuid(getuid());
if (p)
return p->pw_dir;
auto home = getenv("HOME");
if (!home)
std::cerr << "Cannot get user's home directory ($HOME)\n";
if (home == nullptr)
return "";
#endif
return home;
}

inline path temp_sw_directory_path() {
return fs::temp_directory_path() / "sw";
}

} // namespace sw

template <>
struct std::hash<::sw::abspath> {
size_t operator()(const ::sw::abspath &p) {
return std::hash<sw::path>()(p);
}
};
4 changes: 2 additions & 2 deletions src/sw/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace sw {
struct solution;

struct entry_point {
std::function<void(solution &)> f;
std::function<void(solution &)> build;
path source_dir;
path binary_dir;

Expand All @@ -24,7 +24,7 @@ struct entry_point {
sln.binary_dir = binary_dir;
}
swap_and_restore sr3{sln.bs, &bs};
f(sln);
build(sln);
}
};

Expand Down
27 changes: 22 additions & 5 deletions src/sw/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void sw1(auto &cl) {
swap_and_restore sr{s.dry_run, true};
for (auto &&ep : entry_points) {
input_with_settings is;
is.ep = entry_point{ep.f, ep.source_dir};
is.ep = entry_point{ep.build, ep.source_dir};
is.settings.insert(settings.begin(), settings.end());
s.gather_entry_points(is);
}
Expand All @@ -192,7 +192,7 @@ void sw1(auto &cl) {
auto settings = make_settings(b);
for (auto &&ep : entry_points) {
input_with_settings is;
is.ep = entry_point{ep.f, ep.source_dir};
is.ep = entry_point{ep.build, ep.source_dir};
is.settings.insert(settings.begin(), settings.end());
s.add_input(is);
}
Expand Down Expand Up @@ -370,8 +370,21 @@ namespace sw {
// sw_context?
// sw_command_runner?
struct sw_tool {
path config_dir;
path storage_dir;
repository repo;

sw_tool() {
config_dir = get_home_directory() / ".sw2";
#ifndef BUILTIN_STORAGE_DIR
#endif
auto storfn = config_dir / "storage_dir";
if (!fs::exists(storfn)) {
write_file(storfn, (const char *)(config_dir / "storage").u8string().c_str());
}
storage_dir = (const char8_t *)read_file(config_dir / "storage_dir").c_str();
repo.init(storage_dir);
}
int run_command_line(int argc, char *argv[]) {
return run_command_line(std::span<char *>{argv, argv+argc});
}
Expand Down Expand Up @@ -497,7 +510,7 @@ int main2(int argc, char *argv[]) {
write_file_if_different(pch, e.s);
pch_ep.source_dir = pch_tmp;
pch_ep.binary_dir = pch_tmp;
pch_ep.f = [pch](solution &s) {
pch_ep.build = [pch](solution &s) {
auto &t = s.add<native_target>("sw_pch");
t += precompiled_header{pch};
#ifdef __APPLE__
Expand Down Expand Up @@ -553,7 +566,9 @@ int main2(int argc, char *argv[]) {
e += "}";
write_file_if_different(fn, e.s);

input_with_settings is{entry_point{&self_build::build, cfg_dir}};
input_with_settings is;
is.ep.build = [](auto &&s){ self_build::sw_build b; b.build(s); };
is.ep.source_dir = cfg_dir;
auto dbs = default_build_settings();
dbs.build_type = build_type::debug{};
is.settings.insert(dbs);
Expand Down Expand Up @@ -658,7 +673,9 @@ using namespace fs;
t += "sw.lib"_dep;
}
};
input_with_settings is{entry_point{&self_build::build, get_sw_dir()}};
input_with_settings is;
is.ep.build = [](auto &&s){ self_build::sw_build b; b.build(s); };
is.ep.source_dir = get_sw_dir();
auto settings = make_settings(b);
is.settings.insert(settings.begin(), settings.end());
sln.add_input(is);
Expand Down
Loading

0 comments on commit b362215

Please sign in to comment.