deduplicate sh_c2 setup & output prep

This commit is contained in:
dzaima 2024-02-04 15:22:01 +02:00
parent 4f39729013
commit 291d3ef5d7

View File

@ -1023,24 +1023,8 @@ void shClose(int fd) { if (close(fd)) fatal("bad file descriptor close"); }
// #define shDbg(...) printf(__VA_ARGS__); fflush(stdout) // #define shDbg(...) printf(__VA_ARGS__); fflush(stdout)
#define shDbg(...) #define shDbg(...)
B sh_c2(B t, B w, B x) { static i32 sh_core(bool raw, B x, usz xia, B inObj, u64 iLen, B* s_outp, B* s_errp) {
// parse options
B inObj = bi_N;
bool raw = false;
if (!q_N(w)) {
if (!isNsp(w)) thrM("•SH: 𝕨 must be a namespace");
inObj = ns_getC(w, "stdin");
if (!q_N(inObj) && !isArr(inObj)) thrM("•SH: Invalid stdin value");
B rawObj = ns_getC(w, "raw");
if (!q_N(rawObj)) raw = o2b(rawObj);
}
u64 iLen = q_N(inObj)? 0 : (raw? IA(inObj) : utf8lenB(inObj));
// allocate args // allocate args
if (isAtm(x) || RNK(x)>1) thrM("•SH: 𝕩 must be a vector of strings");
usz xia = IA(x);
if (xia==0) thrM("•SH: 𝕩 must have at least one item");
TALLOC(char*, argv, xia+1); TALLOC(char*, argv, xia+1);
SGetU(x) SGetU(x)
for (u64 i = 0; i < xia; i++) { for (u64 i = 0; i < xia; i++) {
@ -1152,46 +1136,19 @@ B sh_c2(B t, B w, B x) {
int status; int status;
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
dec(w); dec(x); *s_outp = s_out;
B s_outRaw = toC8Any(s_out); *s_errp = s_err;
B s_errRaw = toC8Any(s_err); return WIFEXITED(status)? WEXITSTATUS(status)
B s_outObj;
B s_errObj;
if (raw) {
s_outObj = s_outRaw;
s_errObj = s_errRaw;
} else {
s_outObj = utf8Decode((char*)c8any_ptr(s_outRaw), IA(s_outRaw)); dec(s_outRaw);
s_errObj = utf8Decode((char*)c8any_ptr(s_errRaw), IA(s_errRaw)); dec(s_errRaw);
}
int code = WIFEXITED(status)? WEXITSTATUS(status)
: WIFSIGNALED(status)? WTERMSIG(status)+128 : WIFSIGNALED(status)? WTERMSIG(status)+128
: -1; : -1;
return m_hvec3(m_i32(code), s_outObj, s_errObj);
} }
#elif defined(_WIN32) || defined(_WIN64) #elif defined(_WIN32) || defined(_WIN64)
#define HAS_SH 1 #define HAS_SH 1
#include "../windows/winError.c" #include "../windows/winError.c"
#include "../windows/sh.c" #include "../windows/sh.c"
B sh_c2(B t, B w, B x) { static i32 sh_core(bool raw, B x, usz xia, B inObj, u64 iLen, B* s_outp, B* s_errp) {
// parse options
B inObj = bi_N;
bool raw = false;
if (!q_N(w)) {
if (!isNsp(w)) thrM("•SH: 𝕨 must be a namespace");
inObj = ns_getC(w, "stdin");
if (!q_N(inObj) && !isArr(inObj)) thrM("•SH: Invalid stdin value");
B rawObj = ns_getC(w, "raw");
if (!q_N(rawObj)) raw = o2b(rawObj);
}
u64 iLen = q_N(inObj)? 0 : (raw? IA(inObj) : utf8lenB(inObj));
// allocate args // allocate args
if (isAtm(x) || RNK(x)>1) thrM("•SH: 𝕩 must be a vector of strings");
usz xia = IA(x);
if (xia==0) thrM("•SH: 𝕩 must have at least one item");
u64 arglen = 0; u64 arglen = 0;
SGetU(x) SGetU(x)
for (u64 i = 0; i < xia; i++) { for (u64 i = 0; i < xia; i++) {
@ -1240,30 +1197,11 @@ B sh_c2(B t, B w, B x) {
} }
// prepare output // prepare output
u8* op; u8* op; *s_outp = m_c8arrv(&op, oLen);
B s_out = m_c8arrv(&op, oLen); u8* ep; *s_errp = m_c8arrv(&ep, eLen);
if (oLen > 0 && oBuf != NULL) { if (oLen > 0 && oBuf != NULL) memcpy(op, oBuf, oLen*sizeof(char)); free(oBuf);
memcpy(op, oBuf, oLen*sizeof(char)); free(oBuf); if (eLen > 0 && eBuf != NULL) memcpy(ep, eBuf, eLen*sizeof(char)); free(eBuf);
} return (i32)code;
u8* ep;
B s_err = m_c8arrv(&ep, eLen);
if (eLen > 0 && eBuf != NULL) {
memcpy(ep, eBuf, eLen*sizeof(char)); free(eBuf);
}
dec(w); dec(x);
B s_outRaw = toC8Any(s_out);
B s_errRaw = toC8Any(s_err);
B s_outObj;
B s_errObj;
if (raw) {
s_outObj = s_outRaw;
s_errObj = s_errRaw;
} else {
s_outObj = utf8Decode((char*)c8any_ptr(s_outRaw), IA(s_outRaw)); dec(s_outRaw);
s_errObj = utf8Decode((char*)c8any_ptr(s_errRaw), IA(s_errRaw)); dec(s_errRaw);
}
return m_hvec3(m_i32((i32)code), s_outObj, s_errObj);
} }
#else #else
#if FOR_BUILD #if FOR_BUILD
@ -1275,7 +1213,43 @@ B sh_c2(B t, B w, B x) {
#endif #endif
#define HAS_SH 0 #define HAS_SH 0
B sh_c2(B t, B w, B x) { thrM("•SH: CBQN was compiled without <spawn.h>"); } #endif
#if HAS_SH
B sh_c2(B t, B w, B x) {
// parse options
B inObj = bi_N;
bool raw = false;
if (!q_N(w)) {
if (!isNsp(w)) thrM("•SH: 𝕨 must be a namespace");
inObj = ns_getC(w, "stdin");
if (!q_N(inObj) && !isArr(inObj)) thrM("•SH: Invalid stdin value");
B rawObj = ns_getC(w, "raw");
if (!q_N(rawObj)) raw = o2b(rawObj);
}
u64 iLen = q_N(inObj)? 0 : (raw? IA(inObj) : utf8lenB(inObj));
if (isAtm(x) || RNK(x)>1) thrM("•SH: 𝕩 must be a vector of strings");
usz xia = IA(x);
if (xia==0) thrM("•SH: 𝕩 must have at least one item");
B s_out, s_err;
i32 code = sh_core(raw, x, xia, inObj, iLen, &s_out, &s_err);
dec(w); dec(x);
B s_outObj; B s_outRaw = toC8Any(s_out);
B s_errObj; B s_errRaw = toC8Any(s_err);
if (raw) {
s_outObj = s_outRaw;
s_errObj = s_errRaw;
} else {
s_outObj = utf8Decode((char*)c8any_ptr(s_outRaw), IA(s_outRaw)); dec(s_outRaw);
s_errObj = utf8Decode((char*)c8any_ptr(s_errRaw), IA(s_errRaw)); dec(s_errRaw);
}
return m_hvec3(m_i32(code), s_outObj, s_errObj);
}
#else
B sh_c2(B t, B w, B x) { thrM("•SH: CBQN was compiled without <spawn.h>"); }
#endif #endif
B sh_c1(B t, B x) { return sh_c2(t, bi_N, x); } B sh_c1(B t, B x) { return sh_c2(t, bi_N, x); }