some file path handling changes around windows

This commit is contained in:
dzaima 2023-01-13 19:16:13 +02:00
parent 52d78657c9
commit e987a5e4c0
3 changed files with 28 additions and 12 deletions

View File

@ -29,6 +29,21 @@ static DIR* dir_open(B path) { // doesn't consume
return f;
}
#if defined(_WIN32) || defined(_WIN64)
#define PREFERRED_SEP '\\'
static bool isPathSep(uint32_t c) { return c=='/' || c=='\\'; }
static bool isAbsolutePath(B x) {
char* p = toCStr(x);
bool r = winIsAbsolute(p);
freeCStr(p);
return r;
}
#else
#define PREFERRED_SEP '/'
static bool isPathSep(uint32_t c) { return c=='/'; }
static bool isAbsolutePath(B x) { return o2cG(IGetU(x, 0))=='/'; }
#endif
I8Arr* stream_bytes(FILE* f) {
B r = emptyIVec();
@ -114,17 +129,17 @@ B path_rel(B base, B rel) { // consumes rel; assumes base is a char vector or bi
usz ria = IA(rel);
if (RNK(rel)!=1) thrM("Paths must be character vectors");
guaranteeStr(rel);
if (ria>0 && o2cG(GetU(rel, 0))=='/') return rel;
if (ria>0 && isAbsolutePath(rel)) return rel;
if (q_N(base)) thrM("Using relative path with no absolute base path known");
if (ria==0) { dec(rel); return incG(base); }
usz bia = IA(base);
if (bia==0) return rel;
SGetU(base)
bool has = o2cG(GetU(base, bia-1))=='/';
bool has = isPathSep(o2cG(GetU(base, bia-1)));
u32* rp; B r = m_c32arrv(&rp, bia+ria+(has?0:1));
usz ri = 0;
for (usz i = 0; i < bia-(has?1:0); i++) rp[ri++] = o2cG(GetU(base, i));
rp[ri++] = '/';
rp[ri++] = PREFERRED_SEP;
for (usz i = 0; i < ria; i++) rp[ri++] = o2cG(GetU(rel, i));
dec(rel);
return r;
@ -137,11 +152,11 @@ B path_parent(B path) {
if (pia==0) thrM("Empty file path");
guaranteeStr(path);
for (i64 i = (i64)pia-2; i >= 0; i--) {
if (o2cG(GetU(path, i))=='/') return taga(arr_shVec(TI(path,slice)(path, 0, i+1)));
if (isPathSep(o2cG(GetU(path, i)))) return taga(arr_shVec(TI(path,slice)(path, 0, i+1)));
}
if (o2cG(GetU(path, 0))=='/') return path;
if (isAbsolutePath(path)) return path;
dec(path);
u32* rp; B r = m_c32arrv(&rp, 2); rp[0] = '.'; rp[1] = '/';
u32* rp; B r = m_c32arrv(&rp, 2); rp[0] = '.'; rp[1] = PREFERRED_SEP;
return r;
}
B path_name(B path) {
@ -151,7 +166,7 @@ B path_name(B path) {
if (pia==0) thrM("Empty file path");
guaranteeStr(path);
for (i64 i = (i64)pia-1; i >= 0; i--) {
if (o2cG(GetU(path, i))=='/') {
if (isPathSep(o2cG(GetU(path, i)))) {
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))));
}

View File

@ -2,8 +2,8 @@
#include "realpath.h"
char* realpath (const char *__restrict path, char *__restrict resolved_path) {
unsigned long len=strlen(path)+1;
void* r = malloc(len);
memcpy(r, path, len);
return r;
return _fullpath(NULL, path, 0);
}
bool winIsAbsolute(const char* path) { // TODO something more proper
return *path && path[1]==':' && (!path[2] || path[2]=='/' || path[2]=='\\');
}

View File

@ -1,6 +1,7 @@
#ifndef REALPATH_H
#define REALPATH_H
char* realpath (const char *__restrict path, char *__restrict resolved_path);
char* realpath(const char *__restrict path, char *__restrict resolved_path);
bool winIsAbsolute(const char* path);
#endif /* REALPATH_H */