Last active
August 25, 2022 18:11
-
-
Save deathcap/77bbe28924948e86529468f43b837ba6 to your computer and use it in GitHub Desktop.
example of transpiling FreeBSD bin/ls/ls.c to JS using https://github.com/deathcap/transpile-c-to-js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function xo_emit_hvp(xop, fmt, vap) | |
{ | |
return xo_emit_hv(xop, fmt, vap); | |
} | |
function xo_emit_hp(xop, fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
let rc = xo_emit_hv(xop, fmt, vap); | |
; | |
return rc; | |
} | |
function xo_emit_p(fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
let rc = xo_emit_hv(0, fmt, vap); | |
; | |
return rc; | |
} | |
function xo_emit_warn_hcvp(xop, as_warning, code, fmt, vap) | |
{ | |
xo_emit_warn_hcv(xop, as_warning, code, fmt, vap); | |
} | |
function xo_emit_warn_hcp(xop, code, fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(xop, 1, code, fmt, vap); | |
; | |
} | |
function xo_emit_warn_cp(code, fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(0, 1, code, fmt, vap); | |
; | |
} | |
function xo_emit_warn_p(fmt, ...args) | |
{ | |
let code = errno; | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(0, 1, code, fmt, vap); | |
; | |
} | |
function xo_emit_warnx_p(fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(0, 1, -1, fmt, vap); | |
; | |
} | |
function xo_emit_err_p(eval, fmt, ...args) | |
{ | |
let code = errno; | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(0, 0, code, fmt, vap); | |
; | |
exit(eval); | |
} | |
function xo_emit_errx_p(eval, fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(0, 0, -1, fmt, vap); | |
; | |
exit(eval); | |
} | |
function xo_emit_errc_p(eval, code, fmt, ...args) | |
{ | |
let vap; | |
__builtin_va_start(vap); | |
xo_emit_warn_hcv(0, 0, code, fmt, vap); | |
; | |
exit(eval); | |
} | |
function main(argc, argv) | |
{ | |
let dot = "."; | |
let dotav = [dot, 0]; | |
let win; | |
let ch; | |
let fts_options; | |
let notused; | |
let p; | |
let errstr = 0; | |
setlocale(LC_ALL, ""); | |
if (isatty(STDOUT_FILENO)) | |
{ | |
termwidth = 80; | |
if (((p = getenv("COLUMNS")) !== 0) && ((p) !== '\0')) | |
termwidth = strtonum(p, 0, 0x7fffffff, errstr); | |
else | |
if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, win) !== (-1)) && (win.ws_col > 0)) | |
termwidth = win.ws_col; | |
f_nonprint = 1; | |
} | |
else | |
{ | |
f_singlecol = 1; | |
p = getenv("COLUMNS"); | |
if (p) | |
termwidth = strtonum(p, 0, 0x7fffffff, errstr); | |
} | |
if (errstr) | |
termwidth = 80; | |
fts_options = 0x010; | |
if (getenv("LS_SAMESORT")) | |
f_samesort = 1; | |
argc = xo_parse_args(argc, argv); | |
if (argc < 0) | |
return 1; | |
xo_set_flags(0, (1) << 21); | |
xo_set_version("1"); | |
while ((ch = getopt(argc, argv, "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) !== (-1)) | |
{ | |
switch (ch) | |
{ | |
case '1': | |
f_singlecol = 1; | |
f_longform = 0; | |
f_stream = 0; | |
break; | |
case 'C': | |
f_sortacross = (f_longform = (f_singlecol = 0)); | |
break; | |
case 'l': | |
f_longform = 1; | |
f_singlecol = 0; | |
f_stream = 0; | |
break; | |
case 'x': | |
f_sortacross = 1; | |
f_longform = 0; | |
f_singlecol = 0; | |
break; | |
case 'c': | |
f_statustime = 1; | |
f_accesstime = 0; | |
f_birthtime = 0; | |
break; | |
case 'u': | |
f_accesstime = 1; | |
f_statustime = 0; | |
f_birthtime = 0; | |
break; | |
case 'U': | |
f_birthtime = 1; | |
f_accesstime = 0; | |
f_statustime = 0; | |
break; | |
case 'f': | |
f_nosort = 1; | |
case 'a': | |
fts_options |= 0x020; | |
case 'A': | |
f_listdot = 1; | |
break; | |
case 'S': | |
f_sizesort = 1; | |
f_timesort = 0; | |
break; | |
case 't': | |
f_timesort = 1; | |
f_sizesort = 0; | |
break; | |
case ',': | |
f_thousands = 1; | |
break; | |
case 'B': | |
f_nonprint = 0; | |
f_octal = 1; | |
f_octal_escape = 0; | |
break; | |
case 'D': | |
f_timeformat = optarg; | |
break; | |
case 'F': | |
f_type = 1; | |
f_slash = 0; | |
break; | |
case 'G': | |
setenv("CLICOLOR", "", 1); | |
break; | |
case 'H': | |
fts_options |= 0x001; | |
f_nofollow = 0; | |
break; | |
case 'I': | |
f_noautodot = 1; | |
break; | |
case 'L': | |
fts_options &= ~0x010; | |
fts_options |= 0x002; | |
f_nofollow = 0; | |
break; | |
case 'P': | |
fts_options &= ~0x001; | |
fts_options &= ~0x002; | |
fts_options |= 0x010; | |
f_nofollow = 1; | |
break; | |
case 'R': | |
f_recursive = 1; | |
break; | |
case 'T': | |
f_sectime = 1; | |
break; | |
case 'W': | |
f_whiteout = 1; | |
break; | |
case 'Z': | |
f_label = 1; | |
break; | |
case 'b': | |
f_nonprint = 0; | |
f_octal = 0; | |
f_octal_escape = 1; | |
break; | |
case 'd': | |
f_listdir = 1; | |
f_recursive = 0; | |
break; | |
case 'g': | |
break; | |
case 'h': | |
f_humanval = 1; | |
break; | |
case 'i': | |
f_inode = 1; | |
break; | |
case 'k': | |
f_humanval = 0; | |
f_kblocks = 1; | |
break; | |
case 'm': | |
f_stream = 1; | |
f_singlecol = 0; | |
f_longform = 0; | |
break; | |
case 'n': | |
f_numericonly = 1; | |
break; | |
case 'o': | |
f_flags = 1; | |
break; | |
case 'p': | |
f_slash = 1; | |
f_type = 1; | |
break; | |
case 'q': | |
f_nonprint = 1; | |
f_octal = 0; | |
f_octal_escape = 0; | |
break; | |
case 'r': | |
f_reversesort = 1; | |
break; | |
case 's': | |
f_size = 1; | |
break; | |
case 'w': | |
f_nonprint = 0; | |
f_octal = 0; | |
f_octal_escape = 0; | |
break; | |
case 'y': | |
f_samesort = 1; | |
break; | |
default: | |
case '?': | |
usage(); | |
} | |
} | |
argc -= optind; | |
argv += optind; | |
if (((!f_listdot) && (getuid() === (0))) && (!f_noautodot)) | |
f_listdot = 1; | |
if (getenv("CLICOLOR") && (isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE"))) | |
xo_warnx("color support not compiled in"); | |
if ((((((!f_inode) && (!f_longform)) && (!f_size)) && (!f_timesort)) && (!f_sizesort)) && (!f_type)) | |
fts_options |= 0x008; | |
if ((((!f_nofollow) && (!f_longform)) && (!f_listdir)) && ((!f_type) || f_slash)) | |
fts_options |= 0x001; | |
if (f_whiteout) | |
fts_options |= 0x080; | |
if ((f_inode || f_longform) || f_size) | |
{ | |
if (f_kblocks) | |
blocksize = 2; | |
else | |
{ | |
getbsize(notused, blocksize); | |
blocksize /= 512; | |
} | |
} | |
if (f_reversesort) | |
{ | |
if ((!f_timesort) && (!f_sizesort)) | |
sortfcn = revnamecmp; | |
else | |
if (f_sizesort) | |
sortfcn = revsizecmp; | |
else | |
if (f_accesstime) | |
sortfcn = revacccmp; | |
else | |
if (f_birthtime) | |
sortfcn = revbirthcmp; | |
else | |
if (f_statustime) | |
sortfcn = revstatcmp; | |
else | |
sortfcn = revmodcmp; | |
} | |
else | |
{ | |
if ((!f_timesort) && (!f_sizesort)) | |
sortfcn = namecmp; | |
else | |
if (f_sizesort) | |
sortfcn = sizecmp; | |
else | |
if (f_accesstime) | |
sortfcn = acccmp; | |
else | |
if (f_birthtime) | |
sortfcn = birthcmp; | |
else | |
if (f_statustime) | |
sortfcn = statcmp; | |
else | |
sortfcn = modcmp; | |
} | |
if (f_singlecol) | |
printfcn = printscol; | |
else | |
if (f_longform) | |
printfcn = printlong; | |
else | |
if (f_stream) | |
printfcn = printstream; | |
else | |
printfcn = printcol; | |
xo_open_container("file-information"); | |
if (argc) | |
traverse(argc, argv, fts_options); | |
else | |
traverse(1, dotav, fts_options); | |
xo_close_container("file-information"); | |
xo_finish(); | |
exit(rval); | |
} | |
function traverse(argc, argv, options) | |
{ | |
let ftsp; | |
let p; | |
let chp; | |
let ch_options; | |
let first = 1; | |
if ((ftsp = fts_open(argv, options, f_nosort ? 0 : mastercmp)) === 0) | |
xo_err(1, "fts_open"); | |
chp = fts_children(ftsp, 0); | |
if (chp !== 0) | |
display(0, chp, options); | |
if (f_listdir) | |
return; | |
ch_options = ((!f_recursive) && (!f_label)) && (options & 0x008) ? 0x100 : 0; | |
while ((p = fts_read(ftsp)) !== 0) | |
switch (p.fts_info) | |
{ | |
case 2: | |
xo_warnx("%s: directory causes a cycle", p.fts_name); | |
break; | |
case 4: | |
case 7: | |
xo_warnx("%s: %s", p.fts_path, strerror(p.fts_errno)); | |
rval = 1; | |
break; | |
case 1: | |
if (((p.fts_level !== 0) && (p.fts_name[0] === '.')) && (!f_listdot)) | |
break; | |
if (first) | |
{ | |
first = 0; | |
xo_open_list("directory"); | |
} | |
xo_open_instance("directory"); | |
if (output) | |
{ | |
xo_emit("\n"); | |
printname("path", p.fts_path); | |
xo_emit(":\n"); | |
} | |
else | |
if (argc > 1) | |
{ | |
printname("path", p.fts_path); | |
xo_emit(":\n"); | |
output = 1; | |
} | |
chp = fts_children(ftsp, ch_options); | |
display(p, chp, options); | |
xo_close_instance("directory"); | |
if ((!f_recursive) && (chp !== 0)) | |
fts_set(ftsp, p, 4); | |
break; | |
default: | |
break; | |
} | |
if (!first) | |
xo_close_list("directory"); | |
if (errno) | |
xo_err(1, "fts_read"); | |
} | |
function display(p, list, options) | |
{ | |
let sp; | |
let d; | |
let cur; | |
let np; | |
let maxsize; | |
let maxblock; | |
let maxinode; | |
let btotal; | |
let labelstrlen; | |
let maxlen; | |
let maxnlink; | |
let maxlabelstr; | |
let sizelen; | |
let maxflags; | |
let maxgroup; | |
let maxuser; | |
let flen; | |
let ulen; | |
let glen; | |
let initmax; | |
let entries; | |
let needstats; | |
let user; | |
let group; | |
let flags; | |
let labelstr = 0; | |
let ngroup; | |
let nuser; | |
needstats = (f_inode || f_longform) || f_size; | |
flen = 0; | |
btotal = 0; | |
initmax = getenv("LS_COLWIDTHS"); | |
maxlabelstr = (maxblock = (maxlen = (maxnlink = 0))); | |
maxuser = (maxgroup = (maxflags = (maxsize = 0))); | |
maxinode = 0; | |
if ((initmax !== 0) && ((initmax) !== '\0')) | |
{ | |
let initmax2; | |
let jinitmax; | |
let ninitmax; | |
jinitmax = malloc((strlen(initmax) * 2) + 2); | |
if (jinitmax === 0) | |
xo_err(1, "malloc"); | |
initmax2 = jinitmax; | |
if ((initmax) === ':') | |
strcpy(initmax2, "0:"), initmax2 += 2; | |
else | |
/* FIXME: (initmax2++) = initmax */0, initmax2 = '\0'; | |
for (initmax++; (initmax) !== '\0'; initmax++) | |
{ | |
if ((initmax[-1] === ':') && (initmax[0] === ':')) | |
{ | |
/* FIXME: (initmax2++) = '0' */0; | |
/* FIXME: (initmax2++) = initmax[0] */0; | |
initmax2[1] = '\0'; | |
} | |
else | |
{ | |
/* FIXME: (initmax2++) = initmax[0] */0; | |
initmax2[1] = '\0'; | |
} | |
} | |
if (initmax2[-1] === ':') | |
strcpy(initmax2, "0"); | |
ninitmax = sscanf(jinitmax, " %ju : %ld : %lu : %u : %u : %i : %jd : %lu : %lu ", maxinode, maxblock, maxnlink, maxuser, maxgroup, maxflags, maxsize, maxlen, maxlabelstr); | |
f_notabs = 1; | |
switch (ninitmax) | |
{ | |
case 0: | |
maxinode = 0; | |
case 1: | |
maxblock = 0; | |
case 2: | |
maxnlink = 0; | |
case 3: | |
maxuser = 0; | |
case 4: | |
maxgroup = 0; | |
case 5: | |
maxflags = 0; | |
case 6: | |
maxsize = 0; | |
case 7: | |
maxlen = 0; | |
case 8: | |
maxlabelstr = 0; | |
f_notabs = 0; | |
default: | |
break; | |
} | |
do | |
{ | |
let i; | |
for (i = 1; maxinode > 0; i *= 10) | |
maxinode--; | |
maxinode = i - 1; | |
} | |
while (0); | |
do | |
{ | |
let i; | |
for (i = 1; maxblock > 0; i *= 10) | |
maxblock--; | |
maxblock = i - 1; | |
} | |
while (0); | |
do | |
{ | |
let i; | |
for (i = 1; maxnlink > 0; i *= 10) | |
maxnlink--; | |
maxnlink = i - 1; | |
} | |
while (0); | |
do | |
{ | |
let i; | |
for (i = 1; maxsize > 0; i *= 10) | |
maxsize--; | |
maxsize = i - 1; | |
} | |
while (0); | |
free(jinitmax); | |
} | |
d.s_size = 0; | |
sizelen = 0; | |
flags = 0; | |
for (cur = list, entries = 0; cur; cur = cur.fts_link) | |
{ | |
if ((cur.fts_info === 7) || (cur.fts_info === 10)) | |
{ | |
xo_warnx("%s: %s", cur.fts_name, strerror(cur.fts_errno)); | |
cur.fts_number = 1; | |
rval = 1; | |
continue; | |
} | |
if (p === 0) | |
{ | |
if ((cur.fts_info === 1) && (!f_listdir)) | |
{ | |
cur.fts_number = 1; | |
continue; | |
} | |
} | |
else | |
{ | |
if ((cur.fts_name[0] === '.') && (!f_listdot)) | |
{ | |
cur.fts_number = 1; | |
continue; | |
} | |
} | |
if (cur.fts_namelen > maxlen) | |
maxlen = cur.fts_namelen; | |
if (f_octal || f_octal_escape) | |
{ | |
let t = len_octal(cur.fts_name, cur.fts_namelen); | |
if (t > maxlen) | |
maxlen = t; | |
} | |
if (needstats) | |
{ | |
sp = cur.fts_statp; | |
if (sp.st_blocks > maxblock) | |
maxblock = sp.st_blocks; | |
if (sp.st_ino > maxinode) | |
maxinode = sp.st_ino; | |
if (sp.st_nlink > maxnlink) | |
maxnlink = sp.st_nlink; | |
if (sp.st_size > maxsize) | |
maxsize = sp.st_size; | |
btotal += sp.st_blocks; | |
if (f_longform) | |
{ | |
if (f_numericonly) | |
{ | |
snprintf(nuser, sizeof(nuser), "%u", sp.st_uid); | |
snprintf(ngroup, sizeof(ngroup), "%u", sp.st_gid); | |
user = nuser; | |
group = ngroup; | |
} | |
else | |
{ | |
user = user_from_uid(sp.st_uid, 0); | |
group = group_from_gid(sp.st_gid, 0); | |
} | |
if ((ulen = strlen(user)) > maxuser) | |
maxuser = ulen; | |
if ((glen = strlen(group)) > maxgroup) | |
maxgroup = glen; | |
if (f_flags) | |
{ | |
flags = fflagstostr(sp.st_flags); | |
if ((flags !== 0) && ((flags) === '\0')) | |
{ | |
free(flags); | |
flags = strdup("-"); | |
} | |
if (flags === 0) | |
xo_err(1, "fflagstostr"); | |
flen = strlen(flags); | |
if (flen > (maxflags)) | |
maxflags = flen; | |
} | |
else | |
flen = 0; | |
labelstr = 0; | |
if (f_label) | |
{ | |
let name; | |
let label; | |
let error; | |
error = mac_prepare_file_label(label); | |
if (error === (-1)) | |
{ | |
xo_warn("MAC label for %s/%s", cur.fts_parent.fts_path, cur.fts_name); | |
// FIXME: goto label_out; | |
} | |
if (cur.fts_level === 0) | |
snprintf(name, sizeof(name), "%s", cur.fts_name); | |
else | |
snprintf(name, sizeof(name), "%s/%s", cur.fts_parent.fts_accpath, cur.fts_name); | |
if (options & 0x002) | |
error = mac_get_file(name, label); | |
else | |
error = mac_get_link(name, label); | |
if (error === (-1)) | |
{ | |
xo_warn("MAC label for %s/%s", cur.fts_parent.fts_path, cur.fts_name); | |
mac_free(label); | |
// FIXME: goto label_out; | |
} | |
error = mac_to_text(label, labelstr); | |
if (error === (-1)) | |
{ | |
xo_warn("MAC label for %s/%s", cur.fts_parent.fts_path, cur.fts_name); | |
mac_free(label); | |
// FIXME: goto label_out; | |
} | |
mac_free(label); | |
label_out: | |
if (labelstr === 0) | |
labelstr = strdup("-"); | |
labelstrlen = strlen(labelstr); | |
if (labelstrlen > maxlabelstr) | |
maxlabelstr = labelstrlen; | |
} | |
else | |
labelstrlen = 0; | |
if ((np = malloc((((((sizeof(NAMES)) + labelstrlen) + ulen) + glen) + flen) + 4)) === 0) | |
xo_err(1, "malloc"); | |
np.user = np.data[0]; | |
strcpy(np.user, user); | |
np.group = np.data[ulen + 1]; | |
strcpy(np.group, group); | |
if (S_ISCHR(sp.st_mode) || S_ISBLK(sp.st_mode)) | |
{ | |
sizelen = snprintf(0, 0, "%#jx", sp.st_rdev); | |
if (d.s_size < sizelen) | |
d.s_size = sizelen; | |
} | |
if (f_flags) | |
{ | |
np.flags = np.data[(ulen + glen) + 2]; | |
strcpy(np.flags, flags); | |
free(flags); | |
} | |
if (f_label) | |
{ | |
np.label = np.data[((ulen + glen) + 2) + (f_flags ? flen + 1 : 0)]; | |
strcpy(np.label, labelstr); | |
free(labelstr); | |
} | |
cur.fts_pointer = np; | |
} | |
} | |
++entries; | |
} | |
if ((!entries) && ((!(f_longform || f_size)) || (p === 0))) | |
return; | |
d.list = list; | |
d.entries = entries; | |
d.maxlen = maxlen; | |
if (needstats) | |
{ | |
d.btotal = btotal; | |
d.s_block = snprintf(0, 0, "%lu", (maxblock + (blocksize - 1)) / blocksize); | |
d.s_flags = maxflags; | |
d.s_label = maxlabelstr; | |
d.s_group = maxgroup; | |
d.s_inode = snprintf(0, 0, "%ju", maxinode); | |
d.s_nlink = snprintf(0, 0, "%lu", maxnlink); | |
sizelen = f_humanval ? 5 : snprintf(0, 0, "%ju", maxsize); | |
if (d.s_size < sizelen) | |
d.s_size = sizelen; | |
d.s_user = maxuser; | |
} | |
if (f_thousands) | |
d.s_size += (d.s_size - 1) / 3; | |
printfcn(d); | |
output = 1; | |
if (f_longform) | |
for (cur = list; cur; cur = cur.fts_link) | |
free(cur.fts_pointer); | |
} | |
function mastercmp(a, b) | |
{ | |
let a_info; | |
let b_info; | |
a_info = (a).fts_info; | |
if (a_info === 7) | |
return 0; | |
b_info = (b).fts_info; | |
if (b_info === 7) | |
return 0; | |
if ((a_info === 10) || (b_info === 10)) | |
return namecmp(a, b); | |
if (((a_info !== b_info) && ((a).fts_level === 0)) && (!f_listdir)) | |
{ | |
if (a_info === 1) | |
return 1; | |
if (b_info === 1) | |
return -1; | |
} | |
return sortfcn(a, b); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment