•file.Created, •file.Accessed, •file.Modified
This commit is contained in:
parent
905a9f78d4
commit
d12a53fd08
@ -15,7 +15,7 @@ See [the BQN specification](https://mlochbaum.github.io/BQN/spec/system.html) fo
|
|||||||
| `•name` | |
|
| `•name` | |
|
||||||
| `•wdpath` | |
|
| `•wdpath` | |
|
||||||
| `•Exit` | |
|
| `•Exit` | |
|
||||||
| `•file` | Fields: `path`, `At`, `List`, `Bytes`, `Chars`, `Lines`, `Type`, `Exists`, `Name`, `Parent`, `MapBytes`, `CreateDir`, `Rename`, `Remove` |
|
| `•file` | Fields: `path`, `At`, `List`, `Bytes`, `Chars`, `Lines`, `Type`, `Exists`, `Name`, `Parent`, `MapBytes`, `CreateDir`, `Rename`, `Remove`, `Created`, `Modified`, `Accessed` |
|
||||||
| `•FChars` | |
|
| `•FChars` | |
|
||||||
| `•FBytes` | |
|
| `•FBytes` | |
|
||||||
| `•FLines` | |
|
| `•FLines` | |
|
||||||
|
|||||||
@ -726,6 +726,9 @@ void clearImportCache() {
|
|||||||
|
|
||||||
|
|
||||||
static NFnDesc* fTypeDesc;
|
static NFnDesc* fTypeDesc;
|
||||||
|
static NFnDesc* fCreatedDesc;
|
||||||
|
static NFnDesc* fAccessedDesc;
|
||||||
|
static NFnDesc* fModifiedDesc;
|
||||||
static NFnDesc* fExistsDesc;
|
static NFnDesc* fExistsDesc;
|
||||||
static NFnDesc* fListDesc;
|
static NFnDesc* fListDesc;
|
||||||
static NFnDesc* fMapBytesDesc;
|
static NFnDesc* fMapBytesDesc;
|
||||||
@ -759,6 +762,11 @@ B ftype_c1(B d, B x) {
|
|||||||
if (ty==0) thrM("•file.Type: Error while accessing file");
|
if (ty==0) thrM("•file.Type: Error while accessing file");
|
||||||
return m_c32(ty);
|
return m_c32(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
B fcreated_c1 (B d, B x) { return path_info(path_rel(nfn_objU(d), x), 0); }
|
||||||
|
B faccessed_c1(B d, B x) { return path_info(path_rel(nfn_objU(d), x), 1); }
|
||||||
|
B fmodified_c1(B d, B x) { return path_info(path_rel(nfn_objU(d), x), 2); }
|
||||||
|
|
||||||
B fexists_c1(B d, B x) {
|
B fexists_c1(B d, B x) {
|
||||||
char ty = path_type(path_rel(nfn_objU(d), x));
|
char ty = path_type(path_rel(nfn_objU(d), x));
|
||||||
return m_f64(ty!=0);
|
return m_f64(ty!=0);
|
||||||
@ -1208,7 +1216,7 @@ B sys_c1(B t, B x) {
|
|||||||
if(!fileNS.u) {
|
if(!fileNS.u) {
|
||||||
REQ_PATH;
|
REQ_PATH;
|
||||||
#define F(X) m_nfn(X##Desc, inc(path))
|
#define F(X) m_nfn(X##Desc, inc(path))
|
||||||
fileNS = m_nns(file_nsGen, q_N(path)? m_c32(0) : inc(path), F(fileAt), F(fList), F(fBytes), F(fChars), F(fLines), F(fType), F(fExists), inc(bi_fName), inc(bi_fParent), F(fMapBytes), F(createdir), F(rename), F(remove));
|
fileNS = m_nns(file_nsGen, q_N(path)? m_c32(0) : inc(path), F(fileAt), F(fList), F(fBytes), F(fChars), F(fLines), F(fType), F(fCreated), F(fAccessed), F(fModified), F(fExists), inc(bi_fName), inc(bi_fParent), F(fMapBytes), F(createdir), F(rename), F(remove));
|
||||||
#undef F
|
#undef F
|
||||||
}
|
}
|
||||||
cr = incG(fileNS);
|
cr = incG(fileNS);
|
||||||
@ -1241,6 +1249,7 @@ B sys_c1(B t, B x) {
|
|||||||
else if (eqStr(c, U"rebqn")) cr = incG(bi_reBQN);
|
else if (eqStr(c, U"rebqn")) cr = incG(bi_reBQN);
|
||||||
else if (eqStr(c, U"primitives")) cr = getPrimitives();
|
else if (eqStr(c, U"primitives")) cr = getPrimitives();
|
||||||
else if (eqStr(c, U"fromutf8")) cr = incG(bi_fromUtf8);
|
else if (eqStr(c, U"fromutf8")) cr = incG(bi_fromUtf8);
|
||||||
|
else if (eqStr(c, U"toutf8")) cr = incG(bi_toUtf8);
|
||||||
else if (eqStr(c, U"path")) cr = inc(REQ_PATH);
|
else if (eqStr(c, U"path")) cr = inc(REQ_PATH);
|
||||||
else if (eqStr(c, U"name")) cr = inc(REQ_NAME);
|
else if (eqStr(c, U"name")) cr = inc(REQ_NAME);
|
||||||
else if (eqStr(c, U"fchars")) cr = m_nfn(fCharsDesc, inc(REQ_PATH));
|
else if (eqStr(c, U"fchars")) cr = m_nfn(fCharsDesc, inc(REQ_PATH));
|
||||||
@ -1279,6 +1288,9 @@ void sysfn_init() {
|
|||||||
fBytesDesc = registerNFn(m_c8vec_0("(file).Bytes"), fbytes_c1, fbytes_c2);
|
fBytesDesc = registerNFn(m_c8vec_0("(file).Bytes"), fbytes_c1, fbytes_c2);
|
||||||
fListDesc = registerNFn(m_c8vec_0("(file).List"), list_c1, c2_bad);
|
fListDesc = registerNFn(m_c8vec_0("(file).List"), list_c1, c2_bad);
|
||||||
fTypeDesc = registerNFn(m_c8vec_0("(file).Type"), ftype_c1, c2_bad);
|
fTypeDesc = registerNFn(m_c8vec_0("(file).Type"), ftype_c1, c2_bad);
|
||||||
|
fCreatedDesc = registerNFn(m_c8vec_0("(file).Created"), fcreated_c1, c2_bad);
|
||||||
|
fModifiedDesc= registerNFn(m_c8vec_0("(file).Modified"), fmodified_c1, c2_bad);
|
||||||
|
fAccessedDesc= registerNFn(m_c8vec_0("(file).Accessed"), faccessed_c1, c2_bad);
|
||||||
createdirDesc= registerNFn(m_c8vec_0("(file).CreateDir"), createdir_c1, c2_bad);
|
createdirDesc= registerNFn(m_c8vec_0("(file).CreateDir"), createdir_c1, c2_bad);
|
||||||
renameDesc = registerNFn(m_c8vec_0("(file).Rename"), c1_bad, rename_c2);
|
renameDesc = registerNFn(m_c8vec_0("(file).Rename"), c1_bad, rename_c2);
|
||||||
removeDesc = registerNFn(m_c8vec_0("(file).Remove"), remove_c1, c2_bad);
|
removeDesc = registerNFn(m_c8vec_0("(file).Remove"), remove_c1, c2_bad);
|
||||||
@ -1289,6 +1301,6 @@ void sysfn_init() {
|
|||||||
ffiloadDesc = registerNFn(m_c32vec_0(U"•FFI"), c1_bad, ffiload_c2);
|
ffiloadDesc = registerNFn(m_c32vec_0(U"•FFI"), c1_bad, ffiload_c2);
|
||||||
}
|
}
|
||||||
void sysfnPost_init() {
|
void sysfnPost_init() {
|
||||||
file_nsGen = m_nnsDesc("path","at","list","bytes","chars","lines","type","exists","name","parent","mapbytes","createdir","rename","remove");
|
file_nsGen = m_nnsDesc("path","at","list","bytes","chars","lines","type","created","accessed","modified","exists","name","parent","mapbytes","createdir","rename","remove");
|
||||||
c(BMd1,bi_bitcast)->im = bitcast_im;
|
c(BMd1,bi_bitcast)->im = bitcast_im;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,7 +139,7 @@ B path_name(B path) {
|
|||||||
guaranteeStr(path);
|
guaranteeStr(path);
|
||||||
for (i64 i = (i64)pia-1; i >= 0; i--) {
|
for (i64 i = (i64)pia-1; i >= 0; i--) {
|
||||||
if (o2cu(GetU(path, i))=='/') {
|
if (o2cu(GetU(path, i))=='/') {
|
||||||
if (i == pia-1) thrF("File path ended with a slash: '%R'", path);
|
if (i == pia-1) thrF("File path ended with a slash: \"%R\"", path);
|
||||||
return taga(arr_shVec(TI(path,slice)(path, i+1, pia - (i+1))));
|
return taga(arr_shVec(TI(path,slice)(path, i+1, pia - (i+1))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,7 +301,7 @@ void mmap_init() {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
B mmap_file(B path) {
|
B mmap_file(B path) {
|
||||||
thrM("CBQN was compiled without mmap");
|
thrM("CBQN was compiled without •file.MapBytes support");
|
||||||
}
|
}
|
||||||
void mmap_init() { }
|
void mmap_init() { }
|
||||||
#endif
|
#endif
|
||||||
@ -335,15 +335,20 @@ bool path_remove(B path) {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
char path_type(B path) {
|
int path_stat(struct stat* s, B path) { // doesn't consume; get stat of s; errors if path isn't string; returns non-zero on failure
|
||||||
char* p = toCStr(path);
|
char* p = toCStr(path);
|
||||||
struct stat path_stat;
|
int r = stat(p, s);
|
||||||
int r = stat(p, &path_stat);
|
|
||||||
freeCStr(p);
|
freeCStr(p);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path_type(B path) {
|
||||||
|
struct stat s;
|
||||||
|
int r = path_stat(&s, path);
|
||||||
dec(path);
|
dec(path);
|
||||||
|
|
||||||
if (r==-1) return 0;
|
if (r==-1) return 0;
|
||||||
i64 mode = path_stat.st_mode;
|
i64 mode = s.st_mode;
|
||||||
if (S_ISREG (mode)) return 'f';
|
if (S_ISREG (mode)) return 'f';
|
||||||
if (S_ISDIR (mode)) return 'd';
|
if (S_ISDIR (mode)) return 'd';
|
||||||
if (S_ISLNK (mode)) return 'l';
|
if (S_ISLNK (mode)) return 'l';
|
||||||
@ -353,6 +358,21 @@ char path_type(B path) {
|
|||||||
if (S_ISCHR (mode)) return 'c';
|
if (S_ISCHR (mode)) return 'c';
|
||||||
thrM("Unexpected file type");
|
thrM("Unexpected file type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
B get_timespec(struct timespec ts) {
|
||||||
|
return m_f64(ts.tv_sec + ts.tv_nsec*1e-9);
|
||||||
|
}
|
||||||
|
B path_info(B path, i32 mode) {
|
||||||
|
struct stat s;
|
||||||
|
int r = path_stat(&s, path);
|
||||||
|
if (r==-1) thrF("Failed to access file \"%R\": %S", path, strerror(errno));
|
||||||
|
dec(path);
|
||||||
|
if (mode==0) return get_timespec(s.st_ctim);
|
||||||
|
if (mode==1) return get_timespec(s.st_atim);
|
||||||
|
if (mode==2) return get_timespec(s.st_mtim);
|
||||||
|
thrM("Unknown path_info mode");
|
||||||
|
}
|
||||||
|
|
||||||
void mmX_dumpHeap(FILE* f);
|
void mmX_dumpHeap(FILE* f);
|
||||||
void writeNum(FILE* f, u64 v, i32 len) {
|
void writeNum(FILE* f, u64 v, i32 len) {
|
||||||
u8 buf[8];
|
u8 buf[8];
|
||||||
|
|||||||
@ -27,5 +27,6 @@ void path_wBytes(B path, B x); // consumes path
|
|||||||
void file_wBytes(FILE* file, B name, B x); // doesn't consume
|
void file_wBytes(FILE* file, B name, B x); // doesn't consume
|
||||||
|
|
||||||
B path_list(B path); // consumes
|
B path_list(B path); // consumes
|
||||||
char path_type(B path); // consumes
|
char path_type(B path); // consumes; errors only if path isn't a string
|
||||||
|
B path_info(B path, i32 mode); // consumes; mode: 0:created 1:accessed 2:modified
|
||||||
void cbqn_heapDump(void);
|
void cbqn_heapDump(void);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user