style updates

master
Daniel Kolesa 2016-08-01 00:09:29 +01:00
parent aee15f8515
commit a36e9d021a
4 changed files with 236 additions and 145 deletions

View File

@ -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

View File

@ -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
View File

@ -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");
} }

View File

@ -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"