forked from OctaForge/OctaBuild
style updates
parent
aee15f8515
commit
a36e9d021a
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
OB_CXXFLAGS = -g -Wall -Wextra -Wshadow -O2
|
OB_CXXFLAGS = -g -Wall -Wextra -Wshadow -Wold-style-cast -O2
|
||||||
|
|
||||||
CUBESCRIPT_PATH = ../libcubescript
|
CUBESCRIPT_PATH = ../libcubescript
|
||||||
OCTASTD_PATH = ../octastd
|
OCTASTD_PATH = ../octastd
|
||||||
|
|
74
globs.cc
74
globs.cc
|
@ -11,46 +11,55 @@ using ostd::Vector;
|
||||||
using ostd::String;
|
using ostd::String;
|
||||||
using ostd::slice_until;
|
using ostd::slice_until;
|
||||||
|
|
||||||
static void ob_get_path_parts(Vector<ConstCharRange> &parts,
|
static void ob_get_path_parts(
|
||||||
ConstCharRange elem) {
|
Vector<ConstCharRange> &parts, ConstCharRange elem
|
||||||
|
) {
|
||||||
ConstCharRange star = ostd::find(elem, '*');
|
ConstCharRange star = ostd::find(elem, '*');
|
||||||
while (!star.empty()) {
|
while (!star.empty()) {
|
||||||
ConstCharRange ep = slice_until(elem, star);
|
ConstCharRange ep = slice_until(elem, star);
|
||||||
if (!ep.empty())
|
if (!ep.empty()) {
|
||||||
parts.push(ep);
|
parts.push(ep);
|
||||||
|
}
|
||||||
parts.push("*");
|
parts.push("*");
|
||||||
elem = star;
|
elem = star;
|
||||||
++elem;
|
++elem;
|
||||||
star = ostd::find(elem, '*');
|
star = ostd::find(elem, '*');
|
||||||
}
|
}
|
||||||
if (!elem.empty())
|
if (!elem.empty()) {
|
||||||
parts.push(elem);
|
parts.push(elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ob_path_matches(ConstCharRange fn,
|
static bool ob_path_matches(
|
||||||
const Vector<ConstCharRange> &parts) {
|
ConstCharRange fn, Vector<ConstCharRange> const &parts
|
||||||
|
) {
|
||||||
for (auto it = parts.iter(); !it.empty(); ++it) {
|
for (auto it = parts.iter(); !it.empty(); ++it) {
|
||||||
ConstCharRange elem = it.front();
|
ConstCharRange elem = it.front();
|
||||||
if (elem == "*") {
|
if (elem == "*") {
|
||||||
++it;
|
++it;
|
||||||
/* skip multiple stars if present */
|
/* skip multiple stars if present */
|
||||||
while (!it.empty() && ((elem = it.front()) == "*"))
|
while (!it.empty() && ((elem = it.front()) == "*")) {
|
||||||
++it;
|
++it;
|
||||||
|
}
|
||||||
/* trailing stars, we match */
|
/* trailing stars, we match */
|
||||||
if (it.empty())
|
if (it.empty()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
/* skip about as much as we can until the elem part matches */
|
/* skip about as much as we can until the elem part matches */
|
||||||
while (fn.size() > elem.size()) {
|
while (fn.size() > elem.size()) {
|
||||||
if (fn.slice(0, elem.size()) == elem)
|
if (fn.slice(0, elem.size()) == elem) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
++fn;
|
++fn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* non-star here */
|
/* non-star here */
|
||||||
if (fn.size() < elem.size())
|
if (fn.size() < elem.size()) {
|
||||||
return false;
|
return false;
|
||||||
if (fn.slice(0, elem.size()) != elem)
|
}
|
||||||
|
if (fn.slice(0, elem.size()) != elem) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
fn += elem.size();
|
fn += elem.size();
|
||||||
}
|
}
|
||||||
/* if there are no chars in the fname remaining, we fully matched */
|
/* if there are no chars in the fname remaining, we fully matched */
|
||||||
|
@ -59,18 +68,21 @@ static bool ob_path_matches(ConstCharRange fn,
|
||||||
|
|
||||||
static bool ob_expand_glob(String &ret, ConstCharRange src, bool ne = false);
|
static bool ob_expand_glob(String &ret, ConstCharRange src, bool ne = false);
|
||||||
|
|
||||||
static bool ob_expand_dir(String &ret, ConstCharRange dir,
|
static bool ob_expand_dir(
|
||||||
const Vector<ConstCharRange> &parts,
|
String &ret, ConstCharRange dir, Vector<ConstCharRange> const &parts,
|
||||||
ConstCharRange slash) {
|
ConstCharRange slash
|
||||||
|
) {
|
||||||
ostd::DirectoryStream d(dir);
|
ostd::DirectoryStream d(dir);
|
||||||
bool appended = false;
|
bool appended = false;
|
||||||
if (!d.is_open())
|
if (!d.is_open()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
for (auto fi: d.iter()) {
|
for (auto fi: d.iter()) {
|
||||||
ConstCharRange fn = fi.filename();
|
ConstCharRange fn = fi.filename();
|
||||||
/* check if filename matches */
|
/* check if filename matches */
|
||||||
if (!ob_path_matches(fn, parts))
|
if (!ob_path_matches(fn, parts)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
String afn((dir == ".") ? "" : "./");
|
String afn((dir == ".") ? "" : "./");
|
||||||
afn.append(fn);
|
afn.append(fn);
|
||||||
/* if we reach this, we match; try recursively matching */
|
/* if we reach this, we match; try recursively matching */
|
||||||
|
@ -78,21 +90,25 @@ static bool ob_expand_dir(String &ret, ConstCharRange dir,
|
||||||
afn.append(slash);
|
afn.append(slash);
|
||||||
ConstCharRange psl = slash + 1;
|
ConstCharRange psl = slash + 1;
|
||||||
if (!ostd::find(psl, '*').empty()) {
|
if (!ostd::find(psl, '*').empty()) {
|
||||||
if (!appended)
|
if (!appended) {
|
||||||
appended = ob_expand_glob(ret, afn.iter());
|
appended = ob_expand_glob(ret, afn.iter());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* no further star, just do file test */
|
/* no further star, just do file test */
|
||||||
if (!ostd::FileStream(afn, ostd::StreamMode::read).is_open())
|
if (!ostd::FileStream(afn, ostd::StreamMode::read).is_open()) {
|
||||||
continue;
|
continue;
|
||||||
if (!ret.empty())
|
}
|
||||||
|
if (!ret.empty()) {
|
||||||
ret.push(' ');
|
ret.push(' ');
|
||||||
|
}
|
||||||
ret.append(afn);
|
ret.append(afn);
|
||||||
appended = true;
|
appended = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!ret.empty())
|
if (!ret.empty()) {
|
||||||
ret.push(' ');
|
ret.push(' ');
|
||||||
|
}
|
||||||
ret.append(afn);
|
ret.append(afn);
|
||||||
appended = true;
|
appended = true;
|
||||||
}
|
}
|
||||||
|
@ -104,8 +120,9 @@ static bool ob_expand_glob(String &ret, ConstCharRange src, bool ne) {
|
||||||
/* no star use as-is */
|
/* no star use as-is */
|
||||||
if (star.empty()) {
|
if (star.empty()) {
|
||||||
if (ne) return false;
|
if (ne) return false;
|
||||||
if (!ret.empty())
|
if (!ret.empty()) {
|
||||||
ret.push(' ');
|
ret.push(' ');
|
||||||
|
}
|
||||||
ret.append(src);
|
ret.append(src);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,26 +143,31 @@ static bool ob_expand_glob(String &ret, ConstCharRange src, bool ne) {
|
||||||
ConstCharRange fnpost = star + 1;
|
ConstCharRange fnpost = star + 1;
|
||||||
/* if a slash follows, adjust */
|
/* if a slash follows, adjust */
|
||||||
ConstCharRange nslash = ostd::find(fnpost, '/');
|
ConstCharRange nslash = ostd::find(fnpost, '/');
|
||||||
if (!nslash.empty())
|
if (!nslash.empty()) {
|
||||||
fnpost = slice_until(fnpost, nslash);
|
fnpost = slice_until(fnpost, nslash);
|
||||||
|
}
|
||||||
/* retrieve the single element with whatever stars in it, chop it up */
|
/* retrieve the single element with whatever stars in it, chop it up */
|
||||||
Vector<ConstCharRange> parts;
|
Vector<ConstCharRange> parts;
|
||||||
ob_get_path_parts(parts, ConstCharRange(&fnpre[0], &fnpost[fnpost.size()]));
|
ob_get_path_parts(parts, ConstCharRange(&fnpre[0], &fnpost[fnpost.size()]));
|
||||||
/* do a directory scan and match */
|
/* do a directory scan and match */
|
||||||
if (!ob_expand_dir(ret, dir, parts, nslash)) {
|
if (!ob_expand_dir(ret, dir, parts, nslash)) {
|
||||||
if (ne) return false;
|
if (ne) {
|
||||||
if (!ret.empty())
|
return false;
|
||||||
|
}
|
||||||
|
if (!ret.empty()) {
|
||||||
ret.push(' ');
|
ret.push(' ');
|
||||||
|
}
|
||||||
ret.append(src);
|
ret.append(src);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String ob_expand_globs(const Vector<String> &src) {
|
static String ob_expand_globs(Vector<String> const &src) {
|
||||||
String ret;
|
String ret;
|
||||||
for (auto &s: src.iter())
|
for (auto &s: src.iter()) {
|
||||||
ob_expand_glob(ret, s.iter());
|
ob_expand_glob(ret, s.iter());
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
303
main.cc
303
main.cc
|
@ -39,11 +39,13 @@ struct ThreadPool {
|
||||||
ThreadPool() {}
|
ThreadPool() {}
|
||||||
|
|
||||||
~ThreadPool() {
|
~ThreadPool() {
|
||||||
if (running) destroy();
|
if (running) {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *thr_func(void *ptr) {
|
static void *thr_func(void *ptr) {
|
||||||
((ThreadPool *)ptr)->run();
|
static_cast<ThreadPool *>(ptr)->run();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +53,9 @@ struct ThreadPool {
|
||||||
running = true;
|
running = true;
|
||||||
for (ostd::Size i = 0; i < size; ++i) {
|
for (ostd::Size i = 0; i < size; ++i) {
|
||||||
Thread tid([this]() { run(); });
|
Thread tid([this]() { run(); });
|
||||||
if (!tid)
|
if (!tid) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
thrs.push(ostd::move(tid));
|
thrs.push(ostd::move(tid));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -72,16 +75,18 @@ struct ThreadPool {
|
||||||
void run() {
|
void run() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
UniqueLock<Mutex> l(mtx);
|
UniqueLock<Mutex> l(mtx);
|
||||||
while (running && (tasks == nullptr))
|
while (running && (tasks == nullptr)) {
|
||||||
cond.wait(l);
|
cond.wait(l);
|
||||||
|
}
|
||||||
if (!running) {
|
if (!running) {
|
||||||
l.unlock();
|
l.unlock();
|
||||||
ostd::this_thread::exit();
|
ostd::this_thread::exit();
|
||||||
}
|
}
|
||||||
Task *t = tasks;
|
Task *t = tasks;
|
||||||
tasks = t->next;
|
tasks = t->next;
|
||||||
if (last_task == t)
|
if (last_task == t) {
|
||||||
last_task = nullptr;
|
last_task = nullptr;
|
||||||
|
}
|
||||||
l.unlock();
|
l.unlock();
|
||||||
t->cb();
|
t->cb();
|
||||||
delete t;
|
delete t;
|
||||||
|
@ -91,11 +96,13 @@ struct ThreadPool {
|
||||||
void push(ostd::Function<void()> func) {
|
void push(ostd::Function<void()> func) {
|
||||||
mtx.lock();
|
mtx.lock();
|
||||||
Task *t = new Task(ostd::move(func));
|
Task *t = new Task(ostd::move(func));
|
||||||
if (last_task)
|
if (last_task) {
|
||||||
last_task->next = t;
|
last_task->next = t;
|
||||||
|
}
|
||||||
last_task = t;
|
last_task = t;
|
||||||
if (!tasks)
|
if (!tasks) {
|
||||||
tasks = t;
|
tasks = t;
|
||||||
|
}
|
||||||
cond.signal();
|
cond.signal();
|
||||||
mtx.unlock();
|
mtx.unlock();
|
||||||
}
|
}
|
||||||
|
@ -105,10 +112,10 @@ private:
|
||||||
ostd::Function<void()> cb;
|
ostd::Function<void()> cb;
|
||||||
Task *next = nullptr;
|
Task *next = nullptr;
|
||||||
Task() = delete;
|
Task() = delete;
|
||||||
Task(const Task &) = delete;
|
Task(Task const &) = delete;
|
||||||
Task(Task &&) = delete;
|
Task(Task &&) = delete;
|
||||||
Task(ostd::Function<void()> &&cbf): cb(ostd::move(cbf)) {}
|
Task(ostd::Function<void()> &&cbf): cb(ostd::move(cbf)) {}
|
||||||
Task &operator=(const Task &) = delete;
|
Task &operator=(Task const &) = delete;
|
||||||
Task &operator=(Task &&) = delete;
|
Task &operator=(Task &&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -117,23 +124,28 @@ private:
|
||||||
Vector<Thread> thrs;
|
Vector<Thread> thrs;
|
||||||
Task *tasks;
|
Task *tasks;
|
||||||
Task *last_task;
|
Task *last_task;
|
||||||
volatile bool running;
|
bool volatile running;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* check funcs */
|
/* check funcs */
|
||||||
|
|
||||||
static bool ob_check_ts(ConstCharRange tname, const Vector<String> &deps) {
|
static bool ob_check_ts(ConstCharRange tname, Vector<String> const &deps) {
|
||||||
auto get_ts = [](ConstCharRange fname) {
|
auto get_ts = [](ConstCharRange fname) {
|
||||||
ostd::FileInfo fi(fname);
|
ostd::FileInfo fi(fname);
|
||||||
if (fi.type() != ostd::FileType::regular)
|
if (fi.type() != ostd::FileType::regular) {
|
||||||
return time_t(0);
|
return time_t(0);
|
||||||
|
}
|
||||||
return fi.mtime();
|
return fi.mtime();
|
||||||
};
|
};
|
||||||
time_t tts = get_ts(tname);
|
time_t tts = get_ts(tname);
|
||||||
if (!tts) return true;
|
if (!tts) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
for (auto &dep: deps.iter()) {
|
for (auto &dep: deps.iter()) {
|
||||||
time_t sts = get_ts(dep);
|
time_t sts = get_ts(dep);
|
||||||
if (sts && (tts < sts)) return true;
|
if (sts && (tts < sts)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -142,41 +154,51 @@ static bool ob_check_file(ConstCharRange fname) {
|
||||||
return ostd::FileStream(fname, ostd::StreamMode::read).is_open();
|
return ostd::FileStream(fname, ostd::StreamMode::read).is_open();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ob_check_exec(ConstCharRange tname, const Vector<String> &deps) {
|
static bool ob_check_exec(ConstCharRange tname, Vector<String> const &deps) {
|
||||||
if (!ob_check_file(tname))
|
if (!ob_check_file(tname)) {
|
||||||
return true;
|
return true;
|
||||||
for (auto &dep: deps.iter())
|
}
|
||||||
if (!ob_check_file(dep))
|
for (auto &dep: deps.iter()) {
|
||||||
|
if (!ob_check_file(dep)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ob_check_ts(tname, deps);
|
return ob_check_ts(tname, deps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this lets us properly match % patterns in target names */
|
/* this lets us properly match % patterns in target names */
|
||||||
static ConstCharRange ob_compare_subst(ConstCharRange expanded,
|
static ConstCharRange ob_compare_subst(
|
||||||
ConstCharRange toexpand) {
|
ConstCharRange expanded, ConstCharRange toexpand
|
||||||
|
) {
|
||||||
auto rep = ostd::find(toexpand, '%');
|
auto rep = ostd::find(toexpand, '%');
|
||||||
/* no subst found */
|
/* no subst found */
|
||||||
if (rep.empty())
|
if (rep.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
/* get the part before % */
|
/* get the part before % */
|
||||||
auto fp = slice_until(toexpand, rep);
|
auto fp = slice_until(toexpand, rep);
|
||||||
/* part before % does not compare, so ignore */
|
/* part before % does not compare, so ignore */
|
||||||
if (expanded.size() <= fp.size())
|
if (expanded.size() <= fp.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (expanded.slice(0, fp.size()) != fp)
|
}
|
||||||
|
if (expanded.slice(0, fp.size()) != fp) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
/* pop out front part */
|
/* pop out front part */
|
||||||
expanded += fp.size();
|
expanded += fp.size();
|
||||||
/* part after % */
|
/* part after % */
|
||||||
++rep;
|
++rep;
|
||||||
if (rep.empty())
|
if (rep.empty()) {
|
||||||
return expanded;
|
return expanded;
|
||||||
|
}
|
||||||
/* part after % does not compare, so ignore */
|
/* part after % does not compare, so ignore */
|
||||||
if (expanded.size() <= rep.size())
|
if (expanded.size() <= rep.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
ostd::Size es = expanded.size();
|
ostd::Size es = expanded.size();
|
||||||
if (expanded.slice(es - rep.size(), es) != rep)
|
if (expanded.slice(es - rep.size(), es) != rep) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
/* cut off latter part */
|
/* cut off latter part */
|
||||||
expanded.pop_back_n(rep.size());
|
expanded.pop_back_n(rep.size());
|
||||||
/* we got what we wanted... */
|
/* we got what we wanted... */
|
||||||
|
@ -200,8 +222,9 @@ struct ObState: CsState {
|
||||||
bool action;
|
bool action;
|
||||||
|
|
||||||
Rule(): target(), deps(), func(), action(false) {}
|
Rule(): target(), deps(), func(), action(false) {}
|
||||||
Rule(const Rule &r): target(r.target), deps(r.deps), func(r.func),
|
Rule(Rule const &r):
|
||||||
action(r.action) {}
|
target(r.target), deps(r.deps), func(r.func), action(r.action)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<Rule> rules;
|
Vector<Rule> rules;
|
||||||
|
@ -218,8 +241,9 @@ struct ObState: CsState {
|
||||||
|
|
||||||
void wait() {
|
void wait() {
|
||||||
UniqueLock<Mutex> l(mtx);
|
UniqueLock<Mutex> l(mtx);
|
||||||
while (counter)
|
while (counter) {
|
||||||
cond.wait(l);
|
cond.wait(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void incr() {
|
void incr() {
|
||||||
|
@ -237,7 +261,7 @@ struct ObState: CsState {
|
||||||
|
|
||||||
Condition cond;
|
Condition cond;
|
||||||
Mutex mtx;
|
Mutex mtx;
|
||||||
volatile int counter;
|
int volatile counter;
|
||||||
ostd::AtomicInt result;
|
ostd::AtomicInt result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,7 +273,9 @@ struct ObState: CsState {
|
||||||
counters.push(&ctr);
|
counters.push(&ctr);
|
||||||
int ret = func();
|
int ret = func();
|
||||||
counters.pop();
|
counters.pop();
|
||||||
if (ret) return ret;
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
ctr.wait();
|
ctr.wait();
|
||||||
return ctr.result;
|
return ctr.result;
|
||||||
}
|
}
|
||||||
|
@ -261,8 +287,10 @@ struct ObState: CsState {
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exec_list(const Vector<SubRule> &rlist, Vector<String> &subdeps,
|
int exec_list(
|
||||||
ConstCharRange tname) {
|
Vector<SubRule> const &rlist, Vector<String> &subdeps,
|
||||||
|
ConstCharRange tname
|
||||||
|
) {
|
||||||
String repd;
|
String repd;
|
||||||
for (auto &sr: rlist.iter()) for (auto &target: sr.rule->deps.iter()) {
|
for (auto &sr: rlist.iter()) for (auto &target: sr.rule->deps.iter()) {
|
||||||
ConstCharRange atgt = target.iter();
|
ConstCharRange atgt = target.iter();
|
||||||
|
@ -272,42 +300,51 @@ struct ObState: CsState {
|
||||||
repd.append(slice_until(atgt, lp));
|
repd.append(slice_until(atgt, lp));
|
||||||
repd.append(sr.sub);
|
repd.append(sr.sub);
|
||||||
++lp;
|
++lp;
|
||||||
if (!lp.empty()) repd.append(lp);
|
if (!lp.empty()) {
|
||||||
|
repd.append(lp);
|
||||||
|
}
|
||||||
atgt = repd.iter();
|
atgt = repd.iter();
|
||||||
}
|
}
|
||||||
subdeps.push(atgt);
|
subdeps.push(atgt);
|
||||||
int r = exec_rule(atgt, tname);
|
int r = exec_rule(atgt, tname);
|
||||||
if (r) return r;
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exec_func(ConstCharRange tname, const Vector<SubRule> &rlist) {
|
int exec_func(ConstCharRange tname, Vector<SubRule> const &rlist) {
|
||||||
Vector<String> subdeps;
|
Vector<String> subdeps;
|
||||||
int ret = wait_result([&rlist, &subdeps, &tname, this]() {
|
int ret = wait_result([&rlist, &subdeps, &tname, this]() {
|
||||||
return exec_list(rlist, subdeps, tname);
|
return exec_list(rlist, subdeps, tname);
|
||||||
});
|
});
|
||||||
Bytecode *func = nullptr;
|
Bytecode *func = nullptr;
|
||||||
bool act = false;
|
bool act = false;
|
||||||
for (auto &sr: rlist.iter()) if (sr.rule->func) {
|
for (auto &sr: rlist.iter()) {
|
||||||
func = &sr.rule->func;
|
if (sr.rule->func) {
|
||||||
act = sr.rule->action;
|
func = &sr.rule->func;
|
||||||
break;
|
act = sr.rule->action;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((!ret && (act || ob_check_exec(tname, subdeps))) && func) {
|
if ((!ret && (act || ob_check_exec(tname, subdeps))) && func) {
|
||||||
StackedValue targetv, sourcev, sourcesv;
|
StackedValue targetv, sourcev, sourcesv;
|
||||||
CsState &cs = *this;
|
CsState &cs = *this;
|
||||||
|
|
||||||
if (!targetv.alias(cs, "target"))
|
if (!targetv.alias(cs, "target")) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
targetv.set_cstr(tname);
|
targetv.set_cstr(tname);
|
||||||
targetv.push();
|
targetv.push();
|
||||||
|
|
||||||
if (!subdeps.empty()) {
|
if (!subdeps.empty()) {
|
||||||
if (!sourcev.alias(cs, "source"))
|
if (!sourcev.alias(cs, "source")) {
|
||||||
return 1;
|
return 1;
|
||||||
if (!sourcesv.alias(cs, "sources"))
|
}
|
||||||
|
if (!sourcesv.alias(cs, "sources")) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
sourcev.set_cstr(subdeps[0]);
|
sourcev.set_cstr(subdeps[0]);
|
||||||
sourcev.push();
|
sourcev.push();
|
||||||
|
@ -328,20 +365,21 @@ struct ObState: CsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_rules(ConstCharRange target, Vector<SubRule> &rlist) {
|
int find_rules(ConstCharRange target, Vector<SubRule> &rlist) {
|
||||||
if (!rlist.empty())
|
if (!rlist.empty()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
SubRule *frule = nullptr;
|
SubRule *frule = nullptr;
|
||||||
bool exact = false;
|
bool exact = false;
|
||||||
for (auto &rule: rules.iter()) {
|
for (auto &rule: rules.iter()) {
|
||||||
if (target == rule.target) {
|
if (target == rule.target) {
|
||||||
rlist.push().rule = &rule;
|
rlist.push().rule = &rule;
|
||||||
if (rule.func) {
|
if (rule.func) {
|
||||||
if (frule && exact)
|
if (frule && exact) {
|
||||||
return error(1, "redefinition of rule '%s'",
|
return error(1, "redefinition of rule '%s'", target);
|
||||||
target);
|
}
|
||||||
if (!frule)
|
if (!frule) {
|
||||||
frule = &rlist.back();
|
frule = &rlist.back();
|
||||||
else {
|
} else {
|
||||||
*frule = rlist.back();
|
*frule = rlist.back();
|
||||||
rlist.pop();
|
rlist.pop();
|
||||||
}
|
}
|
||||||
|
@ -349,22 +387,25 @@ struct ObState: CsState {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (exact || !rule.func)
|
if (exact || !rule.func) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
ConstCharRange sub = ob_compare_subst(target, rule.target);
|
ConstCharRange sub = ob_compare_subst(target, rule.target);
|
||||||
if (!sub.empty()) {
|
if (!sub.empty()) {
|
||||||
SubRule &sr = rlist.push();
|
SubRule &sr = rlist.push();
|
||||||
sr.rule = &rule;
|
sr.rule = &rule;
|
||||||
sr.sub = sub;
|
sr.sub = sub;
|
||||||
if (frule) {
|
if (frule) {
|
||||||
if (sub.size() == frule->sub.size())
|
if (sub.size() == frule->sub.size()) {
|
||||||
return error(1, "redefinition of rule '%s'",
|
return error(1, "redefinition of rule '%s'", target);
|
||||||
target);
|
}
|
||||||
if (sub.size() < frule->sub.size()) {
|
if (sub.size() < frule->sub.size()) {
|
||||||
*frule = sr;
|
*frule = sr;
|
||||||
rlist.pop();
|
rlist.pop();
|
||||||
}
|
}
|
||||||
} else frule = &sr;
|
} else {
|
||||||
|
frule = &sr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -373,16 +414,21 @@ struct ObState: CsState {
|
||||||
int exec_rule(ConstCharRange target, ConstCharRange from = nullptr) {
|
int exec_rule(ConstCharRange target, ConstCharRange from = nullptr) {
|
||||||
Vector<SubRule> &rlist = cache[target];
|
Vector<SubRule> &rlist = cache[target];
|
||||||
int fret = find_rules(target, rlist);
|
int fret = find_rules(target, rlist);
|
||||||
if (fret)
|
if (fret) {
|
||||||
return fret;
|
return fret;
|
||||||
if ((rlist.size() == 1) && rlist[0].rule->action)
|
}
|
||||||
|
if ((rlist.size() == 1) && rlist[0].rule->action) {
|
||||||
return exec_action(rlist[0].rule);
|
return exec_action(rlist[0].rule);
|
||||||
|
}
|
||||||
if (rlist.empty() && !ob_check_file(target)) {
|
if (rlist.empty() && !ob_check_file(target)) {
|
||||||
if (from.empty())
|
if (from.empty()) {
|
||||||
return error(1, "no rule to run target '%s'", target);
|
return error(1, "no rule to run target '%s'", target);
|
||||||
else
|
} else {
|
||||||
return error(1, "no rule to run target '%s' (needed by '%s')",
|
return error(
|
||||||
target, from);
|
1, "no rule to run target '%s' (needed by '%s')",
|
||||||
|
target, from
|
||||||
|
);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return exec_func(target, rlist);
|
return exec_func(target, rlist);
|
||||||
|
@ -392,8 +438,10 @@ struct ObState: CsState {
|
||||||
return wait_result([&target, this]() { return exec_rule(target); });
|
return wait_result([&target, this]() { return exec_rule(target); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void rule_add(ConstCharRange tgt, ConstCharRange dep, Uint32 *body,
|
void rule_add(
|
||||||
bool action = false) {
|
ConstCharRange tgt, ConstCharRange dep, Uint32 *body,
|
||||||
|
bool action = false
|
||||||
|
) {
|
||||||
auto targets = cscript::util::list_explode(tgt);
|
auto targets = cscript::util::list_explode(tgt);
|
||||||
for (auto &target: targets.iter()) {
|
for (auto &target: targets.iter()) {
|
||||||
Rule &r = rules.push();
|
Rule &r = rules.push();
|
||||||
|
@ -404,16 +452,20 @@ struct ObState: CsState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rule_dup(ConstCharRange tgt, ConstCharRange ptgt, ConstCharRange dep,
|
void rule_dup(
|
||||||
bool inherit_deps) {
|
ConstCharRange tgt, ConstCharRange ptgt, ConstCharRange dep,
|
||||||
|
bool inherit_deps
|
||||||
|
) {
|
||||||
Rule *oldr = nullptr;
|
Rule *oldr = nullptr;
|
||||||
for (auto &rule: rules.iter())
|
for (auto &rule: rules.iter()) {
|
||||||
if (ptgt == rule.target) {
|
if (ptgt == rule.target) {
|
||||||
oldr = &rule;
|
oldr = &rule;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!oldr)
|
}
|
||||||
|
if (!oldr) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
Rule &r = rules.push();
|
Rule &r = rules.push();
|
||||||
r.target = tgt;
|
r.target = tgt;
|
||||||
r.action = oldr->action;
|
r.action = oldr->action;
|
||||||
|
@ -447,14 +499,16 @@ struct ObState: CsState {
|
||||||
|
|
||||||
int print_help(bool error) {
|
int print_help(bool error) {
|
||||||
ostd::Stream &os = error ? ostd::err : ostd::out;
|
ostd::Stream &os = error ? ostd::err : ostd::out;
|
||||||
os.writeln("Usage: ", progname, " [options] [action]\n",
|
os.writeln(
|
||||||
"Options:\n"
|
"Usage: ", progname, " [options] [action]\n",
|
||||||
" -C DIRECTORY\tChange to DIRECTORY before running.\n",
|
"Options:\n"
|
||||||
" -f FILE\tSpecify the file to run (default: ", deffile, ").\n"
|
" -C DIRECTORY\tChange to DIRECTORY before running.\n",
|
||||||
" -h\t\tPrint this message.\n"
|
" -f FILE\tSpecify the file to run (default: ", deffile, ").\n"
|
||||||
" -j N\t\tSpecify the number of jobs to use (default: 1).\n"
|
" -h\t\tPrint this message.\n"
|
||||||
" -e STR\tEvaluate a string instead of a file.\n"
|
" -j N\t\tSpecify the number of jobs to use (default: 1).\n"
|
||||||
" -E\t\tIgnore environment variables.");
|
" -e STR\tEvaluate a string instead of a file.\n"
|
||||||
|
" -E\t\tIgnore environment variables."
|
||||||
|
);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -474,38 +528,43 @@ int main(int argc, char **argv) {
|
||||||
ConstCharRange fcont;
|
ConstCharRange fcont;
|
||||||
|
|
||||||
int posarg = argc;
|
int posarg = argc;
|
||||||
for (int i = 1; i < argc; ++i) if (argv[i][0] == '-') {
|
for (int i = 1; i < argc; ++i) {
|
||||||
char argn = argv[i][1];
|
if (argv[i][0] == '-') {
|
||||||
if (argn == 'E') {
|
char argn = argv[i][1];
|
||||||
osv.ignore_env = true;
|
if (argn == 'E') {
|
||||||
continue;
|
osv.ignore_env = true;
|
||||||
} else if ((argn == 'h') || (!argv[i][2] && ((i + 1) >= argc))) {
|
continue;
|
||||||
return osv.print_help(argn != 'h');
|
} else if ((argn == 'h') || (!argv[i][2] && ((i + 1) >= argc))) {
|
||||||
}
|
return osv.print_help(argn != 'h');
|
||||||
ConstCharRange val = (argv[i][2] == '\0') ? argv[++i] : &argv[i][2];
|
}
|
||||||
switch (argn) {
|
ConstCharRange val = (argv[i][2] == '\0') ? argv[++i] : &argv[i][2];
|
||||||
case 'C':
|
switch (argn) {
|
||||||
if (!ostd::directory_change(val))
|
case 'C':
|
||||||
return osv.error(1, "failed changing directory: %s", val);
|
if (!ostd::directory_change(val)) {
|
||||||
break;
|
return osv.error(1, "failed changing directory: %s", val);
|
||||||
case 'f':
|
}
|
||||||
deffile = val;
|
break;
|
||||||
break;
|
case 'f':
|
||||||
case 'e':
|
deffile = val;
|
||||||
fcont = val;
|
break;
|
||||||
break;
|
case 'e':
|
||||||
case 'j': {
|
fcont = val;
|
||||||
int ival = atoi(val.data());
|
break;
|
||||||
if (!ival) ival = ncpus;
|
case 'j': {
|
||||||
osv.jobs = ostd::max(1, ival);
|
int ival = atoi(val.data());
|
||||||
|
if (!ival) {
|
||||||
|
ival = ncpus;
|
||||||
|
}
|
||||||
|
osv.jobs = ostd::max(1, ival);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return osv.print_help(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
posarg = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
return osv.print_help(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
posarg = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tpool.init(osv.jobs);
|
tpool.init(osv.jobs);
|
||||||
|
@ -517,8 +576,9 @@ int main(int argc, char **argv) {
|
||||||
cnt->incr();
|
cnt->incr();
|
||||||
tpool.push([cnt, ds = String(s)]() {
|
tpool.push([cnt, ds = String(s)]() {
|
||||||
int ret = system(ds.data());
|
int ret = system(ds.data());
|
||||||
if (ret && !cnt->result)
|
if (ret && !cnt->result) {
|
||||||
cnt->result = ret;
|
cnt->result = ret;
|
||||||
|
}
|
||||||
cnt->decr();
|
cnt->decr();
|
||||||
});
|
});
|
||||||
os.result->set_int(0);
|
os.result->set_int(0);
|
||||||
|
@ -529,20 +589,27 @@ int main(int argc, char **argv) {
|
||||||
os.result->set_cstr("");
|
os.result->set_cstr("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
os.result->set_str(ostd::move(ostd::env_get(args[0].get_str())
|
os.result->set_str(ostd::move(
|
||||||
.value_or(args[1].get_str())));
|
ostd::env_get(args[0].get_str()).value_or(args[1].get_str())
|
||||||
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
osv.add_command("extreplace", "sss", [](cscript::CsState &cs,
|
osv.add_command("extreplace", "sss", [](
|
||||||
const char *lst,
|
cscript::CsState &cs, char const *lst,
|
||||||
const char *oldext,
|
char const *oldext, char const *newext
|
||||||
const char *newext) {
|
) {
|
||||||
String ret;
|
String ret;
|
||||||
if (oldext[0] == '.') ++oldext;
|
if (oldext[0] == '.') {
|
||||||
if (newext[0] == '.') ++newext;
|
++oldext;
|
||||||
|
}
|
||||||
|
if (newext[0] == '.') {
|
||||||
|
++newext;
|
||||||
|
}
|
||||||
auto fnames = cscript::util::list_explode(lst);
|
auto fnames = cscript::util::list_explode(lst);
|
||||||
for (ConstCharRange it: fnames.iter()) {
|
for (ConstCharRange it: fnames.iter()) {
|
||||||
if (!ret.empty()) ret += ' ';
|
if (!ret.empty()) {
|
||||||
|
ret += ' ';
|
||||||
|
}
|
||||||
auto dot = ostd::find_last(it, '.');
|
auto dot = ostd::find_last(it, '.');
|
||||||
if (!dot.empty() && ((dot + 1) == oldext)) {
|
if (!dot.empty() && ((dot + 1) == oldext)) {
|
||||||
ret += ostd::slice_until(it, dot);
|
ret += ostd::slice_until(it, dot);
|
||||||
|
@ -555,17 +622,19 @@ int main(int argc, char **argv) {
|
||||||
cs.result->set_str(ostd::move(ret));
|
cs.result->set_str(ostd::move(ret));
|
||||||
});
|
});
|
||||||
|
|
||||||
osv.add_command("invoke", "s", [](ObState &os, const char *name) {
|
osv.add_command("invoke", "s", [](ObState &os, char const *name) {
|
||||||
os.result->set_int(os.exec_main(name));
|
os.result->set_int(os.exec_main(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
cs_register_globs(osv);
|
cs_register_globs(osv);
|
||||||
|
|
||||||
if ((!fcont.empty() && !osv.run_bool(fcont)) || !osv.run_file(deffile))
|
if ((!fcont.empty() && !osv.run_bool(fcont)) || !osv.run_file(deffile)) {
|
||||||
return osv.error(1, "failed creating rules");
|
return osv.error(1, "failed creating rules");
|
||||||
|
}
|
||||||
|
|
||||||
if (osv.rules.empty())
|
if (osv.rules.empty()) {
|
||||||
return osv.error(1, "no targets");
|
return osv.error(1, "no targets");
|
||||||
|
}
|
||||||
|
|
||||||
return osv.exec_main((posarg < argc) ? argv[posarg] : "default");
|
return osv.exec_main((posarg < argc) ? argv[posarg] : "default");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CXX = (getenv CXX c++)
|
CXX = (getenv CXX c++)
|
||||||
|
|
||||||
OB_CXXFLAGS = "-g -Wall -Wextra -Wshadow -O2"
|
OB_CXXFLAGS = "-g -Wall -Wextra -Wshadow -Wold-style-cast -O2"
|
||||||
|
|
||||||
CS_PATH = "../libcubescript"
|
CS_PATH = "../libcubescript"
|
||||||
OS_PATH = "../octastd"
|
OS_PATH = "../octastd"
|
||||||
|
|
Loading…
Reference in New Issue