add •state and •name

This commit is contained in:
dzaima 2021-11-24 23:03:17 +02:00
parent 097f39da15
commit b76d30d4bc
3 changed files with 37 additions and 9 deletions

View File

@ -780,8 +780,10 @@ B sys_c1(B t, B x) {
SGetU(x)
B fileNS = m_f64(0);
B path = m_f64(0);
B name = m_f64(0);
B wdpath = m_f64(0);
#define REQ_PATH ({ if(!path.u) path = path_abs(path_dir(inc(comp_currPath))); path; })
#define REQ_PATH ({ if(!path.u) path = q_N(comp_currPath)? bi_N : path_abs(path_dir(inc(comp_currPath))); path; })
#define REQ_NAME ({ if(!name.u) name = path_name(inc(comp_currPath)); name; })
for (; i < a(x)->ia; i++) {
B c = GetU(x,i);
if (eqStr(c, U"out")) r.a[i] = incG(bi_out);
@ -824,18 +826,23 @@ B sys_c1(B t, B x) {
else if (eqStr(c, U"rebqn")) r.a[i] = incG(bi_reBQN);
else if (eqStr(c, U"fromutf8")) r.a[i] = incG(bi_fromUtf8);
else if (eqStr(c, U"path")) r.a[i] = inc(REQ_PATH);
else if (eqStr(c, U"name")) r.a[i] = inc(REQ_NAME);
else if (eqStr(c, U"fchars")) r.a[i] = m_nfn(fCharsDesc, inc(REQ_PATH));
else if (eqStr(c, U"fbytes")) r.a[i] = m_nfn(fBytesDesc, inc(REQ_PATH));
else if (eqStr(c, U"flines")) r.a[i] = m_nfn(fLinesDesc, inc(REQ_PATH));
else if (eqStr(c, U"import")) r.a[i] = m_nfn(importDesc, inc(REQ_PATH));
else if (eqStr(c, U"args")) {
if(q_N(comp_currArgs)) thrM("No arguments present for •args");
else if (eqStr(c, U"state")) {
if (q_N(comp_currArgs)) thrM("No arguments present for •state");
r.a[i] = m_hVec3(inc(REQ_PATH), inc(REQ_NAME), inc(comp_currArgs));
} else if (eqStr(c, U"args")) {
if (q_N(comp_currArgs)) thrM("No arguments present for •args");
r.a[i] = inc(comp_currArgs);
} else { dec(x); thrF("Unknown system function •%R", c); }
}
#undef REQ_PATH
dec(fileNS);
dec(path);
dec(name);
dec(wdpath);
return harr_fcd(r, x);
}

View File

@ -87,15 +87,21 @@ B file_lines(B path) { // consumes
}
static NOINLINE void guaranteeStr(B x) { // assumes x is an array
if (elChr(TI(x,elType))) return;
usz xia = a(x)->ia;
SGetU(x)
for (usz i = 0; i < xia; i++) if (!isC32(GetU(x, i))) thrM("Paths must be character vectors");
}
B path_rel(B base, B rel) { // consumes rel; assumes base is a char vector or bi_N
assert((isArr(base) || q_N(base)));
assert(isArr(base) || q_N(base));
if (!isArr(rel) || rnk(rel)!=1) thrM("Paths must be character vectors");
SGetU(rel)
usz ria = a(rel)->ia;
if (rnk(rel)!=1) thrM("Paths must be character vectors");
for (usz i = 0; i < ria; i++) if (!isC32(GetU(rel, i))) thrM("Paths must be character vectors");
guaranteeStr(rel);
if (ria>0 && o2cu(GetU(rel, 0))=='/') return rel;
if (q_N(base)) thrM("Using relative path with no absolute base path known");
if (ria==0) { dec(rel); return inc(base); }
@ -111,13 +117,12 @@ B path_rel(B base, B rel) { // consumes rel; assumes base is a char vector or bi
return r;
}
B path_dir(B path) { // consumes; returns directory part of file path with trailing slash, or ·
assert(isArr(path) || q_N(path));
if (q_N(path)) return path;
B path_dir(B path) {
assert(isArr(path));
SGetU(path)
usz pia = a(path)->ia;
if (pia==0) thrM("Empty file path");
for (usz i = 0; i < pia; i++) if (!isC32(GetU(path, i))) thrM("Paths must be character vectors");
guaranteeStr(path);
for (i64 i = (i64)pia-1; i >= 0; i--) {
if (o2cu(GetU(path, i))=='/') {
Arr* r = TI(path,slice)(path, 0, i+1); arr_shVec(r);
@ -128,6 +133,21 @@ B path_dir(B path) { // consumes; returns directory part of file path with trail
u32* rp; B r = m_c32arrv(&rp, 2); rp[0] = '.'; rp[1] = '/';
return r;
}
B path_name(B path) {
assert(isArr(path));
SGetU(path)
usz pia = a(path)->ia;
if (pia==0) thrM("Empty file path");
guaranteeStr(path);
for (i64 i = (i64)pia-1; i >= 0; i--) {
if (o2cu(GetU(path, i))=='/') {
if (i == pia-1) thrF("File path ended with a slash: '%R'", path);
Arr* r = TI(path,slice)(path, i+1, pia - (i+1)); arr_shVec(r);
return taga(r);
}
}
return path;
}
B path_abs(B path) {
if (q_N(path)) return path;

View File

@ -3,6 +3,7 @@
B path_rel(B base, B rel); // consumes rel; assumes base is a char vector or bi_N
B path_dir(B path); // consumes; returns directory part of file path, with trailing slash
B path_name(B path); // consumes; returns filename from a path
B path_abs(B path); // consumes; returns absolute version of the path; propagates bi_N
FILE* file_open(B path, char* desc, char* mode); // doesn't consume path