-
Notifications
You must be signed in to change notification settings - Fork 80
/
path.cc
91 lines (82 loc) · 2.21 KB
/
path.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "uv.h"
#undef ERROR
#include "Rcpp.h"
#include "error.h"
using namespace Rcpp;
// [[Rcpp::export]]
CharacterVector realize_(CharacterVector path) {
CharacterVector out = CharacterVector(path.size());
for (R_xlen_t i = 0; i < Rf_xlength(out); ++i) {
uv_fs_t req;
const char* p = CHAR(STRING_ELT(path, i));
uv_fs_realpath(uv_default_loop(), &req, p, NULL);
stop_for_error(req, "Failed to realize '%s'", p);
SET_STRING_ELT(out, i, Rf_mkChar((const char*)req.ptr));
uv_fs_req_cleanup(&req);
}
return out;
}
// [[Rcpp::export]]
CharacterVector path_(List paths, const char* ext) {
R_xlen_t max_row = 0;
R_xlen_t max_col = Rf_xlength(paths);
char buf[1024];
char* b = buf;
for (R_xlen_t c = 0; c < max_col; ++c) {
R_xlen_t len = Rf_xlength(VECTOR_ELT(paths, c));
if (len == 0) {
return CharacterVector();
}
if (len > max_row) {
max_row = len;
}
}
CharacterVector out(max_row);
for (R_xlen_t r = 0; r < max_row; ++r) {
bool has_na = false;
b = buf;
for (R_xlen_t c = 0; c < max_col; ++c) {
R_xlen_t k = Rf_xlength(VECTOR_ELT(paths, c));
if (k > 0) {
SEXP str = STRING_ELT(VECTOR_ELT(paths, c), r % k);
if (str == NA_STRING) {
has_na = true;
break;
}
const char* s = CHAR(str);
strcpy(b, s);
b += strlen(s);
bool trailing_slash =
(b > buf) && (*(b - 1) == '/' || *(b - 1) == '\\');
if (!(trailing_slash || c == (max_col - 1))) {
*b++ = '/';
}
}
}
if (has_na) {
out[r] = NA_STRING;
} else {
if (strlen(ext) > 0) {
*b++ = '.';
strcpy(b, ext);
b += strlen(ext) + 1;
}
*b = '\0';
out[r] = Rf_mkCharCE(buf, CE_UTF8);
}
}
return out;
}
// [[Rcpp::export]]
CharacterVector expand_(CharacterVector path) {
CharacterVector out = CharacterVector(path.size());
for (R_xlen_t i = 0; i < Rf_xlength(out); ++i) {
if (STRING_ELT(path, i) == R_NaString) {
SET_STRING_ELT(out, i, R_NaString);
} else {
const char* p = CHAR(STRING_ELT(path, i));
SET_STRING_ELT(out, i, Rf_mkCharCE(R_ExpandFileName(p), CE_UTF8));
}
}
return out;
}