mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-16 23:50:32 +00:00
Apply clang-format update to repo (#1154)
Commit bc6c183
introduced a bunch of discrepancies between what files
look like in the repo and what clang-format says they should look like.
However, there were already a few discrepancies prior to that. Most of
these discrepancies seemed to be unintentional, but a few of them were
load-bearing (e.g., a #include that violated header ordering needing
something to have been #defined by a 'later' #include.)
I opted to take what I hope is a relatively smooth-brained approach: I
reverted the .clang-format change, ran clang-format on the whole repo,
reapplied the .clang-format change, reran clang-format again, and then
reverted the commit that contained the first run. Thus the full effect
of this PR should only be to apply the changed formatting rules to the
repo, and from skimming the results, this seems to be the case.
My work can be checked by applying the short, manual commits, and then
rerunning the command listed in the autogenerated commits (those whose
messages I have prefixed auto:) and seeing if your results agree.
It might be that the other diffs should be fixed at some point but I'm
leaving that aside for now.
fd '\.c(c|pp)?$' --print0| xargs -0 clang-format -i
This commit is contained in:
parent
342d0c81e5
commit
6e6fc38935
863 changed files with 9201 additions and 4627 deletions
|
@ -280,12 +280,14 @@ static wontreturn void DieOom(void) {
|
|||
|
||||
static void *Malloc(size_t n) {
|
||||
void *p;
|
||||
if (!(p = malloc(n))) DieOom();
|
||||
if (!(p = malloc(n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Realloc(void *p, size_t n) {
|
||||
if (!(p = realloc(p, n))) DieOom();
|
||||
if (!(p = realloc(p, n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -369,8 +371,10 @@ static char *LoadSourceCode(const char *path) {
|
|||
size_t i;
|
||||
char *text;
|
||||
ssize_t rc, size;
|
||||
if ((fd = open(path, O_RDONLY)) == -1) DieSys(path);
|
||||
if ((size = lseek(fd, 0, SEEK_END)) == -1) DieSys(path);
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
DieSys(path);
|
||||
if ((size = lseek(fd, 0, SEEK_END)) == -1)
|
||||
DieSys(path);
|
||||
text = Malloc(size + 1);
|
||||
text[size] = 0;
|
||||
for (i = 0; i < size; i += rc) {
|
||||
|
@ -381,7 +385,8 @@ static char *LoadSourceCode(const char *path) {
|
|||
Die(path, "source code contains binary data");
|
||||
}
|
||||
}
|
||||
if (close(fd)) DieSys(path);
|
||||
if (close(fd))
|
||||
DieSys(path);
|
||||
HashInput(text, size);
|
||||
return text;
|
||||
}
|
||||
|
@ -488,7 +493,8 @@ static void ValidateElfImage(Elf64_Ehdr *e, Elf64_Off esize, //
|
|||
int found_load = 0;
|
||||
Elf64_Addr last_vaddr = 0;
|
||||
for (i = 0; i < e->e_phnum; ++i) {
|
||||
if (p[i].p_type != PT_LOAD) continue;
|
||||
if (p[i].p_type != PT_LOAD)
|
||||
continue;
|
||||
if (found_load && p[i].p_vaddr <= last_vaddr) {
|
||||
Die(epath, "ELF PT_LOAD segments must be ordered by p_vaddr");
|
||||
}
|
||||
|
@ -566,7 +572,8 @@ static void ValidateElfImage(Elf64_Ehdr *e, Elf64_Off esize, //
|
|||
Elf64_Off a = p[i].p_vaddr & -pagesz;
|
||||
Elf64_Off b = (p[i].p_vaddr + p[i].p_memsz + (pagesz - 1)) & -pagesz;
|
||||
for (j = i + 1; j < e->e_phnum; ++j) {
|
||||
if (p[j].p_type != PT_LOAD) continue;
|
||||
if (p[j].p_type != PT_LOAD)
|
||||
continue;
|
||||
Elf64_Off c = p[j].p_vaddr & -pagesz;
|
||||
Elf64_Off d = (p[j].p_vaddr + p[j].p_memsz + (pagesz - 1)) & -pagesz;
|
||||
if (MAX(a, c) < MIN(b, d)) {
|
||||
|
@ -627,7 +634,8 @@ static bool IsSymbolWorthyOfSymtab(Elf64_Sym *sym) {
|
|||
}
|
||||
|
||||
static void AppendZipAsset(unsigned char *lfile, unsigned char *cfile) {
|
||||
if (assets.n == 65534) Die(outpath, "fat binary has >65534 zip assets");
|
||||
if (assets.n == 65534)
|
||||
Die(outpath, "fat binary has >65534 zip assets");
|
||||
assets.p = Realloc(assets.p, (assets.n + 1) * sizeof(*assets.p));
|
||||
assets.p[assets.n].cfile = cfile;
|
||||
assets.p[assets.n].lfile = lfile;
|
||||
|
@ -666,7 +674,8 @@ static void LoadSymbols(Elf64_Ehdr *e, Elf64_Off size, const char *path) {
|
|||
const char *name = ConvertElfMachineToSymtabName(e);
|
||||
size_t name_size = strlen(name);
|
||||
struct SymbolTable *st = OpenSymbolTable(path);
|
||||
if (!st) Die(path, "could not load elf symbol table");
|
||||
if (!st)
|
||||
Die(path, "could not load elf symbol table");
|
||||
size_t data_size;
|
||||
void *data = Deflate(st, st->size, &data_size);
|
||||
uint32_t crc = crc32_z(0, st, st->size);
|
||||
|
@ -1086,9 +1095,12 @@ static void OpenLoader(struct Loader *ldr) {
|
|||
|
||||
static int PhdrFlagsToProt(Elf64_Word flags) {
|
||||
int prot = PROT_NONE;
|
||||
if (flags & PF_R) prot |= PROT_READ;
|
||||
if (flags & PF_W) prot |= PROT_WRITE;
|
||||
if (flags & PF_X) prot |= PROT_EXEC;
|
||||
if (flags & PF_R)
|
||||
prot |= PROT_READ;
|
||||
if (flags & PF_W)
|
||||
prot |= PROT_WRITE;
|
||||
if (flags & PF_X)
|
||||
prot |= PROT_EXEC;
|
||||
return prot;
|
||||
}
|
||||
|
||||
|
@ -1101,8 +1113,10 @@ static char *EncodeWordAsPrintf(char *p, uint64_t w, int bytes) {
|
|||
*p++ = c;
|
||||
} else {
|
||||
*p++ = '\\';
|
||||
if ((c & 0700)) *p++ = '0' + ((c & 0700) >> 6);
|
||||
if ((c & 0770)) *p++ = '0' + ((c & 070) >> 3);
|
||||
if ((c & 0700))
|
||||
*p++ = '0' + ((c & 0700) >> 6);
|
||||
if ((c & 0770))
|
||||
*p++ = '0' + ((c & 070) >> 3);
|
||||
*p++ = '0' + (c & 7);
|
||||
}
|
||||
}
|
||||
|
@ -1203,7 +1217,8 @@ static char *GenerateElf(char *p, struct Input *in) {
|
|||
static bool IsPhdrAllocated(struct Input *in, Elf64_Phdr *phdr) {
|
||||
int i;
|
||||
Elf64_Shdr *shdr;
|
||||
if (1) return true;
|
||||
if (1)
|
||||
return true;
|
||||
for (i = 0; i < in->elf->e_shnum; ++i) {
|
||||
if (!(shdr = GetElfSectionHeaderAddress(in->elf, in->size, i))) {
|
||||
Die(in->path, "elf section header overflow");
|
||||
|
@ -1226,7 +1241,8 @@ static struct Elf64_Sym *GetElfSymbol(struct Input *in, const char *name) {
|
|||
ss = GetElfStringTable(in->elf, in->size, ".strtab");
|
||||
sh = GetElfSymbolTable(in->elf, in->size, SHT_SYMTAB, &n);
|
||||
st = GetElfSectionAddress(in->elf, in->size, sh);
|
||||
if (!st || !ss) Die(in->path, "missing elf symbol table");
|
||||
if (!st || !ss)
|
||||
Die(in->path, "missing elf symbol table");
|
||||
for (i = sh->sh_info; i < n; ++i) {
|
||||
if (st[i].st_name && !strcmp(ss + st[i].st_name, name)) {
|
||||
return st + i;
|
||||
|
@ -1252,7 +1268,8 @@ static char *DefineMachoUuid(char *p) {
|
|||
++macholoadcount;
|
||||
load->command = MAC_LC_UUID;
|
||||
load->size = sizeof(*load);
|
||||
if (!hashes) Die(outpath, "won't generate macho uuid");
|
||||
if (!hashes)
|
||||
Die(outpath, "won't generate macho uuid");
|
||||
memcpy(load->uuid, hashpool, sizeof(load->uuid));
|
||||
return p + sizeof(*load);
|
||||
}
|
||||
|
@ -1411,7 +1428,8 @@ static char *SecondPass(char *p, struct Input *in) {
|
|||
FixupPrintf(in->printf_phoff, p - prologue);
|
||||
for (i = 0; i < in->elf->e_phnum; ++i) {
|
||||
phdr = GetElfProgramHeaderAddress(in->elf, in->size, i);
|
||||
if (phdr->p_type == PT_LOAD && !IsPhdrAllocated(in, phdr)) continue;
|
||||
if (phdr->p_type == PT_LOAD && !IsPhdrAllocated(in, phdr))
|
||||
continue;
|
||||
*(phdr2 = (Elf64_Phdr *)p) = *phdr;
|
||||
p += sizeof(Elf64_Phdr);
|
||||
if (phdr->p_filesz) {
|
||||
|
@ -1580,14 +1598,19 @@ static Elf64_Off ThirdPass(Elf64_Off offset, struct Input *in) {
|
|||
static void OpenInput(const char *path) {
|
||||
int fd;
|
||||
struct Input *in;
|
||||
if (inputs.n == ARRAYLEN(inputs.p)) Die(prog, "too many input files");
|
||||
if (inputs.n == ARRAYLEN(inputs.p))
|
||||
Die(prog, "too many input files");
|
||||
in = inputs.p + inputs.n++;
|
||||
in->path = path;
|
||||
if ((fd = open(path, O_RDONLY)) == -1) DieSys(path);
|
||||
if ((in->size = lseek(fd, 0, SEEK_END)) == -1) DieSys(path);
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
DieSys(path);
|
||||
if ((in->size = lseek(fd, 0, SEEK_END)) == -1)
|
||||
DieSys(path);
|
||||
in->map = mmap(0, in->size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (in->map == MAP_FAILED) DieSys(path);
|
||||
if (!IsElf64Binary(in->elf, in->size)) Die(path, "not an elf64 binary");
|
||||
if (in->map == MAP_FAILED)
|
||||
DieSys(path);
|
||||
if (!IsElf64Binary(in->elf, in->size))
|
||||
Die(path, "not an elf64 binary");
|
||||
HashInput(in->map, in->size);
|
||||
close(fd);
|
||||
}
|
||||
|
@ -1820,7 +1843,8 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "apelink";
|
||||
if (!prog)
|
||||
prog = "apelink";
|
||||
|
||||
// process flags
|
||||
GetOpts(argc, argv);
|
||||
|
@ -2042,7 +2066,8 @@ int main(int argc, char *argv[]) {
|
|||
// output native mach-o morph
|
||||
for (i = 0; i < inputs.n; ++i) {
|
||||
struct Input *in = inputs.p + i;
|
||||
if (in->elf->e_machine != EM_NEXGEN32E) continue;
|
||||
if (in->elf->e_machine != EM_NEXGEN32E)
|
||||
continue;
|
||||
if (GetLoader(in->elf->e_machine, _HOSTXNU)) {
|
||||
p = stpcpy(p, "if [ x\"$1\" = x--assimilate ]; then\n");
|
||||
}
|
||||
|
@ -2197,7 +2222,8 @@ int main(int argc, char *argv[]) {
|
|||
size_t compressed_size;
|
||||
struct Loader *loader;
|
||||
loader = loaders.p + i;
|
||||
if (!loader->used) continue;
|
||||
if (!loader->used)
|
||||
continue;
|
||||
compressed_data = Gzip(loader->map, loader->size, &compressed_size);
|
||||
if (loader->ddarg_skip1) {
|
||||
FixupWordAsDecimal(loader->ddarg_skip1, offset);
|
||||
|
|
|
@ -102,7 +102,8 @@ static wontreturn void Die(const char *path, const char *reason) {
|
|||
|
||||
static wontreturn void SysDie(const char *path, const char *func) {
|
||||
const char *errstr;
|
||||
if (!(errstr = _strerdoc(errno))) errstr = "Unknown error";
|
||||
if (!(errstr = _strerdoc(errno)))
|
||||
errstr = "Unknown error";
|
||||
tinyprint(2, path, ": ", func, ": ", errstr, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -180,11 +181,14 @@ static void *reballoc(void *p, size_t n, size_t z) {
|
|||
size_t c;
|
||||
assert(n >= 0);
|
||||
assert(z >= 1 && !(z & (z - 1)));
|
||||
if (ckd_mul(&n, n, z)) n = HEAP_SIZE;
|
||||
if (!p) return balloc(~n, z);
|
||||
if (ckd_mul(&n, n, z))
|
||||
n = HEAP_SIZE;
|
||||
if (!p)
|
||||
return balloc(~n, z);
|
||||
memcpy(&c, (char *)p - sizeof(c), sizeof(c));
|
||||
assert(c >= z && c < HEAP_SIZE && !(c & (c - 1)));
|
||||
if (n <= c) return p;
|
||||
if (n <= c)
|
||||
return p;
|
||||
return memcpy(balloc(~n, z), p, c);
|
||||
}
|
||||
|
||||
|
@ -264,7 +268,8 @@ static int64_t CopyFileOrDie(const char *inpath, int infd, //
|
|||
for (mode = CFR, toto = 0;; toto += exchanged) {
|
||||
if (mode == CFR) {
|
||||
got = copy_file_range(infd, 0, outfd, 0, 4194304, 0);
|
||||
if (!got) break;
|
||||
if (!got)
|
||||
break;
|
||||
if (got != -1) {
|
||||
exchanged = got;
|
||||
} else if (errno == EXDEV || // different partitions
|
||||
|
@ -278,11 +283,15 @@ static int64_t CopyFileOrDie(const char *inpath, int infd, //
|
|||
}
|
||||
} else {
|
||||
got = read(infd, buf, sizeof(buf));
|
||||
if (!got) break;
|
||||
if (got == -1) SysDie(inpath, "read");
|
||||
if (!got)
|
||||
break;
|
||||
if (got == -1)
|
||||
SysDie(inpath, "read");
|
||||
wrote = write(outfd, buf, got);
|
||||
if (wrote == -1) SysDie(outpath, "write");
|
||||
if (wrote != got) Die(outpath, "posix violated");
|
||||
if (wrote == -1)
|
||||
SysDie(outpath, "write");
|
||||
if (wrote != got)
|
||||
Die(outpath, "posix violated");
|
||||
exchanged = wrote;
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +335,8 @@ int main(int argc, char *argv[]) {
|
|||
// on modern systems that it isn't worth supporting the byzantine
|
||||
// standard posix ar flags intended to improve cassette tape perf
|
||||
SortChars(flags, strlen(flags));
|
||||
if (*flags == 'D') ++flags;
|
||||
if (*flags == 'D')
|
||||
++flags;
|
||||
if (!IsEqual(flags, "cr") && //
|
||||
!IsEqual(flags, "cru") && //
|
||||
!IsEqual(flags, "crsu") && //
|
||||
|
@ -349,14 +359,22 @@ int main(int argc, char *argv[]) {
|
|||
for (objectid = 0;;) {
|
||||
struct stat st;
|
||||
const char *arg;
|
||||
if (!(arg = getargs_next(&ga))) break;
|
||||
if (endswith(arg, "/")) continue;
|
||||
if (endswith(arg, ".pkg")) continue;
|
||||
if (stat(arg, &st)) SysDie(arg, "stat");
|
||||
if (S_ISDIR(st.st_mode)) continue;
|
||||
if (!st.st_size) Die(arg, "file is empty");
|
||||
if (st.st_size > 0x7ffff000) Die(arg, "file too large");
|
||||
if ((fd = open(arg, O_RDONLY)) == -1) SysDie(arg, "open");
|
||||
if (!(arg = getargs_next(&ga)))
|
||||
break;
|
||||
if (endswith(arg, "/"))
|
||||
continue;
|
||||
if (endswith(arg, ".pkg"))
|
||||
continue;
|
||||
if (stat(arg, &st))
|
||||
SysDie(arg, "stat");
|
||||
if (S_ISDIR(st.st_mode))
|
||||
continue;
|
||||
if (!st.st_size)
|
||||
Die(arg, "file is empty");
|
||||
if (st.st_size > 0x7ffff000)
|
||||
Die(arg, "file too large");
|
||||
if ((fd = open(arg, O_RDONLY)) == -1)
|
||||
SysDie(arg, "open");
|
||||
AppendArg(&args, StrDup(arg));
|
||||
AppendInt(&sizes, st.st_size);
|
||||
AppendInt(&modes, st.st_mode);
|
||||
|
@ -374,25 +392,35 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
size_t mapsize = st.st_size;
|
||||
void *elf = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (elf == MAP_FAILED) SysDie(arg, "mmap");
|
||||
if (!IsElf64Binary(elf, mapsize)) Die(arg, "not an elf64 binary");
|
||||
if (elf == MAP_FAILED)
|
||||
SysDie(arg, "mmap");
|
||||
if (!IsElf64Binary(elf, mapsize))
|
||||
Die(arg, "not an elf64 binary");
|
||||
char *strs = GetElfStringTable(elf, mapsize, ".strtab");
|
||||
if (!strs) Die(arg, "elf .strtab not found");
|
||||
if (!strs)
|
||||
Die(arg, "elf .strtab not found");
|
||||
Elf64_Xword symcount;
|
||||
Elf64_Shdr *symsec = GetElfSymbolTable(elf, mapsize, SHT_SYMTAB, &symcount);
|
||||
Elf64_Sym *syms = GetElfSectionAddress(elf, mapsize, symsec);
|
||||
if (!syms) Die(arg, "elf symbol table not found");
|
||||
if (!syms)
|
||||
Die(arg, "elf symbol table not found");
|
||||
for (Elf64_Xword j = symsec->sh_info; j < symcount; ++j) {
|
||||
if (!syms[j].st_name) continue;
|
||||
if (syms[j].st_shndx == SHN_UNDEF) continue;
|
||||
if (syms[j].st_shndx == SHN_COMMON) continue;
|
||||
if (!syms[j].st_name)
|
||||
continue;
|
||||
if (syms[j].st_shndx == SHN_UNDEF)
|
||||
continue;
|
||||
if (syms[j].st_shndx == SHN_COMMON)
|
||||
continue;
|
||||
const char *symname = GetElfString(elf, mapsize, strs, syms[j].st_name);
|
||||
if (!symname) Die(arg, "elf symbol name corrupted");
|
||||
if (!symname)
|
||||
Die(arg, "elf symbol name corrupted");
|
||||
AppendBytes(&symbols, symname, strlen(symname) + 1);
|
||||
AppendInt(&symnames, objectid);
|
||||
}
|
||||
if (munmap(elf, mapsize)) SysDie(arg, "munmap");
|
||||
if (close(fd)) SysDie(arg, "close");
|
||||
if (munmap(elf, mapsize))
|
||||
SysDie(arg, "munmap");
|
||||
if (close(fd))
|
||||
SysDie(arg, "close");
|
||||
++objectid;
|
||||
}
|
||||
getargs_destroy(&ga);
|
||||
|
|
|
@ -197,7 +197,8 @@ static void GetElfHeader(Elf64_Ehdr *ehdr, const char *image, size_t n) {
|
|||
const char *p, *e;
|
||||
for (p = image, e = p + MIN(n, 8192); p < e; ++p) {
|
||||
TryAgain:
|
||||
if (READ64LE(p) != READ64LE("printf '")) continue;
|
||||
if (READ64LE(p) != READ64LE("printf '"))
|
||||
continue;
|
||||
for (i = 0, p += 8; p + 3 < e && (c = *p++) != '\'';) {
|
||||
if (c == '\\') {
|
||||
if ('0' <= *p && *p <= '7') {
|
||||
|
@ -378,18 +379,24 @@ static ssize_t Pwrite(int fd, const void *data, size_t size, uint64_t offset) {
|
|||
|
||||
static int GetMode(int fd) {
|
||||
struct stat st;
|
||||
if (fstat(fd, &st)) DieSys(path);
|
||||
if (fstat(fd, &st))
|
||||
DieSys(path);
|
||||
return st.st_mode & 0777;
|
||||
}
|
||||
|
||||
static void CopyFile(int infd, const char *map, size_t size, //
|
||||
const void *hdr, size_t hdrsize) {
|
||||
int outfd;
|
||||
if (!outpath) return;
|
||||
if ((outfd = creat(outpath, GetMode(infd))) == -1) DieSys(outpath);
|
||||
if (hdrsize && Write(outfd, hdr, hdrsize) == -1) DieSys(outpath);
|
||||
if (Write(outfd, map + hdrsize, size - hdrsize) == -1) DieSys(outpath);
|
||||
if (close(outfd)) DieSys(outpath);
|
||||
if (!outpath)
|
||||
return;
|
||||
if ((outfd = creat(outpath, GetMode(infd))) == -1)
|
||||
DieSys(outpath);
|
||||
if (hdrsize && Write(outfd, hdr, hdrsize) == -1)
|
||||
DieSys(outpath);
|
||||
if (Write(outfd, map + hdrsize, size - hdrsize) == -1)
|
||||
DieSys(outpath);
|
||||
if (close(outfd))
|
||||
DieSys(outpath);
|
||||
}
|
||||
|
||||
static void WriteOutput(int infd, const char *map, size_t size, //
|
||||
|
@ -398,7 +405,8 @@ static void WriteOutput(int infd, const char *map, size_t size, //
|
|||
if (outpath) {
|
||||
CopyFile(infd, map, size, hdr, hdrsize);
|
||||
} else if (g_clobber) {
|
||||
if (Pwrite(infd, hdr, hdrsize, 0) == -1) DieSys(path);
|
||||
if (Pwrite(infd, hdr, hdrsize, 0) == -1)
|
||||
DieSys(path);
|
||||
} else {
|
||||
omode = GetMode(infd);
|
||||
oflags = O_WRONLY | O_CREAT | (g_force ? O_TRUNC : O_EXCL);
|
||||
|
@ -406,10 +414,14 @@ static void WriteOutput(int infd, const char *map, size_t size, //
|
|||
if (strlcat(bakpath, ".bak", sizeof(bakpath)) >= sizeof(bakpath)) {
|
||||
Die(path, "filename too long");
|
||||
}
|
||||
if ((outfd = open(bakpath, oflags, omode)) == -1) DieSys(bakpath);
|
||||
if (Write(outfd, map, size) == -1) DieSys(bakpath);
|
||||
if (close(outfd)) DieSys(bakpath);
|
||||
if (Pwrite(infd, hdr, hdrsize, 0) == -1) DieSys(path);
|
||||
if ((outfd = open(bakpath, oflags, omode)) == -1)
|
||||
DieSys(bakpath);
|
||||
if (Write(outfd, map, size) == -1)
|
||||
DieSys(bakpath);
|
||||
if (close(outfd))
|
||||
DieSys(bakpath);
|
||||
if (Pwrite(infd, hdr, hdrsize, 0) == -1)
|
||||
DieSys(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,11 +450,15 @@ static void Assimilate(void) {
|
|||
int oflags;
|
||||
ssize_t size;
|
||||
oflags = outpath ? O_RDONLY : O_RDWR;
|
||||
if ((fd = open(path, oflags)) == -1) DieSys(path);
|
||||
if ((size = lseek(fd, 0, SEEK_END)) == -1) DieSys(path);
|
||||
if (size < 64) Die(path, "ape executables must be at least 64 bytes");
|
||||
if ((fd = open(path, oflags)) == -1)
|
||||
DieSys(path);
|
||||
if ((size = lseek(fd, 0, SEEK_END)) == -1)
|
||||
DieSys(path);
|
||||
if (size < 64)
|
||||
Die(path, "ape executables must be at least 64 bytes");
|
||||
p = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (p == MAP_FAILED) DieSys(path);
|
||||
if (p == MAP_FAILED)
|
||||
DieSys(path);
|
||||
|
||||
if (READ32LE(p) == READ32LE("\177ELF")) {
|
||||
Elf64_Ehdr *ehdr;
|
||||
|
@ -604,8 +620,10 @@ static void Assimilate(void) {
|
|||
AssimilateMacho(fd, p, size);
|
||||
}
|
||||
|
||||
if (munmap(p, size)) DieSys(path);
|
||||
if (close(fd)) DieSys(path);
|
||||
if (munmap(p, size))
|
||||
DieSys(path);
|
||||
if (close(fd))
|
||||
DieSys(path);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
|
|
@ -51,13 +51,15 @@ void Multiply%dx%d(uint64_t C[%d], const uint64_t A[%d], const uint64_t B[%d]) {
|
|||
Rs = gc(calloc(sizeof(*Rs), n + m + 1));
|
||||
Ra = gc(calloc(sizeof(*Ra), n + m + 1));
|
||||
for (j = 0; j < n; ++j) {
|
||||
if (j) printf(", ");
|
||||
if (j)
|
||||
printf(", ");
|
||||
printf("H%d", j);
|
||||
}
|
||||
printf(";\n");
|
||||
printf(" uint64_t ");
|
||||
for (j = 0; j < n + m; ++j) {
|
||||
if (j) printf(", ");
|
||||
if (j)
|
||||
printf(", ");
|
||||
printf("R%d", j);
|
||||
}
|
||||
printf(";\n");
|
||||
|
|
|
@ -60,7 +60,8 @@ int main(int argc, char *argv[]) {
|
|||
int i, mode;
|
||||
char *endptr;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "chmod";
|
||||
if (!prog)
|
||||
prog = "chmod";
|
||||
GetOpts(argc, argv);
|
||||
if (argc - optind < 2) {
|
||||
tinyprint(2, prog, ": missing operand\n", NULL);
|
||||
|
|
|
@ -364,8 +364,10 @@ char *Slurp(const char *path) {
|
|||
bool HasFlag(const char *flags, const char *s) {
|
||||
char buf[256];
|
||||
size_t n = strlen(s);
|
||||
if (!flags) return false;
|
||||
if (n + 2 > sizeof(buf)) return false;
|
||||
if (!flags)
|
||||
return false;
|
||||
if (n + 2 > sizeof(buf))
|
||||
return false;
|
||||
memcpy(buf, s, n);
|
||||
buf[n] = '\n';
|
||||
buf[n + 1] = 0;
|
||||
|
@ -375,18 +377,29 @@ bool HasFlag(const char *flags, const char *s) {
|
|||
bool IsGccOnlyFlag(const char *s) {
|
||||
if (s[0] == '-') {
|
||||
if (s[1] == 'f') {
|
||||
if (startswith(s, "-ffixed-")) return true;
|
||||
if (startswith(s, "-fcall-saved")) return true;
|
||||
if (startswith(s, "-fcall-used")) return true;
|
||||
if (startswith(s, "-fgcse-")) return true;
|
||||
if (startswith(s, "-fvect-cost-model=")) return true;
|
||||
if (startswith(s, "-fsimd-cost-model=")) return true;
|
||||
if (startswith(s, "-fopt-info")) return true;
|
||||
if (startswith(s, "-ffixed-"))
|
||||
return true;
|
||||
if (startswith(s, "-fcall-saved"))
|
||||
return true;
|
||||
if (startswith(s, "-fcall-used"))
|
||||
return true;
|
||||
if (startswith(s, "-fgcse-"))
|
||||
return true;
|
||||
if (startswith(s, "-fvect-cost-model="))
|
||||
return true;
|
||||
if (startswith(s, "-fsimd-cost-model="))
|
||||
return true;
|
||||
if (startswith(s, "-fopt-info"))
|
||||
return true;
|
||||
}
|
||||
if (startswith(s, "-mstringop-strategy=")) return true;
|
||||
if (startswith(s, "-mpreferred-stack-boundary=")) return true;
|
||||
if (startswith(s, "-Wframe-larger-than=")) return true;
|
||||
if (startswith(s, "-Walloca-larger-than=")) return true;
|
||||
if (startswith(s, "-mstringop-strategy="))
|
||||
return true;
|
||||
if (startswith(s, "-mpreferred-stack-boundary="))
|
||||
return true;
|
||||
if (startswith(s, "-Wframe-larger-than="))
|
||||
return true;
|
||||
if (startswith(s, "-Walloca-larger-than="))
|
||||
return true;
|
||||
}
|
||||
static bool once;
|
||||
static char *gcc_only_flags;
|
||||
|
@ -409,10 +422,14 @@ bool IsClangOnlyFlag(const char *s) {
|
|||
|
||||
bool FileExistsAndIsNewerThan(const char *filepath, const char *thanpath) {
|
||||
struct stat st1, st2;
|
||||
if (stat(filepath, &st1) == -1) return false;
|
||||
if (stat(thanpath, &st2) == -1) return false;
|
||||
if (st1.st_mtim.tv_sec < st2.st_mtim.tv_sec) return false;
|
||||
if (st1.st_mtim.tv_sec > st2.st_mtim.tv_sec) return true;
|
||||
if (stat(filepath, &st1) == -1)
|
||||
return false;
|
||||
if (stat(thanpath, &st2) == -1)
|
||||
return false;
|
||||
if (st1.st_mtim.tv_sec < st2.st_mtim.tv_sec)
|
||||
return false;
|
||||
if (st1.st_mtim.tv_sec > st2.st_mtim.tv_sec)
|
||||
return true;
|
||||
return st1.st_mtim.tv_nsec >= st2.st_mtim.tv_nsec;
|
||||
}
|
||||
|
||||
|
@ -499,44 +516,55 @@ static int GetBaseCpuFreqMhz(void) {
|
|||
|
||||
void PlanResource(int resource, struct rlimit rlim) {
|
||||
struct rlimit prior;
|
||||
if (getrlimit(resource, &prior)) return;
|
||||
if (getrlimit(resource, &prior))
|
||||
return;
|
||||
rlim.rlim_cur = MIN(rlim.rlim_cur, prior.rlim_max);
|
||||
rlim.rlim_max = MIN(rlim.rlim_max, prior.rlim_max);
|
||||
posix_spawnattr_setrlimit(&spawnattr, resource, &rlim);
|
||||
}
|
||||
|
||||
void SetCpuLimit(int secs) {
|
||||
if (secs <= 0) return;
|
||||
if (IsWindows()) return;
|
||||
if (secs <= 0)
|
||||
return;
|
||||
if (IsWindows())
|
||||
return;
|
||||
#ifdef __x86_64__
|
||||
int mhz, lim;
|
||||
if (!(mhz = GetBaseCpuFreqMhz())) return;
|
||||
if (!(mhz = GetBaseCpuFreqMhz()))
|
||||
return;
|
||||
lim = ceil(3100. / mhz * secs);
|
||||
PlanResource(RLIMIT_CPU, (struct rlimit){lim, lim + 1});
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetFszLimit(long n) {
|
||||
if (n <= 0) return;
|
||||
if (IsWindows()) return;
|
||||
if (n <= 0)
|
||||
return;
|
||||
if (IsWindows())
|
||||
return;
|
||||
PlanResource(RLIMIT_FSIZE, (struct rlimit){n, n + (n >> 1)});
|
||||
}
|
||||
|
||||
void SetMemLimit(long n) {
|
||||
if (n <= 0) return;
|
||||
if (IsWindows() || IsXnu()) return;
|
||||
if (n <= 0)
|
||||
return;
|
||||
if (IsWindows() || IsXnu())
|
||||
return;
|
||||
PlanResource(RLIMIT_AS, (struct rlimit){n, n});
|
||||
}
|
||||
|
||||
void SetStkLimit(long n) {
|
||||
if (IsWindows()) return;
|
||||
if (n <= 0) return;
|
||||
if (IsWindows())
|
||||
return;
|
||||
if (n <= 0)
|
||||
return;
|
||||
n = MAX(n, PTHREAD_STACK_MIN * 2);
|
||||
PlanResource(RLIMIT_STACK, (struct rlimit){n, n});
|
||||
}
|
||||
|
||||
void SetProLimit(long n) {
|
||||
if (n <= 0) return;
|
||||
if (n <= 0)
|
||||
return;
|
||||
PlanResource(RLIMIT_NPROC, (struct rlimit){n, n});
|
||||
}
|
||||
|
||||
|
@ -586,7 +614,8 @@ char *AddShellQuotes(const char *s) {
|
|||
}
|
||||
p[j++] = '\'';
|
||||
p[j] = 0;
|
||||
if ((q = realloc(p, j + 1))) p = q;
|
||||
if ((q = realloc(p, j + 1)))
|
||||
p = q;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -659,7 +688,8 @@ int Launch(void) {
|
|||
break;
|
||||
}
|
||||
if ((rc = read(pipefds[0], buf, sizeof(buf))) != -1) {
|
||||
if (!(got = rc)) break;
|
||||
if (!(got = rc))
|
||||
break;
|
||||
appendd(&output, buf, got);
|
||||
if (outquota > 0 && appendz(output).i > outquota) {
|
||||
kill(pid, SIGXFSZ);
|
||||
|
@ -789,7 +819,8 @@ char *MakeTmpOut(const char *path) {
|
|||
g_tmpout_original = path;
|
||||
p = stpcpy(p, __get_tmpdir());
|
||||
while ((c = *path++)) {
|
||||
if (c == '/') c = '_';
|
||||
if (c == '/')
|
||||
c = '_';
|
||||
if (p == e) {
|
||||
tinyprint(2, program_invocation_short_name,
|
||||
": fatal error: MakeTmpOut() generated temporary filename "
|
||||
|
@ -826,7 +857,8 @@ int main(int argc, char *argv[]) {
|
|||
stkquota = 8 * 1024 * 1024; // bytes
|
||||
fszquota = 256 * 1000 * 1000; // bytes
|
||||
memquota = 2048L * 1024 * 1024; // bytes
|
||||
if ((s = getenv("V"))) verbose = atoi(s);
|
||||
if ((s = getenv("V")))
|
||||
verbose = atoi(s);
|
||||
while ((opt = getopt(argc, argv, "hnstvwA:C:F:L:M:O:P:T:V:S:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
|
@ -897,7 +929,8 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
cmd = argv[optind];
|
||||
if (!strchr(cmd, '/')) {
|
||||
if (!(cmd = commandv(cmd, ccpath, sizeof(ccpath)))) exit(127);
|
||||
if (!(cmd = commandv(cmd, ccpath, sizeof(ccpath))))
|
||||
exit(127);
|
||||
}
|
||||
|
||||
s = basename(strdup(cmd));
|
||||
|
@ -1020,13 +1053,20 @@ int main(int argc, char *argv[]) {
|
|||
#ifdef __x86_64__
|
||||
} else if (!strcmp(argv[i], "-march=native")) {
|
||||
const struct X86ProcessorModel *model;
|
||||
if (X86_HAVE(XOP)) AddArg("-mxop");
|
||||
if (X86_HAVE(SSE4A)) AddArg("-msse4a");
|
||||
if (X86_HAVE(SSE3)) AddArg("-msse3");
|
||||
if (X86_HAVE(SSSE3)) AddArg("-mssse3");
|
||||
if (X86_HAVE(SSE4_1)) AddArg("-msse4.1");
|
||||
if (X86_HAVE(SSE4_2)) AddArg("-msse4.2");
|
||||
if (X86_HAVE(AVX)) AddArg("-mavx");
|
||||
if (X86_HAVE(XOP))
|
||||
AddArg("-mxop");
|
||||
if (X86_HAVE(SSE4A))
|
||||
AddArg("-msse4a");
|
||||
if (X86_HAVE(SSE3))
|
||||
AddArg("-msse3");
|
||||
if (X86_HAVE(SSSE3))
|
||||
AddArg("-mssse3");
|
||||
if (X86_HAVE(SSE4_1))
|
||||
AddArg("-msse4.1");
|
||||
if (X86_HAVE(SSE4_2))
|
||||
AddArg("-msse4.2");
|
||||
if (X86_HAVE(AVX))
|
||||
AddArg("-mavx");
|
||||
if (X86_HAVE(AVX2)) {
|
||||
AddArg("-mavx2");
|
||||
if (isgcc) {
|
||||
|
@ -1034,27 +1074,48 @@ int main(int argc, char *argv[]) {
|
|||
AddArg("-Wa,-msse2avx");
|
||||
}
|
||||
}
|
||||
if (X86_HAVE(AVX512F)) AddArg("-mavx512f");
|
||||
if (X86_HAVE(AVX512PF)) AddArg("-mavx512pf");
|
||||
if (X86_HAVE(AVX512ER)) AddArg("-mavx512er");
|
||||
if (X86_HAVE(AVX512CD)) AddArg("-mavx512cd");
|
||||
if (X86_HAVE(AVX512VL)) AddArg("-mavx512vl");
|
||||
if (X86_HAVE(AVX512BW)) AddArg("-mavx512bw");
|
||||
if (X86_HAVE(AVX512DQ)) AddArg("-mavx512dq");
|
||||
if (X86_HAVE(AVX512IFMA)) AddArg("-mavx512ifma");
|
||||
if (X86_HAVE(AVX512VBMI)) AddArg("-mavx512vbmi");
|
||||
if (X86_HAVE(SHA)) AddArg("-msha");
|
||||
if (X86_HAVE(AES)) AddArg("-maes");
|
||||
if (X86_HAVE(VAES)) AddArg("-mvaes");
|
||||
if (X86_HAVE(PCLMUL)) AddArg("-mpclmul");
|
||||
if (X86_HAVE(FSGSBASE)) AddArg("-mfsgsbase");
|
||||
if (X86_HAVE(F16C)) AddArg("-mf16c");
|
||||
if (X86_HAVE(FMA)) AddArg("-mfma");
|
||||
if (X86_HAVE(POPCNT)) AddArg("-mpopcnt");
|
||||
if (X86_HAVE(BMI)) AddArg("-mbmi");
|
||||
if (X86_HAVE(BMI2)) AddArg("-mbmi2");
|
||||
if (X86_HAVE(ADX)) AddArg("-madx");
|
||||
if (X86_HAVE(FXSR)) AddArg("-mfxsr");
|
||||
if (X86_HAVE(AVX512F))
|
||||
AddArg("-mavx512f");
|
||||
if (X86_HAVE(AVX512PF))
|
||||
AddArg("-mavx512pf");
|
||||
if (X86_HAVE(AVX512ER))
|
||||
AddArg("-mavx512er");
|
||||
if (X86_HAVE(AVX512CD))
|
||||
AddArg("-mavx512cd");
|
||||
if (X86_HAVE(AVX512VL))
|
||||
AddArg("-mavx512vl");
|
||||
if (X86_HAVE(AVX512BW))
|
||||
AddArg("-mavx512bw");
|
||||
if (X86_HAVE(AVX512DQ))
|
||||
AddArg("-mavx512dq");
|
||||
if (X86_HAVE(AVX512IFMA))
|
||||
AddArg("-mavx512ifma");
|
||||
if (X86_HAVE(AVX512VBMI))
|
||||
AddArg("-mavx512vbmi");
|
||||
if (X86_HAVE(SHA))
|
||||
AddArg("-msha");
|
||||
if (X86_HAVE(AES))
|
||||
AddArg("-maes");
|
||||
if (X86_HAVE(VAES))
|
||||
AddArg("-mvaes");
|
||||
if (X86_HAVE(PCLMUL))
|
||||
AddArg("-mpclmul");
|
||||
if (X86_HAVE(FSGSBASE))
|
||||
AddArg("-mfsgsbase");
|
||||
if (X86_HAVE(F16C))
|
||||
AddArg("-mf16c");
|
||||
if (X86_HAVE(FMA))
|
||||
AddArg("-mfma");
|
||||
if (X86_HAVE(POPCNT))
|
||||
AddArg("-mpopcnt");
|
||||
if (X86_HAVE(BMI))
|
||||
AddArg("-mbmi");
|
||||
if (X86_HAVE(BMI2))
|
||||
AddArg("-mbmi2");
|
||||
if (X86_HAVE(ADX))
|
||||
AddArg("-madx");
|
||||
if (X86_HAVE(FXSR))
|
||||
AddArg("-mfxsr");
|
||||
if ((model = getx86processormodel(kX86ProcessorModelKey))) {
|
||||
switch (model->march) {
|
||||
case X86_MARCH_CORE2:
|
||||
|
@ -1123,9 +1184,11 @@ int main(int argc, char *argv[]) {
|
|||
#endif /* __x86_64__ */
|
||||
|
||||
} else if (!strcmp(argv[i], "-fsanitize=address")) {
|
||||
if (isgcc && ccversion >= 6) wantasan = true;
|
||||
if (isgcc && ccversion >= 6)
|
||||
wantasan = true;
|
||||
} else if (!strcmp(argv[i], "-fsanitize=undefined")) {
|
||||
if (isgcc && ccversion >= 6) wantubsan = true;
|
||||
if (isgcc && ccversion >= 6)
|
||||
wantubsan = true;
|
||||
} else if (!strcmp(argv[i], "-fno-sanitize=address")) {
|
||||
wantasan = false;
|
||||
} else if (!strcmp(argv[i], "-fno-sanitize=undefined")) {
|
||||
|
@ -1134,14 +1197,18 @@ int main(int argc, char *argv[]) {
|
|||
wantasan = false;
|
||||
wantubsan = false;
|
||||
} else if (!strcmp(argv[i], "-fno-sanitize=null")) {
|
||||
if (isgcc && ccversion >= 6) no_sanitize_null = true;
|
||||
if (isgcc && ccversion >= 6)
|
||||
no_sanitize_null = true;
|
||||
} else if (!strcmp(argv[i], "-fno-sanitize=alignment")) {
|
||||
if (isgcc && ccversion >= 6) no_sanitize_alignment = true;
|
||||
if (isgcc && ccversion >= 6)
|
||||
no_sanitize_alignment = true;
|
||||
} else if (!strcmp(argv[i], "-fno-sanitize=pointer-overflow")) {
|
||||
if (isgcc && ccversion >= 6) no_sanitize_pointer_overflow = true;
|
||||
if (isgcc && ccversion >= 6)
|
||||
no_sanitize_pointer_overflow = true;
|
||||
} else if (startswith(argv[i], "-fsanitize=implicit") &&
|
||||
strstr(argv[i], "integer")) {
|
||||
if (isgcc) AddArg(argv[i]);
|
||||
if (isgcc)
|
||||
AddArg(argv[i]);
|
||||
} else if (strstr(argv[i], "stack-protector")) {
|
||||
if (isclang || (isgcc && ccversion >= 6)) {
|
||||
AddArg(argv[i]);
|
||||
|
@ -1158,7 +1225,8 @@ int main(int argc, char *argv[]) {
|
|||
colorflag = argv[i];
|
||||
} else if (startswith(argv[i], "-R") ||
|
||||
!strcmp(argv[i], "-fsave-optimization-record")) {
|
||||
if (isclang) AddArg(argv[i]);
|
||||
if (isclang)
|
||||
AddArg(argv[i]);
|
||||
} else if (isclang && startswith(argv[i], "--debug-prefix-map")) {
|
||||
/* llvm doesn't provide a gas interface so simulate w/ clang */
|
||||
AddArg(xstrcat("-f", argv[i] + 2));
|
||||
|
@ -1381,11 +1449,14 @@ int main(int argc, char *argv[]) {
|
|||
if (verbose < 1) {
|
||||
/* make silent mode, i.e. `V=0 make o//target` */
|
||||
appendr(&command, 0);
|
||||
if (!action) action = "BUILD";
|
||||
if (!outpath) outpath = shortened;
|
||||
if (!action)
|
||||
action = "BUILD";
|
||||
if (!outpath)
|
||||
outpath = shortened;
|
||||
n = strlen(action);
|
||||
appends(&command, action);
|
||||
do appendw(&command, ' '), ++n;
|
||||
do
|
||||
appendw(&command, ' '), ++n;
|
||||
while (n < 15);
|
||||
appends(&command, outpath);
|
||||
n += strlen(outpath);
|
||||
|
@ -1395,7 +1466,8 @@ int main(int argc, char *argv[]) {
|
|||
appendw(&output, READ32LE("..."));
|
||||
} else {
|
||||
if (n < m && (__nocolor || !ischardev(2))) {
|
||||
while (n < m) appendw(&command, ' '), ++n;
|
||||
while (n < m)
|
||||
appendw(&command, ' '), ++n;
|
||||
}
|
||||
appendd(&output, command, n);
|
||||
}
|
||||
|
@ -1411,7 +1483,8 @@ int main(int argc, char *argv[]) {
|
|||
j += (j - 1) / 3;
|
||||
j += 1 + 3;
|
||||
j += 1 + 3;
|
||||
while (i < j) appendw(&output, ' '), ++i;
|
||||
while (i < j)
|
||||
appendw(&output, ' '), ++i;
|
||||
if (us > timeout * 1000000ull / 2) {
|
||||
if (us > timeout * 1000000ull) {
|
||||
PrintRed();
|
||||
|
@ -1436,7 +1509,8 @@ int main(int argc, char *argv[]) {
|
|||
j += (j - 1) / 3;
|
||||
j += 1 + 3;
|
||||
j += 1 + 3;
|
||||
while (i < j) appendw(&output, ' '), ++i;
|
||||
while (i < j)
|
||||
appendw(&output, ' '), ++i;
|
||||
if ((isproblematic = us > cpuquota * 1000000ull / 2)) {
|
||||
if (us > cpuquota * 1000000ull - (cpuquota * 1000000ull) / 5) {
|
||||
PrintRed();
|
||||
|
@ -1455,7 +1529,8 @@ int main(int argc, char *argv[]) {
|
|||
i = FormatUint64Thousands(buf, usage.ru_maxrss) - buf;
|
||||
j = ceil(log10(memquota / 1024));
|
||||
j += (j - 1) / 3;
|
||||
while (i < j) appendw(&output, ' '), ++i;
|
||||
while (i < j)
|
||||
appendw(&output, ' '), ++i;
|
||||
if ((isproblematic = usage.ru_maxrss * 1024 > memquota / 2)) {
|
||||
if (usage.ru_maxrss * 1024 > memquota - memquota / 5) {
|
||||
PrintRed();
|
||||
|
@ -1473,7 +1548,8 @@ int main(int argc, char *argv[]) {
|
|||
if (fszquota > 0) {
|
||||
us = usage.ru_inblock + usage.ru_oublock;
|
||||
i = FormatUint64Thousands(buf, us) - buf;
|
||||
while (i < 7) appendw(&output, ' '), ++i;
|
||||
while (i < 7)
|
||||
appendw(&output, ' '), ++i;
|
||||
appends(&output, buf);
|
||||
appendw(&output, READ32LE("iop "));
|
||||
n += i + 4;
|
||||
|
@ -1516,7 +1592,8 @@ int main(int argc, char *argv[]) {
|
|||
if (errno == EINTR) {
|
||||
s = "notice: compile output truncated\n";
|
||||
} else {
|
||||
if (!exitcode) exitcode = 55;
|
||||
if (!exitcode)
|
||||
exitcode = 55;
|
||||
s = "error: compile failed to write result\n";
|
||||
}
|
||||
write(2, s, strlen(s));
|
||||
|
|
|
@ -182,8 +182,10 @@ bool MovePreservingDestinationInode(const char *from, const char *to) {
|
|||
void Cp(char *src, char *dst) {
|
||||
ssize_t rc;
|
||||
const char *s;
|
||||
if (strlen(src) + 1 > PATH_MAX) _Exit(2);
|
||||
if (strlen(dst) + 1 > PATH_MAX) _Exit(2);
|
||||
if (strlen(src) + 1 > PATH_MAX)
|
||||
_Exit(2);
|
||||
if (strlen(dst) + 1 > PATH_MAX)
|
||||
_Exit(2);
|
||||
basename(src);
|
||||
basename(dst);
|
||||
if (IsDirectory(src)) {
|
||||
|
@ -243,7 +245,8 @@ int main(int argc, char *argv[]) {
|
|||
int i;
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "cp";
|
||||
if (!prog)
|
||||
prog = "cp";
|
||||
|
||||
GetOpts(argc, argv);
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ int main(int argc, char *argv[]) {
|
|||
const char *oufile = "/dev/stdout";
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "dd";
|
||||
if (!prog)
|
||||
prog = "dd";
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
|
||||
|
@ -65,14 +66,16 @@ int main(int argc, char *argv[]) {
|
|||
argv[i][2] == '=') {
|
||||
infile = argv[i] + 3 + (argv[i][3] == '"');
|
||||
p = strchr(infile, '"');
|
||||
if (p) *p = 0;
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
} else if (argv[i][0] == 'o' && //
|
||||
argv[i][1] == 'f' && //
|
||||
argv[i][2] == '=') {
|
||||
oufile = argv[i] + 3 + (argv[i][3] == '"');
|
||||
p = strchr(infile, '"');
|
||||
if (p) *p = 0;
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
} else if (argv[i][0] == 's' && //
|
||||
argv[i][1] == 'k' && //
|
||||
|
|
|
@ -36,7 +36,8 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
for (j = 0; i + j < argc; ++j) {
|
||||
if (j) fputc(' ', stream);
|
||||
if (j)
|
||||
fputc(' ', stream);
|
||||
fputs(argv[i + j], stream);
|
||||
}
|
||||
if (wantnewline) {
|
||||
|
|
|
@ -179,12 +179,14 @@ static wontreturn void DieOom(void) {
|
|||
|
||||
static void *Calloc(size_t n) {
|
||||
void *p;
|
||||
if (!(p = calloc(1, n))) DieOom();
|
||||
if (!(p = calloc(1, n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Realloc(void *p, size_t n) {
|
||||
if (!(p = realloc(p, n))) DieOom();
|
||||
if (!(p = realloc(p, n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -629,10 +631,12 @@ static bool ParseDllImportSymbol(const char *symbol_name,
|
|||
size_t n;
|
||||
char *dll_name;
|
||||
const char *dolla;
|
||||
if (!startswith(symbol_name, "dll$")) return false;
|
||||
if (!startswith(symbol_name, "dll$"))
|
||||
return false;
|
||||
symbol_name += 4;
|
||||
dolla = strchr(symbol_name, '$');
|
||||
if (!dolla) return false;
|
||||
if (!dolla)
|
||||
return false;
|
||||
n = dolla - symbol_name;
|
||||
dll_name = memcpy(Calloc(n + 1), symbol_name, n);
|
||||
*out_dll_name = dll_name;
|
||||
|
@ -682,19 +686,26 @@ static struct Elf *OpenElf(const char *path) {
|
|||
struct Elf *elf;
|
||||
elf = Calloc(sizeof(*elf));
|
||||
elf->path = path;
|
||||
if ((fd = open(path, O_RDONLY)) == -1) DieSys(path);
|
||||
if ((elf->size = lseek(fd, 0, SEEK_END)) == -1) DieSys(path);
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
DieSys(path);
|
||||
if ((elf->size = lseek(fd, 0, SEEK_END)) == -1)
|
||||
DieSys(path);
|
||||
elf->map = mmap(0, elf->size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (elf->map == MAP_FAILED) DieSys(path);
|
||||
if (!IsElf64Binary(elf->ehdr, elf->size)) Die(path, "not an elf64 binary");
|
||||
if (elf->map == MAP_FAILED)
|
||||
DieSys(path);
|
||||
if (!IsElf64Binary(elf->ehdr, elf->size))
|
||||
Die(path, "not an elf64 binary");
|
||||
elf->symhdr =
|
||||
GetElfSymbolTable(elf->ehdr, elf->size, SHT_SYMTAB, &elf->symcount);
|
||||
elf->symtab = GetElfSectionAddress(elf->ehdr, elf->size, elf->symhdr);
|
||||
if (!elf->symtab) Die(path, "elf doesn't have symbol table");
|
||||
if (!elf->symtab)
|
||||
Die(path, "elf doesn't have symbol table");
|
||||
elf->strtab = GetElfStringTable(elf->ehdr, elf->size, ".strtab");
|
||||
if (!elf->strtab) Die(path, "elf doesn't have string table");
|
||||
if (!elf->strtab)
|
||||
Die(path, "elf doesn't have string table");
|
||||
elf->secstrs = GetElfSectionNameStringTable(elf->ehdr, elf->size);
|
||||
if (!elf->strtab) Die(path, "elf doesn't have section string table");
|
||||
if (!elf->strtab)
|
||||
Die(path, "elf doesn't have section string table");
|
||||
LoadDllImports(elf);
|
||||
LoadSectionsIntoSegments(elf);
|
||||
close(fd);
|
||||
|
@ -810,14 +821,18 @@ static struct ImagePointer GeneratePe(struct Elf *elf, char *fp, int64_t vp) {
|
|||
// embed the ms-dos stub and/or bios bootloader
|
||||
if (stubpath) {
|
||||
int fd = open(stubpath, O_RDONLY);
|
||||
if (fd == -1) DieSys(stubpath);
|
||||
if (fd == -1)
|
||||
DieSys(stubpath);
|
||||
for (;;) {
|
||||
ssize_t got = read(fd, fp, 512);
|
||||
if (got == -1) DieSys(stubpath);
|
||||
if (!got) break;
|
||||
if (got == -1)
|
||||
DieSys(stubpath);
|
||||
if (!got)
|
||||
break;
|
||||
fp += got;
|
||||
}
|
||||
if (close(fd)) DieSys(stubpath);
|
||||
if (close(fd))
|
||||
DieSys(stubpath);
|
||||
}
|
||||
|
||||
// output portable executable magic
|
||||
|
@ -1083,15 +1098,18 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
// get program name
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "elf2pe";
|
||||
if (!prog)
|
||||
prog = "elf2pe";
|
||||
// process flags
|
||||
GetOpts(argc, argv);
|
||||
// translate executable
|
||||
struct Elf *elf = OpenElf(argv[optind]);
|
||||
char *buf = memalign(MAX_ALIGN, 134217728);
|
||||
struct ImagePointer ip = GeneratePe(elf, buf, 0x00400000);
|
||||
if (creat(outpath, 0755) == -1) DieSys(elf->path);
|
||||
if (creat(outpath, 0755) == -1)
|
||||
DieSys(elf->path);
|
||||
Pwrite(3, buf, ip.fp - buf, 0);
|
||||
if (close(3)) DieSys(elf->path);
|
||||
if (close(3))
|
||||
DieSys(elf->path);
|
||||
// PrintElf(elf);
|
||||
}
|
||||
|
|
|
@ -53,8 +53,10 @@ int main(int argc, char *argv[]) {
|
|||
if (!l1 && !l2) {
|
||||
exit(0);
|
||||
}
|
||||
if (l1) chomp(l1);
|
||||
if (l2) chomp(l2);
|
||||
if (l1)
|
||||
chomp(l1);
|
||||
if (l2)
|
||||
chomp(l2);
|
||||
if (!l1 || !l2) {
|
||||
printf("> %s\n", l1 ? l1 : "EOF");
|
||||
printf("< %s\n", l2 ? l2 : "EOF");
|
||||
|
|
|
@ -78,18 +78,21 @@ static wontreturn void DieOom(void) {
|
|||
|
||||
static void *Malloc(size_t n) {
|
||||
void *p;
|
||||
if (!(p = malloc(n))) DieOom();
|
||||
if (!(p = malloc(n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Realloc(void *p, size_t n) {
|
||||
if (!(p = realloc(p, n))) DieOom();
|
||||
if (!(p = realloc(p, n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static wontreturn void SysExit(const char *func) {
|
||||
const char *errstr;
|
||||
if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN";
|
||||
if (!(errstr = _strerdoc(errno)))
|
||||
errstr = "EUNKNOWN";
|
||||
tinyprint(2, epath, ": ", func, " failed with ", errstr, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -201,11 +204,15 @@ static const unsigned char kNops[10][10] = {
|
|||
static unsigned char *CoalesceNops(unsigned char *p, const unsigned char *e) {
|
||||
long n;
|
||||
for (; p + 1 < e; p += n) {
|
||||
if (p[0] != 0x90) break;
|
||||
if (p[1] != 0x90) break;
|
||||
if (p[0] != 0x90)
|
||||
break;
|
||||
if (p[1] != 0x90)
|
||||
break;
|
||||
for (n = 2; p + n < e; ++n) {
|
||||
if (p[n] != 0x90) break;
|
||||
if (n == ARRAYLEN(kNops) - 1) break;
|
||||
if (p[n] != 0x90)
|
||||
break;
|
||||
if (n == ARRAYLEN(kNops) - 1)
|
||||
break;
|
||||
}
|
||||
memcpy(p, kNops[n], n);
|
||||
}
|
||||
|
@ -218,16 +225,23 @@ static void CheckPrivilegedCrossReferences(void) {
|
|||
const Elf64_Shdr *shdr;
|
||||
const Elf64_Rela *rela, *erela;
|
||||
shdr = FindElfSectionByName(elf, esize, secstrs, ".rela.privileged");
|
||||
if (!shdr || !(rela = GetElfSectionAddress(elf, esize, shdr))) return;
|
||||
if (!shdr || !(rela = GetElfSectionAddress(elf, esize, shdr)))
|
||||
return;
|
||||
erela = rela + shdr->sh_size / sizeof(*rela);
|
||||
for (; rela < erela; ++rela) {
|
||||
if (!ELF64_R_TYPE(rela->r_info)) continue;
|
||||
if (!(x = ELF64_R_SYM(rela->r_info))) continue;
|
||||
if (x >= symcount) continue;
|
||||
if (syms[x].st_shndx == SHN_ABS) continue;
|
||||
if (!syms[x].st_shndx) continue;
|
||||
if (!ELF64_R_TYPE(rela->r_info))
|
||||
continue;
|
||||
if (!(x = ELF64_R_SYM(rela->r_info)))
|
||||
continue;
|
||||
if (x >= symcount)
|
||||
continue;
|
||||
if (syms[x].st_shndx == SHN_ABS)
|
||||
continue;
|
||||
if (!syms[x].st_shndx)
|
||||
continue;
|
||||
if ((shdr = GetElfSectionHeaderAddress(elf, esize, syms[x].st_shndx))) {
|
||||
if (~shdr->sh_flags & SHF_EXECINSTR) continue; // data reference
|
||||
if (~shdr->sh_flags & SHF_EXECINSTR)
|
||||
continue; // data reference
|
||||
if ((secname = GetElfString(elf, esize, secstrs, shdr->sh_name)) &&
|
||||
strcmp(".privileged", secname)) {
|
||||
tinyprint(2, epath,
|
||||
|
@ -334,12 +348,15 @@ static void OptimizePatchableFunctionEntries(void) {
|
|||
Elf64_Addr sym_rva;
|
||||
if (elf->e_machine == EM_NEXGEN32E) {
|
||||
for (i = 0; i < symcount; ++i) {
|
||||
if (!syms[i].st_size) continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC) continue;
|
||||
if (!syms[i].st_size)
|
||||
continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC)
|
||||
continue;
|
||||
if (!(shdr = GetElfSectionHeaderAddress(elf, esize, syms[i].st_shndx))) {
|
||||
Die("elf header overflow #3");
|
||||
}
|
||||
if (shdr->sh_type != SHT_PROGBITS) continue;
|
||||
if (shdr->sh_type != SHT_PROGBITS)
|
||||
continue;
|
||||
if (!(p = GetElfSectionAddress(elf, esize, shdr))) {
|
||||
Die("elf section overflow");
|
||||
}
|
||||
|
@ -371,7 +388,8 @@ static void RelinkZipFiles(void) {
|
|||
// scan backwards for zip eocd todo record
|
||||
// that was created by libc/nexgen32e/zip.S
|
||||
for (;;) {
|
||||
if (eocd < stop) return;
|
||||
if (eocd < stop)
|
||||
return;
|
||||
if (READ32LE(eocd) == kZipCdirHdrMagicTodo && //
|
||||
ZIP_CDIR_SIZE(eocd) && //
|
||||
!ZIP_CDIR_OFFSET(eocd) && //
|
||||
|
@ -446,13 +464,17 @@ static void GenerateIfuncInit(void) {
|
|||
static char code[16384];
|
||||
static Elf64_Rela relas[1024];
|
||||
Elf64_Shdr *symtab_shdr = GetElfSymbolTable(elf, esize, SHT_SYMTAB, 0);
|
||||
if (!symtab_shdr) Die("symbol table section header not found");
|
||||
if (!symtab_shdr)
|
||||
Die("symbol table section header not found");
|
||||
Elf64_Word symtab_shdr_index =
|
||||
((char *)symtab_shdr - ((char *)elf + elf->e_shoff)) / elf->e_shentsize;
|
||||
for (Elf64_Xword i = 0; i < symcount; ++i) {
|
||||
if (syms[i].st_shndx == SHN_UNDEF) continue;
|
||||
if (syms[i].st_shndx >= SHN_LORESERVE) continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_GNU_IFUNC) continue;
|
||||
if (syms[i].st_shndx == SHN_UNDEF)
|
||||
continue;
|
||||
if (syms[i].st_shndx >= SHN_LORESERVE)
|
||||
continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_GNU_IFUNC)
|
||||
continue;
|
||||
if (!(name = GetElfString(elf, esize, symstrs, syms[i].st_name)))
|
||||
Die("could not get symbol name of ifunc");
|
||||
static char resolver_name[65536];
|
||||
|
@ -463,11 +485,16 @@ static void GenerateIfuncInit(void) {
|
|||
Elf64_Xword function_sym_index = i;
|
||||
Elf64_Xword resolver_sym_index = -1;
|
||||
for (Elf64_Xword i = 0; i < symcount; ++i) {
|
||||
if (syms[i].st_shndx == SHN_UNDEF) continue;
|
||||
if (syms[i].st_shndx >= SHN_LORESERVE) continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC) continue;
|
||||
if (!(s = GetElfString(elf, esize, symstrs, syms[i].st_name))) continue;
|
||||
if (strcmp(s, resolver_name)) continue;
|
||||
if (syms[i].st_shndx == SHN_UNDEF)
|
||||
continue;
|
||||
if (syms[i].st_shndx >= SHN_LORESERVE)
|
||||
continue;
|
||||
if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC)
|
||||
continue;
|
||||
if (!(s = GetElfString(elf, esize, symstrs, syms[i].st_name)))
|
||||
continue;
|
||||
if (strcmp(s, resolver_name))
|
||||
continue;
|
||||
resolver_sym_index = i;
|
||||
break;
|
||||
}
|
||||
|
@ -521,15 +548,18 @@ static void GenerateIfuncInit(void) {
|
|||
0x5e, // pop %rsi
|
||||
0x5f, // pop %rdi
|
||||
};
|
||||
if (code_i + sizeof(chunk3) > sizeof(code)) Die("too many ifuncs");
|
||||
if (code_i + sizeof(chunk3) > sizeof(code))
|
||||
Die("too many ifuncs");
|
||||
memcpy(code + code_i, chunk3, sizeof(chunk3));
|
||||
code_i += sizeof(chunk3);
|
||||
}
|
||||
if (!code_i) return;
|
||||
if (!code_i)
|
||||
return;
|
||||
|
||||
// prepare to mutate elf
|
||||
// remap file so it has more space
|
||||
if (elf->e_shnum + 2 > 65535) Die("too many sections");
|
||||
if (elf->e_shnum + 2 > 65535)
|
||||
Die("too many sections");
|
||||
size_t reserve_size = esize + 32 * 1024 * 1024;
|
||||
elf = Realloc(elf, reserve_size);
|
||||
|
||||
|
|
|
@ -157,15 +157,19 @@ void Compress(const char *inpath) {
|
|||
p = openflags;
|
||||
*p++ = opt_append ? 'a' : 'w';
|
||||
*p++ = 'b';
|
||||
if (opt_exclusive) *p++ = 'x';
|
||||
if (opt_level) *p++ = opt_level;
|
||||
if (opt_strategy) *p++ = opt_strategy;
|
||||
if (opt_exclusive)
|
||||
*p++ = 'x';
|
||||
if (opt_level)
|
||||
*p++ = opt_level;
|
||||
if (opt_strategy)
|
||||
*p++ = opt_strategy;
|
||||
*p = 0;
|
||||
if (opt_usestdout) {
|
||||
outpath = "/dev/stdout";
|
||||
output = gzdopen(1, openflags);
|
||||
} else {
|
||||
if (strlen(inpath) + 3 + 1 > PATH_MAX) _Exit(2);
|
||||
if (strlen(inpath) + 3 + 1 > PATH_MAX)
|
||||
_Exit(2);
|
||||
stpcpy(stpcpy(pathbuf, inpath), ".gz");
|
||||
outpath = pathbuf;
|
||||
output = gzopen(outpath, openflags);
|
||||
|
@ -237,7 +241,8 @@ void Decompress(const char *inpath) {
|
|||
outpath = "/dev/stdout";
|
||||
} else if (endswith(inpath, ".gz")) {
|
||||
n = strlen(inpath);
|
||||
if (n - 3 + 1 > PATH_MAX) _Exit(2);
|
||||
if (n - 3 + 1 > PATH_MAX)
|
||||
_Exit(2);
|
||||
memcpy(pathbuf, inpath, n - 3);
|
||||
pathbuf[n - 3] = 0;
|
||||
outpath = pathbuf;
|
||||
|
@ -291,7 +296,8 @@ void Decompress(const char *inpath) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "gzip";
|
||||
if (!prog)
|
||||
prog = "gzip";
|
||||
GetOpts(argc, argv);
|
||||
if (opt_decompress) {
|
||||
if (optind == argc) {
|
||||
|
|
|
@ -69,7 +69,8 @@ static wontreturn void OutOfMemory(void) {
|
|||
|
||||
static void *Calloc(size_t n, size_t z) {
|
||||
void *p;
|
||||
if (!(p = calloc(n, z))) OutOfMemory();
|
||||
if (!(p = calloc(n, z)))
|
||||
OutOfMemory();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -186,7 +187,8 @@ int main(int argc, char *argv[]) {
|
|||
int64_t hProcess;
|
||||
char16_t name[PATH_MAX];
|
||||
for (subcount = i = 0; i < n; i++) {
|
||||
if (!pids[i]) continue;
|
||||
if (!pids[i])
|
||||
continue;
|
||||
if ((hProcess = MyOpenProcess(pids[i]))) {
|
||||
if (GetProcessName(hProcess, name)) {
|
||||
ConvertStringToLowercase16(name);
|
||||
|
|
|
@ -33,9 +33,11 @@ static bool IsSymbolChar2(char c) {
|
|||
}
|
||||
|
||||
static bool IsSymbolString(const char *s) {
|
||||
if (!IsSymbolChar1(*s++)) return false;
|
||||
if (!IsSymbolChar1(*s++))
|
||||
return false;
|
||||
while (*s) {
|
||||
if (!IsSymbolChar2(*s++)) return false;
|
||||
if (!IsSymbolChar2(*s++))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ void AppendData(struct Buffer *b, const char *data, size_t len) {
|
|||
unsigned n;
|
||||
if (b->i + len + 1 > b->n) {
|
||||
n = MAX(b->i + len + 1, MAX(16, b->n + (b->n >> 1)));
|
||||
if (!(p = realloc(b->p, n))) return;
|
||||
if (!(p = realloc(b->p, n)))
|
||||
return;
|
||||
b->p = p;
|
||||
b->n = n;
|
||||
}
|
||||
|
|
|
@ -65,17 +65,21 @@ char *CopySymbol(char *p, size_t pn, const char *s, size_t sn) {
|
|||
assert(pn >= 1 + 3 + 1 + 1);
|
||||
iscomplicated = memchr(s, ' ', sn) || memchr(s, '(', sn);
|
||||
extra = 1;
|
||||
if (iscomplicated) extra += 2;
|
||||
if (iscomplicated)
|
||||
extra += 2;
|
||||
if (sn + extra > pn) {
|
||||
sn = pn - extra - 3;
|
||||
showdots = true;
|
||||
} else {
|
||||
showdots = false;
|
||||
}
|
||||
if (iscomplicated) *p++ = '"';
|
||||
if (iscomplicated)
|
||||
*p++ = '"';
|
||||
p = mempcpy(p, s, sn);
|
||||
if (showdots) p = stpcpy(p, "...");
|
||||
if (iscomplicated) *p++ = '"';
|
||||
if (showdots)
|
||||
p = stpcpy(p, "...");
|
||||
if (iscomplicated)
|
||||
*p++ = '"';
|
||||
*p = '\0';
|
||||
return p;
|
||||
}
|
||||
|
@ -85,8 +89,10 @@ char *DemangleCxxFilt(char *p, size_t pn, const char *s, size_t sn) {
|
|||
size_t got;
|
||||
struct iovec iov[2];
|
||||
static char buf[4096];
|
||||
if (!g_cxxfilt.pid) SpawnCxxFilt();
|
||||
if (g_cxxfilt.pid == -1) return NULL;
|
||||
if (!g_cxxfilt.pid)
|
||||
SpawnCxxFilt();
|
||||
if (g_cxxfilt.pid == -1)
|
||||
return NULL;
|
||||
buf[0] = '\n';
|
||||
iov[0].iov_base = (void *)s;
|
||||
iov[0].iov_len = sn;
|
||||
|
@ -96,7 +102,8 @@ char *DemangleCxxFilt(char *p, size_t pn, const char *s, size_t sn) {
|
|||
if ((rc = read(g_cxxfilt.reader, buf, sizeof(buf))) != -1) {
|
||||
got = rc;
|
||||
if (got >= 2 && buf[got - 1] == '\n') {
|
||||
if (buf[got - 2] == '\r') --got;
|
||||
if (buf[got - 2] == '\r')
|
||||
--got;
|
||||
--got;
|
||||
return CopySymbol(p, pn, buf, got);
|
||||
}
|
||||
|
@ -117,7 +124,8 @@ char *Demangle(char *p, const char *symbol, size_t n) {
|
|||
size_t sn;
|
||||
sn = strlen(symbol);
|
||||
if (startswith(symbol, "_Z")) {
|
||||
if ((r = DemangleCxxFilt(p, n, symbol, sn))) return r;
|
||||
if ((r = DemangleCxxFilt(p, n, symbol, sn)))
|
||||
return r;
|
||||
}
|
||||
return CopySymbol(p, n, symbol, sn);
|
||||
}
|
||||
|
|
|
@ -249,7 +249,8 @@ void elfwriter_commit(struct ElfWriter *elf, size_t size) {
|
|||
|
||||
void elfwriter_finishsection(struct ElfWriter *elf) {
|
||||
size_t section = FinishSection(elf);
|
||||
if (elf->relas->j < elf->relas->i) MakeRelaSection(elf, section);
|
||||
if (elf->relas->j < elf->relas->i)
|
||||
MakeRelaSection(elf, section);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -164,7 +164,8 @@ void elfwriter_zip(struct ElfWriter *elf, const char *symbol, const char *cname,
|
|||
lfilehdrsize = kZipLfileHdrMinSize + namesize;
|
||||
crc = crc32_z(0, data, uncompsize);
|
||||
GetDosLocalTime(mtim.tv_sec, &mtime, &mdate);
|
||||
if (isutf8(name, namesize)) gflags |= kZipGflagUtf8;
|
||||
if (isutf8(name, namesize))
|
||||
gflags |= kZipGflagUtf8;
|
||||
if (S_ISREG(mode) && istext(data, size)) {
|
||||
iattrs |= kZipIattrText;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,10 @@ static ssize_t EzWritevAll(int fd, struct iovec *iov, int iovlen) {
|
|||
total = 0;
|
||||
do {
|
||||
if (i) {
|
||||
while (i < iovlen && !iov[i].iov_len) ++i;
|
||||
if (i == iovlen) break;
|
||||
while (i < iovlen && !iov[i].iov_len)
|
||||
++i;
|
||||
if (i == iovlen)
|
||||
break;
|
||||
}
|
||||
if ((rc = writev(fd, iov + i, iovlen - i)) != -1) {
|
||||
wrote = rc;
|
||||
|
@ -99,7 +101,8 @@ int EzTlsFlush(struct EzTlsBio *bio, const unsigned char *buf, size_t len) {
|
|||
v[1].iov_base = (void *)buf;
|
||||
v[1].iov_len = len;
|
||||
if (EzWritevAll(bio->fd, v, 2) != -1) {
|
||||
if (bio->c > 0) bio->c = 0;
|
||||
if (bio->c > 0)
|
||||
bio->c = 0;
|
||||
} else if (errno == EAGAIN) {
|
||||
return MBEDTLS_ERR_SSL_TIMEOUT;
|
||||
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
||||
|
@ -121,7 +124,8 @@ static int EzTlsSend(void *ctx, const unsigned char *buf, size_t len) {
|
|||
bio->c += len;
|
||||
return len;
|
||||
}
|
||||
if ((rc = EzTlsFlush(bio, buf, len)) < 0) return rc;
|
||||
if ((rc = EzTlsFlush(bio, buf, len)) < 0)
|
||||
return rc;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -130,11 +134,13 @@ static int EzTlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
int r;
|
||||
struct iovec v[2];
|
||||
struct EzTlsBio *bio = ctx;
|
||||
if ((r = EzTlsFlush(bio, 0, 0)) < 0) return r;
|
||||
if ((r = EzTlsFlush(bio, 0, 0)) < 0)
|
||||
return r;
|
||||
if (bio->a < bio->b) {
|
||||
r = MIN(n, bio->b - bio->a);
|
||||
memcpy(p, bio->t + bio->a, r);
|
||||
if ((bio->a += r) == bio->b) bio->a = bio->b = 0;
|
||||
if ((bio->a += r) == bio->b)
|
||||
bio->a = bio->b = 0;
|
||||
return r;
|
||||
}
|
||||
v[0].iov_base = p;
|
||||
|
@ -153,7 +159,8 @@ static int EzTlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
}
|
||||
if (r > n) bio->b = r - n;
|
||||
if (r > n)
|
||||
bio->b = r - n;
|
||||
return MIN(n, r);
|
||||
}
|
||||
|
||||
|
@ -237,7 +244,8 @@ void EzSetup(char psk[32]) {
|
|||
}
|
||||
|
||||
void EzDestroy(void) {
|
||||
if (!mytid) return;
|
||||
if (!mytid)
|
||||
return;
|
||||
EzSanity();
|
||||
mbedtls_ssl_free(&ezssl);
|
||||
mbedtls_ctr_drbg_free(&ezrng);
|
||||
|
|
|
@ -77,7 +77,8 @@
|
|||
|
||||
static wontreturn void getargs_fail(const char *path, const char *reason) {
|
||||
const char *errstr;
|
||||
if (!(errstr = _strerdoc(errno))) errstr = "Unknown error";
|
||||
if (!(errstr = _strerdoc(errno)))
|
||||
errstr = "Unknown error";
|
||||
tinyprint(2, path, ": ", reason, ": ", errstr, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -97,7 +98,8 @@ void getargs_init(struct GetArgs *ga, char **args) {
|
|||
*/
|
||||
void getargs_destroy(struct GetArgs *ga) {
|
||||
if (ga->map) {
|
||||
if (munmap(ga->map, ga->mapsize)) notpossible;
|
||||
if (munmap(ga->map, ga->mapsize))
|
||||
notpossible;
|
||||
}
|
||||
bzero(ga, sizeof(*ga));
|
||||
}
|
||||
|
@ -152,7 +154,8 @@ const char *getargs_next(struct GetArgs *ga) {
|
|||
ga->j += ++k;
|
||||
return p;
|
||||
}
|
||||
if (munmap(ga->map, ga->mapsize)) notpossible;
|
||||
if (munmap(ga->map, ga->mapsize))
|
||||
notpossible;
|
||||
ga->map = 0;
|
||||
ga->mapsize = 0;
|
||||
ga->j = 0;
|
||||
|
|
|
@ -43,7 +43,8 @@ static void rehash(struct InternerObject *it) {
|
|||
p = it->p;
|
||||
it->p = xcalloc((it->n <<= 1), sizeof(struct InternerHash));
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!p[i].hash) continue;
|
||||
if (!p[i].hash)
|
||||
continue;
|
||||
step = 0;
|
||||
do {
|
||||
j = (p[i].hash + step * ((step + 1) >> 1)) & (it->n - 1);
|
||||
|
@ -120,15 +121,21 @@ size_t internobj(struct Interner *t, const void *data, size_t size) {
|
|||
} while (it->p[i].hash);
|
||||
}
|
||||
off = it->pool.i;
|
||||
if (ckd_add(&need, off, size)) abort();
|
||||
if (ckd_add(&need, need, 1)) abort();
|
||||
if (ckd_add(&need, off, size))
|
||||
abort();
|
||||
if (ckd_add(&need, need, 1))
|
||||
abort();
|
||||
if (need > it->pool.n) {
|
||||
if (ckd_add(&n2, it->pool.n, 1)) abort();
|
||||
if (ckd_add(&n2, it->pool.n, 1))
|
||||
abort();
|
||||
do {
|
||||
if (ckd_add(&n2, n2, n2 >> 1)) abort();
|
||||
if (ckd_add(&n2, n2, n2 >> 1))
|
||||
abort();
|
||||
} while (need > n2);
|
||||
if (ckd_mul(&bytes, n2, sizeof(*it->pool.p))) abort();
|
||||
if (!(p2 = realloc(it->pool.p, bytes))) abort();
|
||||
if (ckd_mul(&bytes, n2, sizeof(*it->pool.p)))
|
||||
abort();
|
||||
if (!(p2 = realloc(it->pool.p, bytes)))
|
||||
abort();
|
||||
it->pool.p = p2;
|
||||
it->pool.n = n2;
|
||||
}
|
||||
|
|
|
@ -32,13 +32,16 @@ struct Lines {
|
|||
|
||||
static char *SkipEmptyFirstLine(char *p) {
|
||||
int i = 0;
|
||||
while (p[i] == ' ' || p[i] == '\t') ++i;
|
||||
while (p[i] == ' ' || p[i] == '\t')
|
||||
++i;
|
||||
return p[i] == '\n' ? p + i + 1 : p;
|
||||
}
|
||||
|
||||
static void DeleteLastEmptyLine(char *p, size_t n) {
|
||||
while (n && (p[n - 1] == ' ' || p[n - 1] == '\t')) --n;
|
||||
if (n && p[n - 1] == '\n') p[n - 1] = '\0';
|
||||
while (n && (p[n - 1] == ' ' || p[n - 1] == '\t'))
|
||||
--n;
|
||||
if (n && p[n - 1] == '\n')
|
||||
p[n - 1] = '\0';
|
||||
}
|
||||
|
||||
static void AppendLine(struct Lines *lines) {
|
||||
|
@ -88,7 +91,8 @@ static unsigned GetMinPrefixLen(struct Lines *lines,
|
|||
for (m = -1, i = 0; i < lines->n; ++i) {
|
||||
if (lines->p[i].n) {
|
||||
n = GetPrefixLen(lines->p[i].p, lines->p[i].n);
|
||||
if (n < m) m = n;
|
||||
if (n < m)
|
||||
m = n;
|
||||
}
|
||||
}
|
||||
return m == -1 ? 0 : m;
|
||||
|
@ -112,7 +116,8 @@ static void SplitLines(struct Lines *lines, char *p) {
|
|||
AppendLine(lines);
|
||||
lines->p[lines->n - 1].p = p;
|
||||
lines->p[lines->n - 1].n = (q = strchr(p, '\n')) ? q - p : strlen(p);
|
||||
if (!q) break;
|
||||
if (!q)
|
||||
break;
|
||||
p = q + 1;
|
||||
}
|
||||
RemovePrefixes(lines, GetMinPrefixLen(lines, GetSpaceStarPrefixLen));
|
||||
|
@ -175,7 +180,8 @@ static int ExtractText(struct Javadown *jd, struct Lines *lines, int i) {
|
|||
char *p;
|
||||
size_t n;
|
||||
for (p = NULL, n = j = 0; i + j < lines->n; ++j) {
|
||||
if (lines->p[i + j].n && lines->p[i + j].p[0] == '@') break;
|
||||
if (lines->p[i + j].n && lines->p[i + j].p[0] == '@')
|
||||
break;
|
||||
if (j) {
|
||||
p = realloc(p, ++n);
|
||||
p[n - 1] = '\n';
|
||||
|
@ -194,11 +200,14 @@ static void ExtractTags(struct Javadown *jd, struct Lines *lines, int i) {
|
|||
char *tag, *text, *p2;
|
||||
unsigned taglen, textlen, n2;
|
||||
for (; i < lines->n; ++i) {
|
||||
if (!lines->p[i].n) continue;
|
||||
if (lines->p[i].p[0] != '@') continue;
|
||||
if (!lines->p[i].n)
|
||||
continue;
|
||||
if (lines->p[i].p[0] != '@')
|
||||
continue;
|
||||
tag = lines->p[i].p + 1;
|
||||
taglen = GetTagLen(tag, lines->p[i].n - 1);
|
||||
if (!taglen) continue;
|
||||
if (!taglen)
|
||||
continue;
|
||||
text = tag + taglen;
|
||||
tag = strndup(tag, taglen);
|
||||
textlen = lines->p[i].n - 1 - taglen;
|
||||
|
|
|
@ -27,25 +27,30 @@
|
|||
|
||||
static int tpdecode(const char *s, wint_t *out) {
|
||||
uint32_t wc, cb, need, msb, j, i = 0;
|
||||
if ((wc = s[i++] & 255) == -1) return -1;
|
||||
if ((wc = s[i++] & 255) == -1)
|
||||
return -1;
|
||||
while ((wc & 0300) == 0200) {
|
||||
if ((wc = s[i++] & 255) == -1) return -1;
|
||||
if ((wc = s[i++] & 255) == -1)
|
||||
return -1;
|
||||
}
|
||||
if (!(0 <= wc && wc <= 0x7F)) {
|
||||
msb = wc < 252 ? bsr(~wc & 0xff) : 1;
|
||||
need = 7 - msb;
|
||||
wc &= ((1u << msb) - 1) | 0003;
|
||||
for (j = 1; j < need; ++j) {
|
||||
if ((cb = s[i++] & 255) == -1) return -1;
|
||||
if ((cb = s[i++] & 255) == -1)
|
||||
return -1;
|
||||
if ((cb & 0300) == 0200) {
|
||||
wc = wc << 6 | (cb & 077);
|
||||
} else {
|
||||
if (out) *out = 0xFFFD;
|
||||
if (out)
|
||||
*out = 0xFFFD;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (out) *out = wc;
|
||||
if (out)
|
||||
*out = wc;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -71,7 +76,8 @@ ssize_t PrintPanels(int fd, long pn, struct Panel *p, long tyn, long txn) {
|
|||
bzero(&b, sizeof(b));
|
||||
AppendStr(&b, "\e[H");
|
||||
for (y = 0; y < tyn; ++y) {
|
||||
if (y) AppendFmt(&b, "\e[%dH", y + 1);
|
||||
if (y)
|
||||
AppendFmt(&b, "\e[%dH", y + 1);
|
||||
for (x = i = 0; i < pn; ++i) {
|
||||
if (p[i].top <= y && y < p[i].bottom) {
|
||||
j = state = 0;
|
||||
|
|
|
@ -164,7 +164,8 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
/* TODO(jart): Fix Emacs */
|
||||
glyphs[col] = kCp437[ch == '"' || ch == '#' ? '.' : ch];
|
||||
if (col) fputc(',', fout);
|
||||
if (col)
|
||||
fputc(',', fout);
|
||||
fprintf(fout, "0x%02x", ch);
|
||||
if (++col == COLS) {
|
||||
col = 0;
|
||||
|
|
|
@ -76,13 +76,20 @@ int main(int argc, char *argv[]) {
|
|||
GetOpts(argc, argv);
|
||||
#ifdef __x86_64__
|
||||
struct X86ProcessorModel *model;
|
||||
if (X86_HAVE(XOP)) Puts("-mxop");
|
||||
if (X86_HAVE(SSE4A)) Puts("-msse4a");
|
||||
if (X86_HAVE(SSE3)) Puts("-msse3");
|
||||
if (X86_HAVE(SSSE3)) Puts("-mssse3");
|
||||
if (X86_HAVE(SSE4_1)) Puts("-msse4.1");
|
||||
if (X86_HAVE(SSE4_2)) Puts("-msse4.2");
|
||||
if (X86_HAVE(AVX)) Puts("-mavx");
|
||||
if (X86_HAVE(XOP))
|
||||
Puts("-mxop");
|
||||
if (X86_HAVE(SSE4A))
|
||||
Puts("-msse4a");
|
||||
if (X86_HAVE(SSE3))
|
||||
Puts("-msse3");
|
||||
if (X86_HAVE(SSSE3))
|
||||
Puts("-mssse3");
|
||||
if (X86_HAVE(SSE4_1))
|
||||
Puts("-msse4.1");
|
||||
if (X86_HAVE(SSE4_2))
|
||||
Puts("-msse4.2");
|
||||
if (X86_HAVE(AVX))
|
||||
Puts("-mavx");
|
||||
if (X86_HAVE(AVX2)) {
|
||||
Puts("-mavx2");
|
||||
if (!isclang) {
|
||||
|
@ -90,27 +97,48 @@ int main(int argc, char *argv[]) {
|
|||
Puts("-Wa,-msse2avx");
|
||||
}
|
||||
}
|
||||
if (X86_HAVE(AVX512F)) Puts("-mavx512f");
|
||||
if (X86_HAVE(AVX512PF)) Puts("-mavx512pf");
|
||||
if (X86_HAVE(AVX512ER)) Puts("-mavx512er");
|
||||
if (X86_HAVE(AVX512CD)) Puts("-mavx512cd");
|
||||
if (X86_HAVE(AVX512VL)) Puts("-mavx512vl");
|
||||
if (X86_HAVE(AVX512BW)) Puts("-mavx512bw");
|
||||
if (X86_HAVE(AVX512DQ)) Puts("-mavx512dq");
|
||||
if (X86_HAVE(AVX512IFMA)) Puts("-mavx512ifma");
|
||||
if (X86_HAVE(AVX512VBMI)) Puts("-mavx512vbmi");
|
||||
if (X86_HAVE(SHA)) Puts("-msha");
|
||||
if (X86_HAVE(AES)) Puts("-maes");
|
||||
if (X86_HAVE(VAES)) Puts("-mvaes");
|
||||
if (X86_HAVE(PCLMUL)) Puts("-mpclmul");
|
||||
if (X86_HAVE(FSGSBASE)) Puts("-mfsgsbase");
|
||||
if (X86_HAVE(F16C)) Puts("-mf16c");
|
||||
if (X86_HAVE(FMA)) Puts("-mfma");
|
||||
if (X86_HAVE(POPCNT)) Puts("-mpopcnt");
|
||||
if (X86_HAVE(BMI)) Puts("-mbmi");
|
||||
if (X86_HAVE(BMI2)) Puts("-mbmi2");
|
||||
if (X86_HAVE(ADX)) Puts("-madx");
|
||||
if (X86_HAVE(FXSR)) Puts("-mfxsr");
|
||||
if (X86_HAVE(AVX512F))
|
||||
Puts("-mavx512f");
|
||||
if (X86_HAVE(AVX512PF))
|
||||
Puts("-mavx512pf");
|
||||
if (X86_HAVE(AVX512ER))
|
||||
Puts("-mavx512er");
|
||||
if (X86_HAVE(AVX512CD))
|
||||
Puts("-mavx512cd");
|
||||
if (X86_HAVE(AVX512VL))
|
||||
Puts("-mavx512vl");
|
||||
if (X86_HAVE(AVX512BW))
|
||||
Puts("-mavx512bw");
|
||||
if (X86_HAVE(AVX512DQ))
|
||||
Puts("-mavx512dq");
|
||||
if (X86_HAVE(AVX512IFMA))
|
||||
Puts("-mavx512ifma");
|
||||
if (X86_HAVE(AVX512VBMI))
|
||||
Puts("-mavx512vbmi");
|
||||
if (X86_HAVE(SHA))
|
||||
Puts("-msha");
|
||||
if (X86_HAVE(AES))
|
||||
Puts("-maes");
|
||||
if (X86_HAVE(VAES))
|
||||
Puts("-mvaes");
|
||||
if (X86_HAVE(PCLMUL))
|
||||
Puts("-mpclmul");
|
||||
if (X86_HAVE(FSGSBASE))
|
||||
Puts("-mfsgsbase");
|
||||
if (X86_HAVE(F16C))
|
||||
Puts("-mf16c");
|
||||
if (X86_HAVE(FMA))
|
||||
Puts("-mfma");
|
||||
if (X86_HAVE(POPCNT))
|
||||
Puts("-mpopcnt");
|
||||
if (X86_HAVE(BMI))
|
||||
Puts("-mbmi");
|
||||
if (X86_HAVE(BMI2))
|
||||
Puts("-mbmi2");
|
||||
if (X86_HAVE(ADX))
|
||||
Puts("-madx");
|
||||
if (X86_HAVE(FXSR))
|
||||
Puts("-mfxsr");
|
||||
if ((model = (void *)getx86processormodel(kX86ProcessorModelKey))) {
|
||||
switch (model->march) {
|
||||
case X86_MARCH_CORE2:
|
||||
|
|
|
@ -176,37 +176,44 @@ static wontreturn void DieOom(void) {
|
|||
static unsigned Hash(const void *s, size_t l) {
|
||||
unsigned h;
|
||||
h = crc32c(0, s, l);
|
||||
if (!h) h = 1;
|
||||
if (!h)
|
||||
h = 1;
|
||||
return h;
|
||||
}
|
||||
|
||||
static void *Malloc(size_t n) {
|
||||
void *p;
|
||||
if (!(p = malloc(n))) DieOom();
|
||||
if (!(p = malloc(n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Calloc(size_t n, size_t z) {
|
||||
void *p;
|
||||
if (!(p = calloc(n, z))) DieOom();
|
||||
if (!(p = calloc(n, z)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Realloc(void *p, size_t n) {
|
||||
if (!(p = realloc(p, n))) DieOom();
|
||||
if (!(p = realloc(p, n)))
|
||||
DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void Appendw(char **b, uint64_t w) {
|
||||
if (appendw(b, w) == -1) DieOom();
|
||||
if (appendw(b, w) == -1)
|
||||
DieOom();
|
||||
}
|
||||
|
||||
static void Appends(char **b, const char *s) {
|
||||
if (appends(b, s) == -1) DieOom();
|
||||
if (appends(b, s) == -1)
|
||||
DieOom();
|
||||
}
|
||||
|
||||
static void Appendd(char **b, const void *p, size_t n) {
|
||||
if (appendd(b, p, n) == -1) DieOom();
|
||||
if (appendd(b, p, n) == -1)
|
||||
DieOom();
|
||||
}
|
||||
|
||||
static unsigned FindFirstFromEdge(unsigned id) {
|
||||
|
@ -259,7 +266,8 @@ static void Rehash(void) {
|
|||
sources.n = sources.n ? sources.n << 1 : 16;
|
||||
sources.p = Calloc(sources.n, sizeof(struct Source));
|
||||
for (i = 0; i < old.n; ++i) {
|
||||
if (!old.p[i].hash) continue;
|
||||
if (!old.p[i].hash)
|
||||
continue;
|
||||
step = 0;
|
||||
do {
|
||||
j = (old.p[i].hash + step * (step + 1) / 2) & (sources.n - 1);
|
||||
|
@ -286,7 +294,8 @@ static int HashSource(const char *name, size_t len, bool create) {
|
|||
step++;
|
||||
} while (sources.p[i].hash);
|
||||
}
|
||||
if (!create) return -1;
|
||||
if (!create)
|
||||
return -1;
|
||||
if (++sources.i >= (sources.n >> 1)) {
|
||||
Rehash();
|
||||
step = 0;
|
||||
|
@ -439,17 +448,21 @@ static void LoadRelationships(int argc, char *argv[]) {
|
|||
DieSys(src);
|
||||
}
|
||||
for (p = map, pe = map + size; p < pe; ++p) {
|
||||
if (!(p = memmem(p, pe - p, "include ", 8))) break;
|
||||
if (!(path = FindIncludePath(map, size, p, is_assembly))) continue;
|
||||
if (!(p = memmem(p, pe - p, "include ", 8)))
|
||||
break;
|
||||
if (!(path = FindIncludePath(map, size, p, is_assembly)))
|
||||
continue;
|
||||
// copy the specified include path
|
||||
char right;
|
||||
if (path[-1] == '<') {
|
||||
if (!systempaths.n) continue;
|
||||
if (!systempaths.n)
|
||||
continue;
|
||||
right = '>';
|
||||
} else {
|
||||
right = '"';
|
||||
}
|
||||
if (!(pathend = memchr(path, right, pe - path))) continue;
|
||||
if (!(pathend = memchr(path, right, pe - path)))
|
||||
continue;
|
||||
if (pathend - path >= PATH_MAX) {
|
||||
tinyprint(2, src, ": uses really long include path\n", NULL);
|
||||
exit(1);
|
||||
|
@ -620,7 +633,8 @@ static const char *StripExt(char pathbuf[hasatleast PATH_MAX], const char *s) {
|
|||
DiePathTooLong(s);
|
||||
}
|
||||
dot = strrchr(pathbuf, '.');
|
||||
if (dot) *dot = '\0';
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
return pathbuf;
|
||||
}
|
||||
|
||||
|
@ -630,9 +644,12 @@ static uint32_t GetFileExtension(const char *s) {
|
|||
n = s ? strlen(s) : 0;
|
||||
for (i = w = 0; n--;) {
|
||||
wint_t c = s[n];
|
||||
if (!IsGraph(c)) return 0;
|
||||
if (c == '.') break;
|
||||
if (++i > 4) return 0;
|
||||
if (!IsGraph(c))
|
||||
return 0;
|
||||
if (c == '.')
|
||||
break;
|
||||
if (++i > 4)
|
||||
return 0;
|
||||
w <<= 8;
|
||||
w |= kToLower[c];
|
||||
}
|
||||
|
@ -655,7 +672,8 @@ static bool IsObjectSource(const char *name) {
|
|||
__funline bool Bts(uint32_t *p, size_t i) {
|
||||
uint32_t k;
|
||||
k = 1u << (i & 31);
|
||||
if (p[i >> 5] & k) return true;
|
||||
if (p[i >> 5] & k)
|
||||
return true;
|
||||
p[i >> 5] |= k;
|
||||
return false;
|
||||
}
|
||||
|
@ -663,7 +681,8 @@ __funline bool Bts(uint32_t *p, size_t i) {
|
|||
static void Dive(char **makefile, uint32_t *visited, unsigned id) {
|
||||
int i;
|
||||
for (i = FindFirstFromEdge(id); i < edges.i && edges.p[i].from == id; ++i) {
|
||||
if (Bts(visited, edges.p[i].to)) continue;
|
||||
if (Bts(visited, edges.p[i].to))
|
||||
continue;
|
||||
Appendw(makefile, READ32LE(" \\\n\t"));
|
||||
Appends(makefile, names + sauces[edges.p[i].to].name);
|
||||
Dive(makefile, visited, edges.p[i].to);
|
||||
|
@ -681,8 +700,10 @@ static char *Explore(void) {
|
|||
visited = Malloc(visilen * sizeof(*visited));
|
||||
for (i = 0; i < sources.i; ++i) {
|
||||
path = names + sauces[i].name;
|
||||
if (!IsObjectSource(path)) continue;
|
||||
if (startswith(path, genroot)) continue;
|
||||
if (!IsObjectSource(path))
|
||||
continue;
|
||||
if (startswith(path, genroot))
|
||||
continue;
|
||||
Appendw(&makefile, '\n');
|
||||
Appends(&makefile, buildroot);
|
||||
Appends(&makefile, StripExt(buf, path));
|
||||
|
@ -707,7 +728,8 @@ int main(int argc, char *argv[]) {
|
|||
ShowCrashReports();
|
||||
#endif
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "mkdeps";
|
||||
if (!prog)
|
||||
prog = "mkdeps";
|
||||
GetOpts(argc, argv);
|
||||
LoadRelationships(argc, argv);
|
||||
Crunch();
|
||||
|
|
|
@ -35,7 +35,8 @@ int main(int argc, char *argv[]) {
|
|||
int (*mkdirp)(const char *, unsigned) = mkdir;
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "mkdir";
|
||||
if (!prog)
|
||||
prog = "mkdir";
|
||||
|
||||
while ((i = getopt(argc, argv, "hpm:")) != -1) {
|
||||
switch (i) {
|
||||
|
|
|
@ -45,13 +45,17 @@ static wontreturn void DieSys(const char *thing) {
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *prog = program_invocation_short_name;
|
||||
if (argc == 1) Die(prog, "missing argument");
|
||||
if (argc != 2) Die(prog, "too many arguments");
|
||||
if (argc == 1)
|
||||
Die(prog, "missing argument");
|
||||
if (argc != 2)
|
||||
Die(prog, "too many arguments");
|
||||
char *template = argv[1];
|
||||
char *substring = strstr(template, "XXXXXXXXXXXXX");
|
||||
if (!substring) Die(prog, "template missing XXXXXXXXXXXXX substring");
|
||||
if (!substring)
|
||||
Die(prog, "template missing XXXXXXXXXXXXX substring");
|
||||
uint64_t w;
|
||||
if (getrandom(&w, 8, 0) != 8) DieSys("getrandom");
|
||||
if (getrandom(&w, 8, 0) != 8)
|
||||
DieSys("getrandom");
|
||||
for (int i = 0; i < 13; ++i) {
|
||||
substring[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[w % 36];
|
||||
w /= 36;
|
||||
|
|
|
@ -69,7 +69,8 @@ wontreturn void Die(const char *path, const char *reason) {
|
|||
|
||||
wontreturn void SysDie(const char *path, const char *func) {
|
||||
const char *errstr;
|
||||
if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN";
|
||||
if (!(errstr = _strerdoc(errno)))
|
||||
errstr = "EUNKNOWN";
|
||||
tinyprint(2, path, ": ", func, ": ", errstr, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -159,8 +160,10 @@ char *Join(const char *a, const char *b) {
|
|||
void Mv(char *src, char *dst) {
|
||||
ssize_t rc;
|
||||
const char *d;
|
||||
if (strlen(src) + 1 > PATH_MAX) _Exit(2);
|
||||
if (strlen(dst) + 1 > PATH_MAX) _Exit(2);
|
||||
if (strlen(src) + 1 > PATH_MAX)
|
||||
_Exit(2);
|
||||
if (strlen(dst) + 1 > PATH_MAX)
|
||||
_Exit(2);
|
||||
basename(src);
|
||||
basename(dst);
|
||||
if (IsDirectory(src)) {
|
||||
|
@ -212,9 +215,11 @@ void Mv(char *src, char *dst) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "mv";
|
||||
if (!prog)
|
||||
prog = "mv";
|
||||
GetOpts(argc, argv);
|
||||
if (argc - optind < 2) PrintUsage(1, 2);
|
||||
if (argc - optind < 2)
|
||||
PrintUsage(1, 2);
|
||||
for (i = optind; i < argc - 1; ++i) {
|
||||
Mv(argv[i], argv[argc - 1]);
|
||||
}
|
||||
|
|
|
@ -130,9 +130,12 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
|
||||
static int PhdrFlagsToProt(Elf64_Word flags) {
|
||||
int prot = PROT_NONE;
|
||||
if (flags & PF_R) prot |= PROT_READ;
|
||||
if (flags & PF_W) prot |= PROT_WRITE;
|
||||
if (flags & PF_X) prot |= PROT_EXEC;
|
||||
if (flags & PF_R)
|
||||
prot |= PROT_READ;
|
||||
if (flags & PF_W)
|
||||
prot |= PROT_WRITE;
|
||||
if (flags & PF_X)
|
||||
prot |= PROT_EXEC;
|
||||
return prot;
|
||||
}
|
||||
|
||||
|
@ -163,11 +166,13 @@ static void ValidateMachoSection(const char *inpath, //
|
|||
bool found_pagezero;
|
||||
bool found_unixthread;
|
||||
struct MachoLoadCommand *cmd;
|
||||
if (!shdr) return;
|
||||
if (!shdr)
|
||||
return;
|
||||
if (elf->e_machine != EM_NEXGEN32E) {
|
||||
Die(inpath, ".macho section only supported for ELF x86_64");
|
||||
}
|
||||
if (!macho) Die(inpath, "corrupted .macho section content");
|
||||
if (!macho)
|
||||
Die(inpath, "corrupted .macho section content");
|
||||
if (shdr->sh_size < sizeof(struct MachoHeader)) {
|
||||
Die(inpath, ".macho section too small for mach-o header");
|
||||
}
|
||||
|
@ -349,10 +354,14 @@ static void HandleElf(const char *inpath, Elf64_Ehdr *elf, size_t esize) {
|
|||
elf->e_shentsize = 0;
|
||||
for (maxoff = i = 0; i < elf->e_phnum; ++i) {
|
||||
phdr = GetElfProgramHeaderAddress(elf, esize, i);
|
||||
if (!phdr) Die(inpath, "corrupted elf header");
|
||||
if (phdr->p_type == PT_INTERP) Die(inpath, "PT_INTERP isn't supported");
|
||||
if (phdr->p_type == PT_DYNAMIC) Die(inpath, "PT_DYNAMIC isn't supported");
|
||||
if (!phdr->p_filesz) continue;
|
||||
if (!phdr)
|
||||
Die(inpath, "corrupted elf header");
|
||||
if (phdr->p_type == PT_INTERP)
|
||||
Die(inpath, "PT_INTERP isn't supported");
|
||||
if (phdr->p_type == PT_DYNAMIC)
|
||||
Die(inpath, "PT_DYNAMIC isn't supported");
|
||||
if (!phdr->p_filesz)
|
||||
continue;
|
||||
maxoff = MAX(maxoff, phdr->p_offset + phdr->p_filesz);
|
||||
if (macho && phdr->p_type == PT_LOAD) {
|
||||
if (!(loadsegment = GetNextMachoLoadSegment(&loadcommand, &loadcount))) {
|
||||
|
@ -417,7 +426,8 @@ static void HandleInput(const char *inpath) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "objbincopy";
|
||||
if (!prog)
|
||||
prog = "objbincopy";
|
||||
GetOpts(argc, argv);
|
||||
if ((outfd = creat(outpath, 0755)) == -1) {
|
||||
DieSys(outpath);
|
||||
|
|
|
@ -160,7 +160,8 @@ static wontreturn void Die(const char *path, const char *reason) {
|
|||
|
||||
static wontreturn void SysExit(const char *path, const char *func) {
|
||||
const char *errstr;
|
||||
if (!(errstr = _strerrno(errno))) errstr = "EUNKNOWN";
|
||||
if (!(errstr = _strerrno(errno)))
|
||||
errstr = "EUNKNOWN";
|
||||
tinyprint(2, path, ": ", func, " failed with ", errstr, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -414,8 +415,10 @@ static void IndexSections(struct Package *pkg, struct Object *obj) {
|
|||
|
||||
static enum SectionKind ClassifySection(struct Package *pkg, struct Object *obj,
|
||||
uint8_t type, Elf64_Section shndx) {
|
||||
if (shndx == SHN_ABS) return kOther;
|
||||
if (type == STT_COMMON) return kBss;
|
||||
if (shndx == SHN_ABS)
|
||||
return kOther;
|
||||
if (type == STT_COMMON)
|
||||
return kBss;
|
||||
return pkg->sections.p[obj->section_offset + shndx].kind;
|
||||
}
|
||||
|
||||
|
@ -476,10 +479,14 @@ static void LoadPriviligedRefsToUndefs(struct Package *pkg,
|
|||
}
|
||||
erela = rela + shdr->sh_size / sizeof(*rela);
|
||||
for (; rela < erela; ++rela) {
|
||||
if (!ELF64_R_TYPE(rela->r_info)) continue;
|
||||
if (!(x = ELF64_R_SYM(rela->r_info))) continue;
|
||||
if (x > obj->symcount) Die("error", "elf overflow");
|
||||
if (obj->syms[x].st_shndx) continue; // symbol is defined
|
||||
if (!ELF64_R_TYPE(rela->r_info))
|
||||
continue;
|
||||
if (!(x = ELF64_R_SYM(rela->r_info)))
|
||||
continue;
|
||||
if (x > obj->symcount)
|
||||
Die("error", "elf overflow");
|
||||
if (obj->syms[x].st_shndx)
|
||||
continue; // symbol is defined
|
||||
if (ELF64_ST_BIND(obj->syms[x].st_info) != STB_WEAK &&
|
||||
ELF64_ST_BIND(obj->syms[x].st_info) != STB_GLOBAL) {
|
||||
tinyprint(2, "warning: undefined symbol not global\n", NULL);
|
||||
|
@ -526,7 +533,8 @@ static void OpenObject(struct Package *pkg, struct Object *obj, int oid) {
|
|||
}
|
||||
|
||||
static void CloseObject(struct Object *obj) {
|
||||
if (munmap(obj->elf, obj->size)) notpossible;
|
||||
if (munmap(obj->elf, obj->size))
|
||||
notpossible;
|
||||
}
|
||||
|
||||
static void LoadObjects(struct Package *pkg) {
|
||||
|
@ -567,14 +575,18 @@ static bool FindSymbol(const char *name, struct Package *pkg,
|
|||
size_t i;
|
||||
struct Symbol *sym;
|
||||
if ((sym = BisectSymbol(pkg, name))) {
|
||||
if (out_sym) *out_sym = sym;
|
||||
if (out_pkg) *out_pkg = pkg;
|
||||
if (out_sym)
|
||||
*out_sym = sym;
|
||||
if (out_pkg)
|
||||
*out_pkg = pkg;
|
||||
return true;
|
||||
}
|
||||
for (i = 0; i < directdeps->i; ++i) {
|
||||
if ((sym = BisectSymbol(directdeps->p[i], name))) {
|
||||
if (out_sym) *out_sym = sym;
|
||||
if (out_pkg) *out_pkg = directdeps->p[i];
|
||||
if (out_sym)
|
||||
*out_sym = sym;
|
||||
if (out_pkg)
|
||||
*out_pkg = directdeps->p[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -587,7 +599,8 @@ static void CheckStrictDeps(struct Package *pkg, struct Packages *deps) {
|
|||
struct Symbol *undef;
|
||||
for (i = 0; i < pkg->undefs.i; ++i) {
|
||||
undef = &pkg->undefs.p[i];
|
||||
if (undef->bind_ == STB_WEAK) continue;
|
||||
if (undef->bind_ == STB_WEAK)
|
||||
continue;
|
||||
if (!FindSymbol(pkg->strings.p + undef->name, pkg, deps, NULL, NULL)) {
|
||||
tinyprint(2, pkg->strings.p + pkg->path, ": undefined symbol '",
|
||||
pkg->strings.p + undef->name, "' (",
|
||||
|
@ -621,7 +634,8 @@ static void CheckYourPrivilege(struct Package *pkg, struct Packages *deps) {
|
|||
++f;
|
||||
}
|
||||
}
|
||||
if (f) exit(1);
|
||||
if (f)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static bool IsSymbolDirectlyReachable(struct Package *pkg,
|
||||
|
@ -639,7 +653,8 @@ static void Package(int argc, char *argv[], struct Package *pkg,
|
|||
CheckYourPrivilege(pkg, deps);
|
||||
WritePackage(pkg);
|
||||
for (i = 0; i < deps->i; ++i) {
|
||||
if (munmap(deps->p[i]->addr, deps->p[i]->size)) notpossible;
|
||||
if (munmap(deps->p[i]->addr, deps->p[i]->size))
|
||||
notpossible;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -300,7 +300,8 @@ static void CheckPe(const char *path, char *map, size_t size) {
|
|||
Die(exe->path, "PE ImportLookupTable and ImportAddressTable should "
|
||||
"have identical content");
|
||||
}
|
||||
if (!*ilt) break;
|
||||
if (!*ilt)
|
||||
break;
|
||||
CheckPeImportByName(exe, *ilt);
|
||||
}
|
||||
}
|
||||
|
@ -317,12 +318,17 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
for (i = 1; i < argc; ++i) {
|
||||
path = argv[i];
|
||||
if ((fd = open(path, O_RDONLY)) == -1) DieSys(path);
|
||||
if ((size = lseek(fd, 0, SEEK_END)) == -1) DieSys(path);
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
DieSys(path);
|
||||
if ((size = lseek(fd, 0, SEEK_END)) == -1)
|
||||
DieSys(path);
|
||||
map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (map == MAP_FAILED) DieSys(path);
|
||||
if (map == MAP_FAILED)
|
||||
DieSys(path);
|
||||
CheckPe(path, map, size);
|
||||
if (munmap(map, size)) DieSys(path);
|
||||
if (close(fd)) DieSys(path);
|
||||
if (munmap(map, size))
|
||||
DieSys(path);
|
||||
if (close(fd))
|
||||
DieSys(path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,8 +202,10 @@ long ParseSiSize(const char *s, long b) {
|
|||
}
|
||||
|
||||
void AddPromise(const char *s) {
|
||||
while (isspace(*s)) ++s;
|
||||
if (!*s) return;
|
||||
while (isspace(*s))
|
||||
++s;
|
||||
if (!*s)
|
||||
return;
|
||||
if (*g_promises) {
|
||||
strlcat(g_promises, " ", sizeof(g_promises));
|
||||
}
|
||||
|
@ -358,9 +360,12 @@ void NormalizeFileDescriptors(void) {
|
|||
int SetLimit(int r, long lo, long hi) {
|
||||
struct rlimit old;
|
||||
struct rlimit lim = {lo, hi};
|
||||
if (r < 0 || r >= RLIM_NLIMITS) return 0;
|
||||
if (!setrlimit(r, &lim)) return 0;
|
||||
if (getrlimit(r, &old)) return -1;
|
||||
if (r < 0 || r >= RLIM_NLIMITS)
|
||||
return 0;
|
||||
if (!setrlimit(r, &lim))
|
||||
return 0;
|
||||
if (getrlimit(r, &old))
|
||||
return -1;
|
||||
lim.rlim_cur = MIN(lim.rlim_cur, old.rlim_max);
|
||||
lim.rlim_max = MIN(lim.rlim_max, old.rlim_max);
|
||||
return setrlimit(r, &lim);
|
||||
|
@ -373,8 +378,10 @@ static int GetBaseCpuFreqMhz(void) {
|
|||
int SetCpuLimit(int secs) {
|
||||
#ifdef __x86_64__
|
||||
int mhz, lim;
|
||||
if (secs <= 0) return 0;
|
||||
if (!(mhz = GetBaseCpuFreqMhz())) return eopnotsupp();
|
||||
if (secs <= 0)
|
||||
return 0;
|
||||
if (!(mhz = GetBaseCpuFreqMhz()))
|
||||
return eopnotsupp();
|
||||
lim = ceil(3100. / mhz * secs);
|
||||
return SetLimit(RLIMIT_CPU, lim, lim);
|
||||
#else
|
||||
|
@ -464,8 +471,10 @@ enum Strategy GetStrategy(void) {
|
|||
void ApplyFilesystemPolicy(unsigned long ipromises) {
|
||||
const char *p;
|
||||
|
||||
if (g_dontunveil) return;
|
||||
if (!SupportsLandlock()) return;
|
||||
if (g_dontunveil)
|
||||
return;
|
||||
if (!SupportsLandlock())
|
||||
return;
|
||||
|
||||
Unveil(g_prog, "rx");
|
||||
|
||||
|
@ -587,7 +596,8 @@ void ApplyFilesystemPolicy(unsigned long ipromises) {
|
|||
|
||||
void DropCapabilities(void) {
|
||||
int e, i;
|
||||
if (!IsLinux()) return;
|
||||
if (!IsLinux())
|
||||
return;
|
||||
for (e = errno, i = 0;; ++i) {
|
||||
if (prctl(PR_CAPBSET_DROP, i) == -1) {
|
||||
if (errno == EINVAL || errno == EPERM) {
|
||||
|
@ -603,16 +613,21 @@ void DropCapabilities(void) {
|
|||
|
||||
bool FileExistsAndIsNewerThan(const char *filepath, const char *thanpath) {
|
||||
struct stat st1, st2;
|
||||
if (stat(filepath, &st1) == -1) return false;
|
||||
if (stat(thanpath, &st2) == -1) return false;
|
||||
if (st1.st_mtim.tv_sec < st2.st_mtim.tv_sec) return false;
|
||||
if (st1.st_mtim.tv_sec > st2.st_mtim.tv_sec) return true;
|
||||
if (stat(filepath, &st1) == -1)
|
||||
return false;
|
||||
if (stat(thanpath, &st2) == -1)
|
||||
return false;
|
||||
if (st1.st_mtim.tv_sec < st2.st_mtim.tv_sec)
|
||||
return false;
|
||||
if (st1.st_mtim.tv_sec > st2.st_mtim.tv_sec)
|
||||
return true;
|
||||
return st1.st_mtim.tv_nsec >= st2.st_mtim.tv_nsec;
|
||||
}
|
||||
|
||||
int Extract(const char *from, const char *to, int mode) {
|
||||
int fdin, fdout;
|
||||
if ((fdin = open(from, O_RDONLY)) == -1) return -1;
|
||||
if ((fdin = open(from, O_RDONLY)) == -1)
|
||||
return -1;
|
||||
if ((fdout = creat(to, mode)) == -1) {
|
||||
close(fdin);
|
||||
return -1;
|
||||
|
@ -627,7 +642,8 @@ int Extract(const char *from, const char *to, int mode) {
|
|||
|
||||
int CountEnviron(char **ep) {
|
||||
int res = 0;
|
||||
while (*ep++) ++res;
|
||||
while (*ep++)
|
||||
++res;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,8 @@ static int OnFile(const char *fpath, const struct stat *st, int typeflag,
|
|||
rc = unlink(fpath);
|
||||
}
|
||||
if (rc == -1) {
|
||||
if (force && errno == ENOENT) return 0;
|
||||
if (force && errno == ENOENT)
|
||||
return 0;
|
||||
perror(fpath);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -110,7 +111,8 @@ static void Remove(const char *path) {
|
|||
rc = nftw(path, OnFile, 128, FTW_PHYS | FTW_DEPTH);
|
||||
} else {
|
||||
if (lstat(path, &st)) {
|
||||
if (force && errno == ENOENT) return;
|
||||
if (force && errno == ENOENT)
|
||||
return;
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -125,7 +127,8 @@ static void Remove(const char *path) {
|
|||
}
|
||||
}
|
||||
if (rc == -1) {
|
||||
if (force && errno == ENOENT) return;
|
||||
if (force && errno == ENOENT)
|
||||
return;
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -134,7 +137,8 @@ static void Remove(const char *path) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "rm";
|
||||
if (!prog)
|
||||
prog = "rm";
|
||||
GetOpts(argc, argv);
|
||||
if (optind == argc) {
|
||||
tinyprint(2, prog, ": missing operand\n", NULL);
|
||||
|
|
|
@ -57,11 +57,13 @@ static wontreturn void DieOom(void) {
|
|||
}
|
||||
|
||||
static void Appends(char **b, const char *s) {
|
||||
if (appends(b, s) == -1) DieOom();
|
||||
if (appends(b, s) == -1)
|
||||
DieOom();
|
||||
}
|
||||
|
||||
static void Appendd(char **b, const void *p, size_t n) {
|
||||
if (appendd(b, p, n) == -1) DieOom();
|
||||
if (appendd(b, p, n) == -1)
|
||||
DieOom();
|
||||
}
|
||||
|
||||
size_t GetFdSize(int fd) {
|
||||
|
@ -84,10 +86,12 @@ void Process(const char *p, const char *pe, const char *path, bool isheader) {
|
|||
p2 = memchr(p, '\n', pe - p);
|
||||
p2 = p2 ? p2 + 1 : pe;
|
||||
if (LOOKINGAT(p, pe, "#if")) {
|
||||
if (isheader && !level++) continue;
|
||||
if (isheader && !level++)
|
||||
continue;
|
||||
}
|
||||
if (LOOKINGAT(p, pe, "#endif")) {
|
||||
if (isheader && !--level) continue;
|
||||
if (isheader && !--level)
|
||||
continue;
|
||||
}
|
||||
if (LOOKINGAT(p, pe, "/* clang-format off */")) {
|
||||
noformat = true;
|
||||
|
@ -114,26 +118,37 @@ void Visit(const char *path) {
|
|||
char *map;
|
||||
size_t size;
|
||||
bool isheader;
|
||||
if (!endswith(path, ".h") && !endswith(path, ".inc")) return;
|
||||
if (endswith(path, ".internal.h")) return;
|
||||
if (endswith(path, "/internal.h")) return;
|
||||
if (endswith(path, ".internal.inc")) return;
|
||||
if (endswith(path, "/internal.inc")) return;
|
||||
if (startswith(path, "libc/isystem/")) return;
|
||||
if (!endswith(path, ".h") && !endswith(path, ".inc"))
|
||||
return;
|
||||
if (endswith(path, ".internal.h"))
|
||||
return;
|
||||
if (endswith(path, "/internal.h"))
|
||||
return;
|
||||
if (endswith(path, ".internal.inc"))
|
||||
return;
|
||||
if (endswith(path, "/internal.inc"))
|
||||
return;
|
||||
if (startswith(path, "libc/isystem/"))
|
||||
return;
|
||||
isheader = endswith(path, ".h");
|
||||
if (isheader && isinterned(visited, path)) return;
|
||||
if (isheader && isinterned(visited, path))
|
||||
return;
|
||||
Appends(&output, "\n\f\n/*!BEGIN ");
|
||||
Appends(&output, path);
|
||||
Appends(&output, " */\n\n");
|
||||
intern(visited, path);
|
||||
if ((fd = open(path, O_RDONLY)) == -1) DieSys(path);
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
DieSys(path);
|
||||
if ((size = GetFdSize(fd))) {
|
||||
map = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (map == MAP_FAILED) DieSys(path);
|
||||
if (map == MAP_FAILED)
|
||||
DieSys(path);
|
||||
Process(map, map + size, path, isheader);
|
||||
if (munmap(map, size)) DieSys(path);
|
||||
if (munmap(map, size))
|
||||
DieSys(path);
|
||||
}
|
||||
if (close(fd)) DieSys(path);
|
||||
if (close(fd))
|
||||
DieSys(path);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -141,7 +156,8 @@ int main(int argc, char *argv[]) {
|
|||
const char *src;
|
||||
struct GetArgs ga;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "rollup";
|
||||
if (!prog)
|
||||
prog = "rollup";
|
||||
visited = newinterner();
|
||||
Appends(&output, "#ifndef COSMOPOLITAN_H_\n");
|
||||
Appends(&output, "#define COSMOPOLITAN_H_\n");
|
||||
|
|
|
@ -268,7 +268,8 @@ void RelayRequest(void) {
|
|||
rc = read(13, buf, PIPE_BUF);
|
||||
CHECK_NE(-1, rc);
|
||||
have = rc;
|
||||
if (!rc) break;
|
||||
if (!rc)
|
||||
break;
|
||||
transferred += have;
|
||||
for (i = 0; i < have; i += rc) {
|
||||
rc = mbedtls_ssl_write(&ezssl, buf + i, have - i);
|
||||
|
@ -288,9 +289,11 @@ void RelayRequest(void) {
|
|||
bool Recv(char *p, int n) {
|
||||
int i, rc;
|
||||
for (i = 0; i < n; i += rc) {
|
||||
do rc = mbedtls_ssl_read(&ezssl, p + i, n - i);
|
||||
do
|
||||
rc = mbedtls_ssl_read(&ezssl, p + i, n - i);
|
||||
while (rc == MBEDTLS_ERR_SSL_WANT_READ);
|
||||
if (!rc) return false;
|
||||
if (!rc)
|
||||
return false;
|
||||
if (rc < 0) {
|
||||
if (rc == MBEDTLS_ERR_NET_CONN_RESET) {
|
||||
EzTlsDie("connection reset", rc);
|
||||
|
@ -334,10 +337,12 @@ int ReadResponse(void) {
|
|||
mbedtls_ssl_close_notify(&ezssl);
|
||||
break;
|
||||
} else if (msg[4] == kRunitStdout || msg[4] == kRunitStderr) {
|
||||
if (!Recv(msg, 4)) goto TruncatedMessage;
|
||||
if (!Recv(msg, 4))
|
||||
goto TruncatedMessage;
|
||||
int n = READ32BE(msg);
|
||||
char *s = malloc(n);
|
||||
if (!Recv(s, n)) goto TruncatedMessage;
|
||||
if (!Recv(s, n))
|
||||
goto TruncatedMessage;
|
||||
write(2, s, n);
|
||||
free(s);
|
||||
} else {
|
||||
|
@ -356,7 +361,8 @@ int RunOnHost(char *spec) {
|
|||
int err;
|
||||
char *p;
|
||||
for (p = spec; *p; ++p) {
|
||||
if (*p == ':') *p = ' ';
|
||||
if (*p == ':')
|
||||
*p = ' ';
|
||||
}
|
||||
int got =
|
||||
sscanf(spec, "%100s %hu %hu", g_hostname, &g_runitdport, &g_sshport);
|
||||
|
@ -365,7 +371,8 @@ int RunOnHost(char *spec) {
|
|||
fprintf(stderr, "what on earth %#s -> %d\n", spec, got);
|
||||
exit(1);
|
||||
}
|
||||
if (!strchr(g_hostname, '.')) strcat(g_hostname, ".test.");
|
||||
if (!strchr(g_hostname, '.'))
|
||||
strcat(g_hostname, ".test.");
|
||||
DEBUGF("connecting to %s port %d", g_hostname, g_runitdport);
|
||||
for (;;) {
|
||||
Connect();
|
||||
|
@ -373,7 +380,8 @@ int RunOnHost(char *spec) {
|
|||
struct timespec start = timespec_real();
|
||||
err = EzHandshake2();
|
||||
handshake_latency = timespec_tomicros(timespec_sub(timespec_real(), start));
|
||||
if (!err) break;
|
||||
if (!err)
|
||||
break;
|
||||
WARNF("handshake with %s:%d failed -0x%04x (%s)", //
|
||||
g_hostname, g_runitdport, err, GetTlsError(err));
|
||||
close(g_sock);
|
||||
|
@ -446,22 +454,27 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
|||
// wait for children to terminate
|
||||
for (;;) {
|
||||
if ((pid = wait(&ws)) == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
if (errno == ECHILD) break;
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (errno == ECHILD)
|
||||
break;
|
||||
FATALF("wait failed");
|
||||
}
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (pids[i] != pid) continue;
|
||||
if (pids[i] != pid)
|
||||
continue;
|
||||
if (WIFEXITED(ws)) {
|
||||
if (WEXITSTATUS(ws)) {
|
||||
INFOF("%s exited with %d", argv[i], WEXITSTATUS(ws));
|
||||
} else {
|
||||
DEBUGF("%s exited with %d", argv[i], WEXITSTATUS(ws));
|
||||
}
|
||||
if (!exitcode) exitcode = WEXITSTATUS(ws);
|
||||
if (!exitcode)
|
||||
exitcode = WEXITSTATUS(ws);
|
||||
} else {
|
||||
INFOF("%s terminated with %s", argv[i], strsignal(WTERMSIG(ws)));
|
||||
if (!exitcode) exitcode = 128 + WTERMSIG(ws);
|
||||
if (!exitcode)
|
||||
exitcode = 128 + WTERMSIG(ws);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -515,8 +515,10 @@ void *ClientWorker(void *arg) {
|
|||
int i = 0;
|
||||
char *args[8] = {0};
|
||||
args[i++] = client->tmpexepath;
|
||||
if (use_strace) args[i++] = "--strace";
|
||||
if (use_ftrace) args[i++] = "--ftrace";
|
||||
if (use_strace)
|
||||
args[i++] = "--strace";
|
||||
if (use_ftrace)
|
||||
args[i++] = "--ftrace";
|
||||
|
||||
// run program, tee'ing stderr to both log and client
|
||||
DEBUF("spawning %s", client->tmpexepath);
|
||||
|
@ -776,11 +778,14 @@ int Serve(void) {
|
|||
}
|
||||
|
||||
void Daemonize(void) {
|
||||
if (fork() > 0) _exit(0);
|
||||
if (fork() > 0)
|
||||
_exit(0);
|
||||
setsid();
|
||||
if (fork() > 0) _exit(0);
|
||||
if (fork() > 0)
|
||||
_exit(0);
|
||||
dup2(g_bogusfd, 0);
|
||||
if (!g_sendready) dup2(g_bogusfd, 1);
|
||||
if (!g_sendready)
|
||||
dup2(g_bogusfd, 1);
|
||||
close(2);
|
||||
open(kLogFile, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0644);
|
||||
extern long __klog_handle;
|
||||
|
@ -796,7 +801,8 @@ int main(int argc, char *argv[]) {
|
|||
signal(SIGPIPE, SIG_IGN);
|
||||
setenv("TZ", "PST", true);
|
||||
gethostname(g_hostname, sizeof(g_hostname));
|
||||
for (int i = 3; i < 16; ++i) close(i);
|
||||
for (int i = 3; i < 16; ++i)
|
||||
close(i);
|
||||
errno = 0;
|
||||
// poll()'ing /dev/null stdin file descriptor on xnu returns POLLNVAL?!
|
||||
if (IsWindows()) {
|
||||
|
@ -805,7 +811,8 @@ int main(int argc, char *argv[]) {
|
|||
g_bogusfd = open("/dev/zero", O_RDONLY | O_CLOEXEC);
|
||||
}
|
||||
mkdir("o", 0700);
|
||||
if (g_daemonize) Daemonize();
|
||||
if (g_daemonize)
|
||||
Daemonize();
|
||||
Serve();
|
||||
free(g_psk);
|
||||
#ifdef MODE_DBG
|
||||
|
|
|
@ -102,7 +102,8 @@ static bool IsSupportedPath(const char *path) {
|
|||
for (i = 0;; ++i) {
|
||||
switch (path[i]) {
|
||||
case 0:
|
||||
if (i) return true;
|
||||
if (i)
|
||||
return true;
|
||||
// fallthrough
|
||||
case '\r':
|
||||
case '\n':
|
||||
|
@ -137,8 +138,10 @@ static bool ProduceDigest(const char *path, FILE *f) {
|
|||
char hexdigest[65];
|
||||
char mode[2] = {g_mode};
|
||||
unsigned char digest[32];
|
||||
if (!IsSupportedPath(path)) return false;
|
||||
if (!GetDigest(path, f, digest)) return false;
|
||||
if (!IsSupportedPath(path))
|
||||
return false;
|
||||
if (!GetDigest(path, f, digest))
|
||||
return false;
|
||||
hexpcpy(hexdigest, digest, 32);
|
||||
tinyprint(1, hexdigest, " ", mode, path, "\n", NULL);
|
||||
return true;
|
||||
|
@ -152,17 +155,24 @@ static bool CheckDigests(const char *path, FILE *f) {
|
|||
unsigned char wantdigest[32], gotdigest[32];
|
||||
char buf[64 + 2 + PATH_MAX + 1 + 1], *p;
|
||||
for (line = 0; fgets(buf, sizeof(buf), f); ++line) {
|
||||
if (!*chomp(buf)) continue;
|
||||
if (!*chomp(buf))
|
||||
continue;
|
||||
for (p = buf, i = 0; i < 32; ++i) {
|
||||
if ((a = kHexToInt[*p++ & 255]) == -1) goto InvalidLine;
|
||||
if ((b = kHexToInt[*p++ & 255]) == -1) goto InvalidLine;
|
||||
if ((a = kHexToInt[*p++ & 255]) == -1)
|
||||
goto InvalidLine;
|
||||
if ((b = kHexToInt[*p++ & 255]) == -1)
|
||||
goto InvalidLine;
|
||||
wantdigest[i] = a << 4 | b;
|
||||
}
|
||||
if (*p++ != ' ') goto InvalidLine;
|
||||
if (!IsModeCharacter(*p++)) goto InvalidLine;
|
||||
if (*p++ != ' ')
|
||||
goto InvalidLine;
|
||||
if (!IsModeCharacter(*p++))
|
||||
goto InvalidLine;
|
||||
path2 = p;
|
||||
if (!*path2) goto InvalidLine;
|
||||
if (!IsSupportedPath(path2)) continue;
|
||||
if (!*path2)
|
||||
goto InvalidLine;
|
||||
if (!IsSupportedPath(path2))
|
||||
continue;
|
||||
if ((f2 = fopen(path2, "rb"))) {
|
||||
if (GetDigest(path2, f2, gotdigest)) {
|
||||
if (!memcmp(wantdigest, gotdigest, 32)) {
|
||||
|
@ -210,7 +220,8 @@ int main(int argc, char *argv[]) {
|
|||
FILE *f;
|
||||
bool k = true;
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "sha256sum";
|
||||
if (!prog)
|
||||
prog = "sha256sum";
|
||||
GetOpts(argc, argv);
|
||||
if (optind == argc) {
|
||||
f = stdin;
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
int main(int argc, char *argv[]) {
|
||||
long x, sum = 0;
|
||||
if (argc == 2 && !strcmp(argv[1], "-x")) {
|
||||
while (scanf("%lx", &x) > 0) sum += x;
|
||||
while (scanf("%lx", &x) > 0)
|
||||
sum += x;
|
||||
} else {
|
||||
while (scanf("%ld", &x) > 0) sum += x;
|
||||
while (scanf("%ld", &x) > 0)
|
||||
sum += x;
|
||||
}
|
||||
printf("%,ld\n", sum);
|
||||
return 0;
|
||||
|
|
|
@ -29,7 +29,8 @@ int main(int argc, char *argv[]) {
|
|||
const char *prog;
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "touch";
|
||||
if (!prog)
|
||||
prog = "touch";
|
||||
|
||||
if (argc < 2) {
|
||||
tinyprint(2, prog, ": missing operand\n", NULL);
|
||||
|
|
|
@ -91,10 +91,12 @@ int main(int argc, char *argv[]) {
|
|||
p++;
|
||||
continue;
|
||||
}
|
||||
if (i > 1) errx(1, "<stdin>:%zu - too many fields", count);
|
||||
if (i > 1)
|
||||
errx(1, "<stdin>:%zu - too many fields", count);
|
||||
fields[i++] = p;
|
||||
}
|
||||
if (i != 2) errx(1, "<stdin>:%zu - malformed line", count);
|
||||
if (i != 2)
|
||||
errx(1, "<stdin>:%zu - malformed line", count);
|
||||
|
||||
if (unveil(fields[0], fields[1]) == -1)
|
||||
err(1, "unveil(%s, %s)", fields[0], fields[1]);
|
||||
|
@ -104,7 +106,8 @@ int main(int argc, char *argv[]) {
|
|||
err(1, "getline");
|
||||
}
|
||||
|
||||
if (unveil(NULL, NULL) == -1) err(1, "unveil(NULL, NULL)");
|
||||
if (unveil(NULL, NULL) == -1)
|
||||
err(1, "unveil(NULL, NULL)");
|
||||
|
||||
__sys_execve(prog, argv + optind, environ);
|
||||
err(127, "execve");
|
||||
|
|
|
@ -38,7 +38,8 @@ static wontreturn void PrintUsage(int rc, int fd) {
|
|||
int main(int argc, char *argv[]) {
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "verynice";
|
||||
if (!prog)
|
||||
prog = "verynice";
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "h")) != -1) {
|
||||
|
|
|
@ -51,7 +51,8 @@ static wontreturn void Die(const char *path, const char *reason) {
|
|||
|
||||
static wontreturn void SysDie(const char *path, const char *func) {
|
||||
const char *errstr;
|
||||
if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN";
|
||||
if (!(errstr = _strerdoc(errno)))
|
||||
errstr = "EUNKNOWN";
|
||||
tinyprint(2, path, ": ", func, " failed with ", errstr, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -133,7 +134,8 @@ static void CopyZip(void) {
|
|||
eocd = ineof - kZipCdirHdrMinSize;
|
||||
stop = MAX(eocd - 65536, inmap);
|
||||
for (;; --eocd) {
|
||||
if (eocd < stop) return;
|
||||
if (eocd < stop)
|
||||
return;
|
||||
if (READ32LE(eocd) == kZipCdirHdrMagic) {
|
||||
if (IsZipEocd32(inmap, insize, eocd - inmap) != kZipOk) {
|
||||
Die(inpath, "found bad eocd record");
|
||||
|
@ -217,7 +219,8 @@ int main(int argc, char *argv[]) {
|
|||
ShowCrashReports();
|
||||
#endif
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "apelink";
|
||||
if (!prog)
|
||||
prog = "apelink";
|
||||
GetOpts(argc, argv);
|
||||
if ((infd = open(inpath, O_RDONLY)) == -1) {
|
||||
SysDie(inpath, "open");
|
||||
|
|
|
@ -189,9 +189,11 @@ void ProcessFile(struct ElfWriter *elf, const char *path) {
|
|||
name = name_;
|
||||
} else {
|
||||
name = path;
|
||||
if (basenamify_) name = basename(gc(xstrdup(name)));
|
||||
if (basenamify_)
|
||||
name = basename(gc(xstrdup(name)));
|
||||
name = StripComponents(name, strip_components_);
|
||||
if (path_prefix_) name = gc(xjoinpaths(path_prefix_, name));
|
||||
if (path_prefix_)
|
||||
name = gc(xjoinpaths(path_prefix_, name));
|
||||
}
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
st.st_size = 0;
|
||||
|
@ -225,10 +227,12 @@ void zipobj(int argc, char **argv) {
|
|||
struct ElfWriter *elf;
|
||||
unassert(argc < UINT16_MAX / 3 - 64); /* ELF 64k section limit */
|
||||
GetOpts(&argc, &argv);
|
||||
for (i = 0; i < argc; ++i) CheckFilenameKosher(argv[i]);
|
||||
for (i = 0; i < argc; ++i)
|
||||
CheckFilenameKosher(argv[i]);
|
||||
elf = elfwriter_open(outpath_, 0644, arch_);
|
||||
elfwriter_cargoculting(elf);
|
||||
for (i = 0; i < argc; ++i) ProcessFile(elf, argv[i]);
|
||||
for (i = 0; i < argc; ++i)
|
||||
ProcessFile(elf, argv[i]);
|
||||
PullEndOfCentralDirectoryIntoLinkage(elf);
|
||||
elfwriter_close(elf);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,8 @@ static wontreturn void PrintUsage(int fd, int rc) {
|
|||
|
||||
static const char *DescribeErrno(void) {
|
||||
const char *reason;
|
||||
if (!(reason = _strerdoc(errno))) reason = "Unknown error";
|
||||
if (!(reason = _strerdoc(errno)))
|
||||
reason = "Unknown error";
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
@ -499,7 +500,8 @@ int _curl(int argc, char *argv[]) {
|
|||
break;
|
||||
case kHttpClientStateBody:
|
||||
WriteOutput(p + i - g, g);
|
||||
if (!g) goto Finished;
|
||||
if (!g)
|
||||
goto Finished;
|
||||
break;
|
||||
case kHttpClientStateBodyLengthed:
|
||||
unassert(g);
|
||||
|
|
|
@ -60,7 +60,8 @@ static void Open(void) {
|
|||
exit(1);
|
||||
}
|
||||
CHECK_NE(-1, fstat(fd, &st));
|
||||
if (!(size = st.st_size)) exit(0);
|
||||
if (!(size = st.st_size))
|
||||
exit(0);
|
||||
CHECK_NE(MAP_FAILED,
|
||||
(data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0)));
|
||||
LOGIFNEG1(close(fd));
|
||||
|
@ -136,7 +137,8 @@ static void Print(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) return 1;
|
||||
if (argc < 2)
|
||||
return 1;
|
||||
path = argv[1];
|
||||
Open();
|
||||
Check();
|
||||
|
|
|
@ -52,8 +52,10 @@ void Encode(void) {
|
|||
b = getchar();
|
||||
c = getchar();
|
||||
w = a << 020;
|
||||
if (b != -1) w |= b << 010;
|
||||
if (c != -1) w |= c;
|
||||
if (b != -1)
|
||||
w |= b << 010;
|
||||
if (c != -1)
|
||||
w |= c;
|
||||
putchar(CHARS[(w >> 18) & 077]);
|
||||
putchar(CHARS[(w >> 12) & 077]);
|
||||
putchar(b != -1 ? CHARS[(w >> 6) & 077] : '=');
|
||||
|
@ -65,7 +67,8 @@ void Encode(void) {
|
|||
int Get(void) {
|
||||
int c;
|
||||
while ((c = getchar()) != -1) {
|
||||
if ((c = kBase64[c]) != -1) break;
|
||||
if ((c = kBase64[c]) != -1)
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
@ -76,11 +79,15 @@ void Decode(void) {
|
|||
c = Get();
|
||||
d = Get();
|
||||
w = a << 18 | b << 12;
|
||||
if (c != -1) w |= c << 6;
|
||||
if (d != -1) w |= d;
|
||||
if (c != -1)
|
||||
w |= c << 6;
|
||||
if (d != -1)
|
||||
w |= d;
|
||||
putchar((w & 0xFF0000) >> 020);
|
||||
if (c != -1) putchar((w & 0x00FF00) >> 010);
|
||||
if (d != -1) putchar((w & 0x0000FF) >> 000);
|
||||
if (c != -1)
|
||||
putchar((w & 0x00FF00) >> 010);
|
||||
if (d != -1)
|
||||
putchar((w & 0x0000FF) >> 000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,8 @@ static void printelfehdr(void) {
|
|||
|
||||
static void printelfsegmentheader(int i) {
|
||||
Elf64_Phdr *phdr = GetElfProgramHeaderAddress(elf, st->st_size, i);
|
||||
if (!phdr) return;
|
||||
if (!phdr)
|
||||
return;
|
||||
printf("/\tElf64_Phdr *phdr = GetElfProgramHeaderAddress(elf, st->st_size, "
|
||||
"%d)\n",
|
||||
i);
|
||||
|
@ -132,13 +133,15 @@ static void printelfsegmentheader(int i) {
|
|||
static void printelfsegmentheaders(void) {
|
||||
printf("\n");
|
||||
printf("\t.org\t%#x\n", elf->e_phoff);
|
||||
for (unsigned i = 0; i < elf->e_phnum; ++i) printelfsegmentheader(i);
|
||||
for (unsigned i = 0; i < elf->e_phnum; ++i)
|
||||
printelfsegmentheader(i);
|
||||
}
|
||||
|
||||
static void printelfsectionheader(int i, char *shstrtab) {
|
||||
Elf64_Shdr *shdr;
|
||||
shdr = GetElfSectionHeaderAddress(elf, st->st_size, i);
|
||||
if (!shdr) return;
|
||||
if (!shdr)
|
||||
return;
|
||||
printf("/\tElf64_Shdr *shdr = GetElfSectionHeaderAddress(elf, st->st_size, "
|
||||
"%d)\n",
|
||||
i);
|
||||
|
@ -170,7 +173,8 @@ static void printelfsectionheaders(void) {
|
|||
Elf64_Shdr *shdr, *shshdr;
|
||||
shshdr = GetElfSectionHeaderAddress(elf, st->st_size, elf->e_shstrndx);
|
||||
shstrtab = GetElfSectionNameStringTable(elf, st->st_size);
|
||||
if (!shshdr || !shstrtab) return;
|
||||
if (!shshdr || !shstrtab)
|
||||
return;
|
||||
if (shstrtab) {
|
||||
printf("\n");
|
||||
printf("\t.org\t%#x\n", elf->e_shoff);
|
||||
|
@ -181,7 +185,8 @@ static void printelfsectionheaders(void) {
|
|||
printf("\t.org\t%#x\n", shshdr->sh_offset);
|
||||
for (i = 0; i < elf->e_shnum; ++i) {
|
||||
shdr = GetElfSectionHeaderAddress(elf, st->st_size, i);
|
||||
if (!shdr) break;
|
||||
if (!shdr)
|
||||
break;
|
||||
str = GetElfString(elf, st->st_size, shstrtab, shdr->sh_name);
|
||||
show(".asciz", format(b1, "%`'s", str), NULL);
|
||||
}
|
||||
|
@ -191,18 +196,23 @@ static void printelfsectionheaders(void) {
|
|||
static void printelfgroups(void) {
|
||||
for (int i = 0; i < elf->e_shnum; ++i) {
|
||||
Elf64_Shdr *shdr = GetElfSectionHeaderAddress(elf, st->st_size, i);
|
||||
if (!shdr) break;
|
||||
if (!shdr)
|
||||
break;
|
||||
if (shdr->sh_type == SHT_GROUP) {
|
||||
const Elf64_Shdr *symhdr =
|
||||
GetElfSectionHeaderAddress(elf, st->st_size, shdr->sh_link);
|
||||
if (!symhdr) break;
|
||||
if (!symhdr)
|
||||
break;
|
||||
const Elf64_Shdr *strhdr =
|
||||
GetElfSectionHeaderAddress(elf, st->st_size, symhdr->sh_link);
|
||||
if (!strhdr) break;
|
||||
if (!strhdr)
|
||||
break;
|
||||
Elf64_Sym *syms = GetElfSectionAddress(elf, st->st_size, symhdr);
|
||||
if (!syms) break;
|
||||
if (!syms)
|
||||
break;
|
||||
char *strs = GetElfSectionAddress(elf, st->st_size, strhdr);
|
||||
if (!strs) break;
|
||||
if (!strs)
|
||||
break;
|
||||
printf("\n");
|
||||
printf("//\t%s group\n",
|
||||
GetElfString(elf, st->st_size, strs, syms[shdr->sh_info].st_name));
|
||||
|
@ -276,7 +286,8 @@ static void printelfsymbol(Elf64_Sym *sym, char *strtab, char *shstrtab) {
|
|||
static void printelfsymboltable(void) {
|
||||
size_t i, symcount = 0;
|
||||
Elf64_Sym *symtab = GetElfSymbols(elf, st->st_size, SHT_SYMTAB, &symcount);
|
||||
if (!symtab) return;
|
||||
if (!symtab)
|
||||
return;
|
||||
char *strtab = GetElfStringTable(elf, st->st_size, ".strtab");
|
||||
char *shstrtab = GetElfSectionNameStringTable(elf, st->st_size);
|
||||
printf("\n\n");
|
||||
|
@ -292,7 +303,8 @@ static void printelfsymboltable(void) {
|
|||
static void printelfdynsymboltable(void) {
|
||||
size_t i, symcount = 0;
|
||||
Elf64_Sym *symtab = GetElfSymbols(elf, st->st_size, SHT_DYNSYM, &symcount);
|
||||
if (!symtab) return;
|
||||
if (!symtab)
|
||||
return;
|
||||
char *strtab = GetElfStringTable(elf, st->st_size, ".dynstr");
|
||||
char *shstrtab = GetElfSectionNameStringTable(elf, st->st_size);
|
||||
printf("\n\n");
|
||||
|
@ -342,7 +354,8 @@ static void printelfrelocations(void) {
|
|||
(uintptr_t)elf + shdr->sh_offset + shdr->sh_size));
|
||||
++rela, ++j) {
|
||||
symtab = GetElfSectionHeaderAddress(elf, st->st_size, shdr->sh_link);
|
||||
if (!symtab) continue;
|
||||
if (!symtab)
|
||||
continue;
|
||||
count = symtab->sh_size / symtab->sh_entsize;
|
||||
syms = GetElfSectionAddress(elf, st->st_size, symtab);
|
||||
sym = ELF64_R_SYM(rela->r_info);
|
||||
|
|
|
@ -40,7 +40,8 @@ char *tabpad(const char *s, unsigned width) {
|
|||
l = strlen(s);
|
||||
need = width > l ? (roundup(width, 8) - l - 1) / 8 + 1 : 0;
|
||||
p = memcpy(malloc(l + need + 2), s, l);
|
||||
for (i = 0; i < need; ++i) p[l + i] = '\t';
|
||||
for (i = 0; i < need; ++i)
|
||||
p[l + i] = '\t';
|
||||
if (!need) {
|
||||
p[l] = ' ';
|
||||
++need;
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
static size_t countzeroes(const uint8_t *data, size_t size) {
|
||||
size_t i;
|
||||
for (i = 0; i < size; ++i) {
|
||||
if (data[i] != '\0') break;
|
||||
if (data[i] != '\0')
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -42,19 +43,22 @@ void disassemblehex(uint8_t *data, size_t size, FILE *f) {
|
|||
if (z > 2) {
|
||||
fprintf(f, "\t.%s\t%zu*%d\n", "zero", z, kDisassembleHexColumns);
|
||||
i += z * kDisassembleHexColumns;
|
||||
if (i == size) break;
|
||||
if (i == size)
|
||||
break;
|
||||
}
|
||||
fprintf(f, "\t.%s\t", "byte");
|
||||
bzero(glyphs, sizeof(glyphs));
|
||||
}
|
||||
/* TODO(jart): Fix Emacs */
|
||||
glyphs[col] = kCp437[ch == '"' || ch == '\\' || ch == '#' ? '.' : ch];
|
||||
if (col) fputc(',', f);
|
||||
if (col)
|
||||
fputc(',', f);
|
||||
fprintf(f, "0x%02x", ch);
|
||||
if (++col == kDisassembleHexColumns) {
|
||||
col = 0;
|
||||
fprintf(f, "\t#%hs\n", glyphs);
|
||||
}
|
||||
}
|
||||
if (col) fputc('\n', f);
|
||||
if (col)
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ char *RecreateFlags(const struct IdName *names, unsigned long id) {
|
|||
}
|
||||
}
|
||||
if (id) {
|
||||
if (bufi) APPEND(&bufp, &bufi, &bufn, "|");
|
||||
if (bufi)
|
||||
APPEND(&bufp, &bufi, &bufn, "|");
|
||||
CONCAT(&bufp, &bufi, &bufn, extrabuf,
|
||||
snprintf(extrabuf, sizeof(extrabuf), "%#x", id));
|
||||
} else if (!bufi) {
|
||||
|
|
|
@ -40,14 +40,17 @@ void showtitle(const char *brand, const char *tool, const char *title,
|
|||
printf("/*");
|
||||
if (modeline) {
|
||||
printf("-*-%-71s-*-│\n│ vi:%-70s:vi │\n╞", modeline->emacs, modeline->vim);
|
||||
for (unsigned i = 0; i < 78; ++i) printf("═");
|
||||
for (unsigned i = 0; i < 78; ++i)
|
||||
printf("═");
|
||||
printf("╡\n│ %-76s ", buf);
|
||||
} else {
|
||||
for (unsigned i = 0; i < 75; ++i) printf("─");
|
||||
for (unsigned i = 0; i < 75; ++i)
|
||||
printf("─");
|
||||
printf("│─╗\n│ %-73s ─╬─", buf);
|
||||
}
|
||||
printf("│\n╚─");
|
||||
for (unsigned i = 0; i < 75; ++i) printf("─");
|
||||
for (unsigned i = 0; i < 75; ++i)
|
||||
printf("─");
|
||||
printf("%s", modeline ? "─" : "│");
|
||||
if (description) {
|
||||
/* TODO(jart): paragraph fill */
|
||||
|
|
|
@ -187,7 +187,8 @@ static void showmacholoadgeneric(struct MachoLoadCommand *lc) {
|
|||
bzero(glyphs, sizeof(glyphs));
|
||||
}
|
||||
glyphs[col] = kCp437[c];
|
||||
if (col) putchar(',');
|
||||
if (col)
|
||||
putchar(',');
|
||||
printf("0x%02x", c);
|
||||
if (++col == COLS) {
|
||||
col = 0;
|
||||
|
@ -334,7 +335,8 @@ void showall(void) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int64_t fd;
|
||||
struct stat st[1];
|
||||
if (argc != 2) fprintf(stderr, "usage: %s FILE\n", argv[0]), exit(1);
|
||||
if (argc != 2)
|
||||
fprintf(stderr, "usage: %s FILE\n", argv[0]), exit(1);
|
||||
if ((fd = open((path = argv[1]), O_RDONLY)) == -1 || fstat(fd, st) == -1 ||
|
||||
(macho = mmap(NULL, (machosize = st->st_size), PROT_READ, MAP_SHARED, fd,
|
||||
0)) == MAP_FAILED) {
|
||||
|
|
|
@ -56,7 +56,8 @@ static struct NtImageSectionHeader *sections;
|
|||
static size_t section_count;
|
||||
|
||||
static void *GetOff(uint32_t off) {
|
||||
if (off < mzsize) return (char *)mz + off;
|
||||
if (off < mzsize)
|
||||
return (char *)mz + off;
|
||||
fprintf(stderr, "%s: off %#x not defined within image\n", path, off);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -377,7 +378,8 @@ int main(int argc, char *argv[]) {
|
|||
int64_t fd;
|
||||
struct stat st[1];
|
||||
ShowCrashReports();
|
||||
if (argc != 2) fprintf(stderr, "usage: %s FILE\n", argv[0]), exit(1);
|
||||
if (argc != 2)
|
||||
fprintf(stderr, "usage: %s FILE\n", argv[0]), exit(1);
|
||||
if ((fd = open((path = argv[1]), O_RDONLY)) == -1 || fstat(fd, st) == -1 ||
|
||||
(mz = mmap(NULL, (mzsize = st->st_size), PROT_READ, MAP_SHARED, fd, 0)) ==
|
||||
MAP_FAILED) {
|
||||
|
|
|
@ -95,7 +95,8 @@ void LoadFlags(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
void Expand(int c) {
|
||||
if (end >= TERMS) Error(5, "OUT OF TERMS");
|
||||
if (end >= TERMS)
|
||||
Error(5, "OUT OF TERMS");
|
||||
mem[end++] = c;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,8 @@ static int Greed(void) {
|
|||
} else {
|
||||
c = fgetwc(stdin);
|
||||
}
|
||||
if (c == EOF) return c;
|
||||
if (c == EOF)
|
||||
return c;
|
||||
if (!t) {
|
||||
if (c == '#' || c == ';') {
|
||||
t = 1;
|
||||
|
@ -218,7 +219,8 @@ static int Greed(void) {
|
|||
|
||||
static int Need(void) {
|
||||
int c;
|
||||
if ((c = Greed()) != EOF) return c;
|
||||
if ((c = Greed()) != EOF)
|
||||
return c;
|
||||
Error(1, "unfinished expression");
|
||||
}
|
||||
|
||||
|
@ -227,7 +229,8 @@ static struct Node *Parse1(void) {
|
|||
int i, oldsp;
|
||||
struct Node *r, *p, *q;
|
||||
do {
|
||||
if ((c = Greed()) == EOF) return 0;
|
||||
if ((c = Greed()) == EOF)
|
||||
return 0;
|
||||
} while (iswspace(c));
|
||||
if (c == L'λ' || c == '\\') {
|
||||
oldsp = sp;
|
||||
|
@ -245,7 +248,8 @@ static struct Node *Parse1(void) {
|
|||
}
|
||||
}
|
||||
q = Parse1();
|
||||
if (!q) Error(4, "lambda needs body");
|
||||
if (!q)
|
||||
Error(4, "lambda needs body");
|
||||
p->l = q;
|
||||
while ((q = Parse1())) {
|
||||
p->l = NewNode(2, 0, p->l, q);
|
||||
|
@ -261,23 +265,27 @@ static struct Node *Parse1(void) {
|
|||
i *= 10;
|
||||
i += c - '0';
|
||||
c = Greed();
|
||||
if (c == EOF) break;
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (!iswdigit(c)) {
|
||||
unget = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i -= indexing;
|
||||
if (i < 0) Error(5, "undefined variable: %lc", c);
|
||||
if (i < 0)
|
||||
Error(5, "undefined variable: %lc", c);
|
||||
return NewNode(1, i, 0, 0);
|
||||
} else if (c == '(') {
|
||||
p = r = Parse1();
|
||||
if (!p) Error(6, "empty parenthesis");
|
||||
if (!p)
|
||||
Error(6, "empty parenthesis");
|
||||
while ((q = Parse1())) {
|
||||
r = NewNode(2, 0, r, q);
|
||||
}
|
||||
c = Need();
|
||||
if (c != ')') Error(7, "expected closing parenthesis");
|
||||
if (c != ')')
|
||||
Error(7, "expected closing parenthesis");
|
||||
return r;
|
||||
} else if (c == ')') {
|
||||
unget = c;
|
||||
|
@ -290,7 +298,8 @@ static struct Node *Parse1(void) {
|
|||
static struct Node *Parse(void) {
|
||||
struct Node *r, *p, *q;
|
||||
p = r = Parse1();
|
||||
if (!p) Error(6, "empty expression");
|
||||
if (!p)
|
||||
Error(6, "empty expression");
|
||||
while ((q = Parse1())) {
|
||||
r = NewNode(2, 0, r, q);
|
||||
}
|
||||
|
|
|
@ -107,7 +107,8 @@ static int Greed(void) {
|
|||
} else {
|
||||
c = fgetwc(stdin);
|
||||
}
|
||||
if (c == EOF) return c;
|
||||
if (c == EOF)
|
||||
return c;
|
||||
if (!t) {
|
||||
if (c == '#' || c == ';') {
|
||||
t = 1;
|
||||
|
@ -119,7 +120,8 @@ static int Greed(void) {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (iswspace(c)) continue;
|
||||
if (iswspace(c))
|
||||
continue;
|
||||
if (!str) {
|
||||
switch (c) {
|
||||
case L'⊥':
|
||||
|
@ -211,7 +213,8 @@ static int Greed(void) {
|
|||
|
||||
static int Need(void) {
|
||||
int c;
|
||||
if ((c = Greed()) != EOF) return c;
|
||||
if ((c = Greed()) != EOF)
|
||||
return c;
|
||||
Error(1, "unfinished expression");
|
||||
}
|
||||
|
||||
|
@ -219,20 +222,24 @@ static struct Node *Parse1(void) {
|
|||
wint_t c;
|
||||
int i, oldsp;
|
||||
struct Node *r, *p, *q;
|
||||
if ((c = Greed()) == EOF) return 0;
|
||||
if ((c = Greed()) == EOF)
|
||||
return 0;
|
||||
if (c == L'λ' || c == '\\') {
|
||||
oldsp = sp;
|
||||
c = Need();
|
||||
if (!(isalnum(c) || c == '_')) Error(2, "lambda needs argument");
|
||||
if (!(isalnum(c) || c == '_'))
|
||||
Error(2, "lambda needs argument");
|
||||
p = r = NewNode(0, 0, 0, 0);
|
||||
args[sp++] = c;
|
||||
while ((c = Need()) != '.') {
|
||||
if (!(isalnum(c) || c == '_')) Error(3, "lambda needs argument");
|
||||
if (!(isalnum(c) || c == '_'))
|
||||
Error(3, "lambda needs argument");
|
||||
p = p->l = NewNode(0, 0, 0, 0);
|
||||
args[sp++] = c;
|
||||
}
|
||||
q = Parse1();
|
||||
if (!q) Error(4, "lambda needs body");
|
||||
if (!q)
|
||||
Error(4, "lambda needs body");
|
||||
p->l = q;
|
||||
while ((q = Parse1())) {
|
||||
p->l = NewNode(2, 0, p->l, q);
|
||||
|
@ -249,16 +256,19 @@ static struct Node *Parse1(void) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i < 0) Error(5, "undefined variable: %d %lc", c, c);
|
||||
if (i < 0)
|
||||
Error(5, "undefined variable: %d %lc", c, c);
|
||||
return NewNode(1, i, 0, 0);
|
||||
} else if (c == '(') {
|
||||
p = r = Parse1();
|
||||
if (!p) Error(6, "empty parenthesis");
|
||||
if (!p)
|
||||
Error(6, "empty parenthesis");
|
||||
while ((q = Parse1())) {
|
||||
r = NewNode(2, 0, r, q);
|
||||
}
|
||||
c = Need();
|
||||
if (c != ')') Error(7, "expected closing parenthesis");
|
||||
if (c != ')')
|
||||
Error(7, "expected closing parenthesis");
|
||||
return r;
|
||||
} else if (c == ')') {
|
||||
unget = c;
|
||||
|
@ -271,7 +281,8 @@ static struct Node *Parse1(void) {
|
|||
static struct Node *Parse(void) {
|
||||
struct Node *r, *p, *q;
|
||||
p = r = Parse1();
|
||||
if (!p) Error(6, "empty expression");
|
||||
if (!p)
|
||||
Error(6, "empty expression");
|
||||
while ((q = Parse1())) {
|
||||
r = NewNode(2, 0, r, q);
|
||||
}
|
||||
|
|
|
@ -101,14 +101,16 @@ int Backref(int x) {
|
|||
}
|
||||
|
||||
static inline void Expand(int c) {
|
||||
if (end >= TERMS) Error(5, "OUT OF TERMS");
|
||||
if (end >= TERMS)
|
||||
Error(5, "OUT OF TERMS");
|
||||
mem[end++] = c;
|
||||
}
|
||||
|
||||
void Gc(struct Closure *p) {
|
||||
struct Closure *t;
|
||||
while (p && p != &root) {
|
||||
if (--p->refs) break;
|
||||
if (--p->refs)
|
||||
break;
|
||||
Gc(p->next);
|
||||
t = p->envp;
|
||||
p->envp = 0;
|
||||
|
@ -123,8 +125,10 @@ void Var(void) {
|
|||
struct Closure *t, *e;
|
||||
e = t = envp;
|
||||
x = mem[ip + 1];
|
||||
for (i = 0; i < x && e != &root; ++i) e = e->next;
|
||||
if (e == &root) Error(10 + x, "UNDEFINED VARIABLE %d", x);
|
||||
for (i = 0; i < x && e != &root; ++i)
|
||||
e = e->next;
|
||||
if (e == &root)
|
||||
Error(10 + x, "UNDEFINED VARIABLE %d", x);
|
||||
ip = e->term;
|
||||
envp = REF(e->envp);
|
||||
Gc(t);
|
||||
|
@ -171,14 +175,17 @@ void Put(void) {
|
|||
|
||||
void Bye(void) {
|
||||
int rc = mem[ip + 2]; // (λ 0) [exitcode]
|
||||
if (rc) Error(rc, "CONTINUATIONS EXHAUSTED");
|
||||
if (postdump && !rc) Dump(0, end, stderr);
|
||||
if (rc)
|
||||
Error(rc, "CONTINUATIONS EXHAUSTED");
|
||||
if (postdump && !rc)
|
||||
Dump(0, end, stderr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// pops continuation and pushes it to environment
|
||||
void Abs(void) {
|
||||
if (!contp) Bye();
|
||||
if (!contp)
|
||||
Bye();
|
||||
struct Closure *t = contp;
|
||||
contp = t->next;
|
||||
t->next = envp;
|
||||
|
@ -249,7 +256,8 @@ void Iop(void) {
|
|||
}
|
||||
|
||||
static void Rex(void) {
|
||||
if (slog) PrintMachineState(stderr);
|
||||
if (slog)
|
||||
PrintMachineState(stderr);
|
||||
if (rlog && (alog || mem[ip] != APP)) {
|
||||
PrintExpressions(stderr, alog, vlog);
|
||||
}
|
||||
|
@ -288,7 +296,8 @@ void Krivine(void) {
|
|||
fputs("]\n", stderr);
|
||||
}
|
||||
}
|
||||
for (;;) Rex();
|
||||
for (;;)
|
||||
Rex();
|
||||
}
|
||||
|
||||
void LoadFlags(int argc, char *argv[]) {
|
||||
|
|
|
@ -72,7 +72,8 @@ void PrintMachineState(FILE *f) {
|
|||
char buf[256];
|
||||
static int op;
|
||||
fputc('\n', f);
|
||||
for (i = 0; i < 80; ++i) fputwc(L'─', f);
|
||||
for (i = 0; i < 80; ++i)
|
||||
fputwc(L'─', f);
|
||||
ksnprintf(buf, sizeof(buf),
|
||||
"%d\n ip %ld | op %d %s | arg %d | end %ld\n", op++, ip,
|
||||
mem[ip], GetOpName(mem[ip]), mem[ip + 1], end);
|
||||
|
@ -97,7 +98,8 @@ void PrintExpressions(FILE *f, char alog, char vlog) {
|
|||
ps.envp = envp;
|
||||
for (p = &ps; p; p = p->next) {
|
||||
Print(p->term, 1, GetDepth(p->envp), f);
|
||||
if (p->next) fputc(' ', f);
|
||||
if (p->next)
|
||||
fputc(' ', f);
|
||||
}
|
||||
if (alog) {
|
||||
fputs(" ⟹ ", f);
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
|
||||
void Dumper(int i, int j, FILE *f) {
|
||||
char buf[64];
|
||||
if (i) fputc('\n', f);
|
||||
if (i)
|
||||
fputc('\n', f);
|
||||
for (; i < j; ++i) {
|
||||
switch (mem[i]) {
|
||||
case VAR:
|
||||
|
|
|
@ -26,14 +26,16 @@ char GetBit(FILE* f) {
|
|||
if (!binary) {
|
||||
for (comment = 0;;) {
|
||||
c = fgetwc(f);
|
||||
if (c == -1) break;
|
||||
if (c == -1)
|
||||
break;
|
||||
if (!comment) {
|
||||
fflush(stdout);
|
||||
if (c == ';') {
|
||||
comment = 1;
|
||||
} else if (!iswspace(c) && c != '(' && c != ')' && c != '[' &&
|
||||
c != ']') {
|
||||
if (c != -1) c &= 1;
|
||||
if (c != -1)
|
||||
c &= 1;
|
||||
break;
|
||||
}
|
||||
} else if (c == '\n') {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
char NeedBit(FILE* f) {
|
||||
char b = GetBit(f);
|
||||
if (b == -1) Error(9, "UNEXPECTED EOF");
|
||||
if (b == -1)
|
||||
Error(9, "UNEXPECTED EOF");
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -26,15 +26,18 @@ struct Parse Parse(int ignored, FILE* f) {
|
|||
char bit, need;
|
||||
struct Parse p;
|
||||
for (need = 0, start = end;;) {
|
||||
if (end + 2 > TERMS) Error(5, "OUT OF TERMS");
|
||||
if (end + 2 > TERMS)
|
||||
Error(5, "OUT OF TERMS");
|
||||
if ((bit = GetBit(f)) == -1) {
|
||||
if (!need) break;
|
||||
if (!need)
|
||||
break;
|
||||
fflush(stdout);
|
||||
fputs("---\n", stderr);
|
||||
Print(start, 0, 0, stderr);
|
||||
Error(9, "UNFINISHED EXPRESSION");
|
||||
} else if (bit) {
|
||||
for (t = 0; NeedBit(f);) ++t;
|
||||
for (t = 0; NeedBit(f);)
|
||||
++t;
|
||||
mem[end++] = VAR;
|
||||
mem[end++] = t;
|
||||
break;
|
||||
|
|
|
@ -23,12 +23,15 @@ static struct Parse ParseImpl(int tail, int need, FILE *f) {
|
|||
struct Parse p, q;
|
||||
int b, i, j, t, start;
|
||||
for (start = end;;) {
|
||||
if (end + 2 > TERMS) Error(5, "OUT OF TERMS");
|
||||
if (end + 2 > TERMS)
|
||||
Error(5, "OUT OF TERMS");
|
||||
if ((b = GetBit(f)) == -1) {
|
||||
if (need) Error(9, "UNFINISHED EXPRESSION");
|
||||
if (need)
|
||||
Error(9, "UNFINISHED EXPRESSION");
|
||||
break;
|
||||
} else if (b) {
|
||||
for (t = 0; NeedBit(f);) ++t;
|
||||
for (t = 0; NeedBit(f);)
|
||||
++t;
|
||||
mem[end++] = VAR;
|
||||
mem[end++] = t;
|
||||
break;
|
||||
|
|
|
@ -873,11 +873,13 @@ void PrintDebruijn(int x, int head, int depth, FILE* f) {
|
|||
} else {
|
||||
fputwc(L'λ', f);
|
||||
}
|
||||
if (!(0 <= x && x < TERMS)) goto Overflow;
|
||||
if (!(0 <= x && x < TERMS))
|
||||
goto Overflow;
|
||||
} while (mem[x] == ABS);
|
||||
fputc(' ', f);
|
||||
}
|
||||
if (!(0 <= (x + 1) && (x + 1) < TERMS)) goto Overflow;
|
||||
if (!(0 <= (x + 1) && (x + 1) < TERMS))
|
||||
goto Overflow;
|
||||
if (mem[x] == APP) {
|
||||
fputc('[', f);
|
||||
PrintDebruijn(x + 2, 1, depth, f);
|
||||
|
@ -1162,11 +1164,13 @@ void PrintLambda(int x, int head, int depth, int apps, FILE* f) {
|
|||
do {
|
||||
++x;
|
||||
fputwc(ALPHABET[depth++], f);
|
||||
if (!(0 <= x && x < TERMS)) goto Overflow;
|
||||
if (!(0 <= x && x < TERMS))
|
||||
goto Overflow;
|
||||
} while (mem[x] == ABS);
|
||||
fputc('.', f);
|
||||
}
|
||||
if (!(0 <= (x + 1) && (x + 1) < TERMS)) goto Overflow;
|
||||
if (!(0 <= (x + 1) && (x + 1) < TERMS))
|
||||
goto Overflow;
|
||||
if (mem[x] == VAR) {
|
||||
if (0 <= x + 1 && x + 1 < TERMS) {
|
||||
PrintVar(depth - 1 - mem[x + 1], f);
|
||||
|
@ -1182,7 +1186,8 @@ void PrintLambda(int x, int head, int depth, int apps, FILE* f) {
|
|||
}
|
||||
PrintLambda(x + 2, 1, depth, apps + 1, f);
|
||||
if (!(x + 2 + mem[x + 1] < TERMS && mem[x + 2 + mem[x + 1]] == APP)) {
|
||||
if (safer || !noname) fputc(' ', f);
|
||||
if (safer || !noname)
|
||||
fputc(' ', f);
|
||||
}
|
||||
PrintLambda(x + 2 + mem[x + 1], 0, depth, apps + 1, f);
|
||||
} else if (mem[x] == IOP) {
|
||||
|
@ -1230,10 +1235,12 @@ void PrintBinary(int x, int head, int depth, FILE* f) {
|
|||
++depth;
|
||||
fputc('0', f);
|
||||
fputc('0', f);
|
||||
if (!(0 <= x && x < TERMS)) goto Overflow;
|
||||
if (!(0 <= x && x < TERMS))
|
||||
goto Overflow;
|
||||
} while (mem[x] == ABS);
|
||||
}
|
||||
if (!(0 <= (x + 1) && (x + 1) < TERMS)) goto Overflow;
|
||||
if (!(0 <= (x + 1) && (x + 1) < TERMS))
|
||||
goto Overflow;
|
||||
if (mem[x] == VAR) {
|
||||
if (0 <= x + 1 && x + 1 < TERMS) {
|
||||
PrintVar(mem[x + 1], f);
|
||||
|
|
|
@ -76,6 +76,7 @@ void lookup(const char *name) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
ShowCrashReports();
|
||||
for (i = 1; i < argc; ++i) lookup(argv[i]);
|
||||
for (i = 1; i < argc; ++i)
|
||||
lookup(argv[i]);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,8 @@ void TcpServer(void) {
|
|||
ip, ntohs(addr2.sin_port));
|
||||
for (;;) {
|
||||
CHECK_NE(-1, (rc = read(client, buf, sizeof(buf))));
|
||||
if (!rc) break;
|
||||
if (!rc)
|
||||
break;
|
||||
CHECK_NE(-1, write(client, buf, rc));
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +118,8 @@ void TcpClient(void) {
|
|||
int main(int argc, char *argv[]) {
|
||||
int port = 0;
|
||||
int64_t ip = 0;
|
||||
if (argc < 3) PrintUsage(argv);
|
||||
if (argc < 3)
|
||||
PrintUsage(argv);
|
||||
if (argc >= 4) {
|
||||
if ((ip = ParseIp(argv[3], -1)) == -1) {
|
||||
PrintUsage(argv);
|
||||
|
|
|
@ -174,43 +174,53 @@ const char *DescribeIpAdapterFlags(int x) {
|
|||
static char buf[256];
|
||||
p = buf;
|
||||
if (x & kNtIpAdapterDdnsEnabled) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "DDNS");
|
||||
}
|
||||
if (x & kNtIpAdapterDhcpv4Enabled) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "DHCPv4");
|
||||
}
|
||||
if (x & kNtIpAdapterReceiveOnly) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "RECV_ONLY");
|
||||
}
|
||||
if (x & kNtIpAdapterNoMulticast) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "NO_MULTICAST");
|
||||
}
|
||||
if (x & kNtIpAdapterIpv4Enabled) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "IPv4");
|
||||
}
|
||||
if (x & kNtIpAdapterIpv6Enabled) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "IPv6");
|
||||
}
|
||||
if (x & kNtIpAdapterIpv6Managed) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "IPv6_MANAGED");
|
||||
}
|
||||
if (x & kNtIpAdapterIpv6OtherStatefulConfig) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "IPv6_OTHER_STATEFUL_CONFIG");
|
||||
}
|
||||
if (x & kNtIpAdapterNetbiosOverTcpipEnabled) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "NETBIOS_OVER_TCP");
|
||||
}
|
||||
if (x & kNtIpAdapterRegisterAdapterSuffix) {
|
||||
if (p > buf) *p++ = ' ';
|
||||
if (p > buf)
|
||||
*p++ = ' ';
|
||||
p = stpcpy(p, "REGISTER_ADAPTER_SUFFIX");
|
||||
}
|
||||
return buf;
|
||||
|
@ -252,9 +262,12 @@ char *ConvertIpv6ToStr(const struct in6_addr *addr) {
|
|||
b = (addr->s6_addr[i + 0] & 0x0F) >> 0;
|
||||
c = (addr->s6_addr[i + 1] & 0xF0) >> 4;
|
||||
d = (addr->s6_addr[i + 1] & 0x0F) >> 0;
|
||||
if (a) *p++ = "0123456789abcdef"[a];
|
||||
if (a || b) *p++ = "0123456789abcdef"[b];
|
||||
if (a || b || c) *p++ = "0123456789abcdef"[c];
|
||||
if (a)
|
||||
*p++ = "0123456789abcdef"[a];
|
||||
if (a || b)
|
||||
*p++ = "0123456789abcdef"[b];
|
||||
if (a || b || c)
|
||||
*p++ = "0123456789abcdef"[c];
|
||||
*p++ = "0123456789abcdef"[d];
|
||||
}
|
||||
*p = '\0';
|
||||
|
@ -406,7 +419,8 @@ void ShowWinNicCidrs(void) {
|
|||
(char16_t *)&lpMsgBuf, 0, NULL)) {
|
||||
printf("\tError: %s", lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
if (pAddresses) free(pAddresses);
|
||||
if (pAddresses)
|
||||
free(pAddresses);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,7 +475,8 @@ int LuaSlurp(lua_State *L) {
|
|||
}
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
if (!got) break;
|
||||
if (!got)
|
||||
break;
|
||||
luaL_addlstring(&b, tb, got);
|
||||
} else if (errno == EINTR) {
|
||||
errno = olderr;
|
||||
|
@ -617,7 +618,8 @@ dontinline int LuaBase32Impl(lua_State *L,
|
|||
const char *a = luaL_optlstring(L, 2, "", &al);
|
||||
if (!IS2POW(al) || al > 128 || al == 1)
|
||||
return luaL_error(L, "alphabet length is not a power of 2 in range 2..128");
|
||||
if (!(p = B32(s, sl, a, al, &sl))) return luaL_error(L, "out of memory");
|
||||
if (!(p = B32(s, sl, a, al, &sl)))
|
||||
return luaL_error(L, "out of memory");
|
||||
lua_pushlstring(L, p, sl);
|
||||
free(p);
|
||||
return 1;
|
||||
|
@ -693,10 +695,12 @@ int LuaGetCryptoHash(lua_State *L) {
|
|||
const void *p = luaL_checklstring(L, 2, &pl);
|
||||
const void *k = luaL_optlstring(L, 3, "", &kl);
|
||||
const mbedtls_md_info_t *digest = mbedtls_md_info_from_string(h);
|
||||
if (!digest) return luaL_argerror(L, 1, "unknown hash type");
|
||||
if (!digest)
|
||||
return luaL_argerror(L, 1, "unknown hash type");
|
||||
if (kl == 0) {
|
||||
// no key provided, run generic hash function
|
||||
if ((digest->f_md)(p, pl, d)) return luaL_error(L, "bad input data");
|
||||
if ((digest->f_md)(p, pl, d))
|
||||
return luaL_error(L, "bad input data");
|
||||
} else if (mbedtls_md_hmac(digest, k, kl, p, pl, d)) {
|
||||
return luaL_error(L, "bad input data");
|
||||
}
|
||||
|
|
|
@ -74,25 +74,30 @@ static void dump_dns_rr(ns_msg *msg, ns_rr *rr, ns_sect sect, FILE *trace) {
|
|||
class = ns_rr_class(*rr);
|
||||
type = ns_rr_type(*rr);
|
||||
fprintf(trace, "%s,%d,%d", ns_rr_name(*rr), class, type);
|
||||
if (sect == ns_s_qd) return;
|
||||
if (sect == ns_s_qd)
|
||||
return;
|
||||
fprintf(trace, ",%lu", (u_long)ns_rr_ttl(*rr));
|
||||
rd = ns_rr_rdata(*rr);
|
||||
switch (type) {
|
||||
case ns_t_soa:
|
||||
n = ns_name_uncompress(ns_msg_base(*msg), ns_msg_end(*msg), rd, buf,
|
||||
sizeof buf);
|
||||
if (n < 0) goto error;
|
||||
if (n < 0)
|
||||
goto error;
|
||||
putc(',', trace);
|
||||
fputs(buf, trace);
|
||||
rd += n;
|
||||
n = ns_name_uncompress(ns_msg_base(*msg), ns_msg_end(*msg), rd, buf,
|
||||
sizeof buf);
|
||||
if (n < 0) goto error;
|
||||
if (n < 0)
|
||||
goto error;
|
||||
putc(',', trace);
|
||||
fputs(buf, trace);
|
||||
rd += n;
|
||||
if (ns_msg_end(*msg) - rd < 5 * NS_INT32SZ) goto error;
|
||||
for (n = 0; n < 5; n++) MY_GET32(soa[n], rd);
|
||||
if (ns_msg_end(*msg) - rd < 5 * NS_INT32SZ)
|
||||
goto error;
|
||||
for (n = 0; n < 5; n++)
|
||||
MY_GET32(soa[n], rd);
|
||||
sprintf(buf, "%u,%u,%u,%u,%u", soa[0], soa[1], soa[2], soa[3], soa[4]);
|
||||
break;
|
||||
case ns_t_a:
|
||||
|
@ -110,7 +115,8 @@ static void dump_dns_rr(ns_msg *msg, ns_rr *rr, ns_sect sect, FILE *trace) {
|
|||
case ns_t_cname:
|
||||
n = ns_name_uncompress(ns_msg_base(*msg), ns_msg_end(*msg), rd, buf,
|
||||
sizeof buf);
|
||||
if (n < 0) goto error;
|
||||
if (n < 0)
|
||||
goto error;
|
||||
break;
|
||||
case ns_t_txt:
|
||||
snprintf(buf, (size_t)rd[0] + 1, "%s", rd + 1);
|
||||
|
|
|
@ -132,7 +132,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
}
|
||||
|
||||
case 'n': // null
|
||||
if (context & (KEY | COLON | COMMA)) goto OnColonCommaKey;
|
||||
if (context & (KEY | COLON | COMMA))
|
||||
goto OnColonCommaKey;
|
||||
if (p + 3 <= e && READ32LE(p - 1) == READ32LE("null")) {
|
||||
lua_pushnil(L);
|
||||
return (struct DecodeJson){1, p + 3};
|
||||
|
@ -141,7 +142,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
}
|
||||
|
||||
case 'f': // false
|
||||
if (context & (KEY | COLON | COMMA)) goto OnColonCommaKey;
|
||||
if (context & (KEY | COLON | COMMA))
|
||||
goto OnColonCommaKey;
|
||||
if (p + 4 <= e && READ32LE(p) == READ32LE("alse")) {
|
||||
lua_pushboolean(L, false);
|
||||
return (struct DecodeJson){1, p + 4};
|
||||
|
@ -150,7 +152,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
}
|
||||
|
||||
case 't': // true
|
||||
if (context & (KEY | COLON | COMMA)) goto OnColonCommaKey;
|
||||
if (context & (KEY | COLON | COMMA))
|
||||
goto OnColonCommaKey;
|
||||
if (p + 3 <= e && READ32LE(p - 1) == READ32LE("true")) {
|
||||
lua_pushboolean(L, true);
|
||||
return (struct DecodeJson){1, p + 3};
|
||||
|
@ -162,9 +165,11 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
IllegalCharacter:
|
||||
return (struct DecodeJson){-1, "illegal character"};
|
||||
OnColonCommaKey:
|
||||
if (context & KEY) goto BadObjectKey;
|
||||
if (context & KEY)
|
||||
goto BadObjectKey;
|
||||
OnColonComma:
|
||||
if (context & COLON) goto MissingColon;
|
||||
if (context & COLON)
|
||||
goto MissingColon;
|
||||
return (struct DecodeJson){-1, "missing ','"};
|
||||
MissingColon:
|
||||
return (struct DecodeJson){-1, "missing ':'"};
|
||||
|
@ -172,7 +177,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
return (struct DecodeJson){-1, "object key must be string"};
|
||||
|
||||
case '-': // negative
|
||||
if (context & (COLON | COMMA | KEY)) goto OnColonCommaKey;
|
||||
if (context & (COLON | COMMA | KEY))
|
||||
goto OnColonCommaKey;
|
||||
if (p < e && isdigit(*p)) {
|
||||
d = -1;
|
||||
break;
|
||||
|
@ -181,7 +187,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
}
|
||||
|
||||
case '0': // zero or number
|
||||
if (context & (COLON | COMMA | KEY)) goto OnColonCommaKey;
|
||||
if (context & (COLON | COMMA | KEY))
|
||||
goto OnColonCommaKey;
|
||||
if (p < e) {
|
||||
if (*p == '.') {
|
||||
if (p + 1 == e || !isdigit(p[1])) {
|
||||
|
@ -198,7 +205,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
return (struct DecodeJson){1, p};
|
||||
|
||||
case '1' ... '9': // integer
|
||||
if (context & (COLON | COMMA | KEY)) goto OnColonCommaKey;
|
||||
if (context & (COLON | COMMA | KEY))
|
||||
goto OnColonCommaKey;
|
||||
for (x = (c - '0') * d; p < e; ++p) {
|
||||
c = *p & 255;
|
||||
if (isdigit(c)) {
|
||||
|
@ -228,7 +236,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
return (struct DecodeJson){1, a + c};
|
||||
|
||||
case '[': // Array
|
||||
if (context & (COLON | COMMA | KEY)) goto OnColonCommaKey;
|
||||
if (context & (COLON | COMMA | KEY))
|
||||
goto OnColonCommaKey;
|
||||
lua_newtable(L); // +1
|
||||
for (context = ARRAY, i = 0;;) {
|
||||
r = Parse(L, p, e, context, depth - 1); // +2
|
||||
|
@ -265,7 +274,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
}
|
||||
|
||||
case '{': // Object
|
||||
if (context & (COLON | COMMA | KEY)) goto OnColonCommaKey;
|
||||
if (context & (COLON | COMMA | KEY))
|
||||
goto OnColonCommaKey;
|
||||
lua_newtable(L); // +1
|
||||
context = KEY | OBJECT;
|
||||
for (;;) {
|
||||
|
@ -293,7 +303,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
}
|
||||
|
||||
case '"': // string
|
||||
if (context & (COLON | COMMA)) goto OnColonComma;
|
||||
if (context & (COLON | COMMA))
|
||||
goto OnColonComma;
|
||||
luaL_buffinit(L, &b);
|
||||
for (;;) {
|
||||
if (UNLIKELY(p >= e)) {
|
||||
|
@ -586,7 +597,8 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
|
|||
* @return r.p is string describing error if `rc < 0`
|
||||
*/
|
||||
struct DecodeJson DecodeJson(struct lua_State *L, const char *p, size_t n) {
|
||||
if (n == -1) n = p ? strlen(p) : 0;
|
||||
if (n == -1)
|
||||
n = p ? strlen(p) : 0;
|
||||
if (lua_checkstack(L, DEPTH * 3 + LUA_MINSTACK)) {
|
||||
return Parse(L, p, p + n, 0, DEPTH);
|
||||
} else {
|
||||
|
|
|
@ -203,7 +203,8 @@ static int LuaMaxmindResultGet(lua_State *L) {
|
|||
ep = &(*ur)->mmlr.entry;
|
||||
} else {
|
||||
path = xcalloc(n + 1, sizeof(const char *));
|
||||
for (i = 0; i < n; ++i) path[i] = lua_tostring(L, 2 + i);
|
||||
for (i = 0; i < n; ++i)
|
||||
path[i] = lua_tostring(L, 2 + i);
|
||||
err = MMDB_aget_value(&(*ur)->mmlr.entry, &edata, path);
|
||||
free(path);
|
||||
if (err) {
|
||||
|
@ -223,7 +224,8 @@ static int LuaMaxmindResultGet(lua_State *L) {
|
|||
ep = &entry;
|
||||
}
|
||||
err = MMDB_get_entry_data_list(ep, &dl);
|
||||
if (err) LuaThrowMaxmindIpError(L, "getlist", (*ur)->ip, err);
|
||||
if (err)
|
||||
LuaThrowMaxmindIpError(L, "getlist", (*ur)->ip, err);
|
||||
LuaMaxmindDump(L, dl);
|
||||
MMDB_free_entry_data_list(dl);
|
||||
return 1;
|
||||
|
|
|
@ -32,9 +32,11 @@ static int LuaPathBasename(lua_State *L) {
|
|||
size_t i, n;
|
||||
const char *p;
|
||||
if ((p = luaL_optlstring(L, 1, 0, &n)) && n) {
|
||||
while (n > 1 && p[n - 1] == '/') --n;
|
||||
while (n > 1 && p[n - 1] == '/')
|
||||
--n;
|
||||
i = n - 1;
|
||||
while (i && p[i - 1] != '/') --i;
|
||||
while (i && p[i - 1] != '/')
|
||||
--i;
|
||||
lua_pushlstring(L, p + i, n - i);
|
||||
} else {
|
||||
lua_pushlstring(L, ".", 1);
|
||||
|
@ -49,13 +51,16 @@ static int LuaPathDirname(lua_State *L) {
|
|||
const char *p;
|
||||
if ((p = luaL_optlstring(L, 1, 0, &n)) && n--) {
|
||||
for (; p[n] == '/'; n--) {
|
||||
if (!n) goto ReturnSlash;
|
||||
if (!n)
|
||||
goto ReturnSlash;
|
||||
}
|
||||
for (; p[n] != '/'; n--) {
|
||||
if (!n) goto ReturnDot;
|
||||
if (!n)
|
||||
goto ReturnDot;
|
||||
}
|
||||
for (; p[n] == '/'; n--) {
|
||||
if (!n) goto ReturnSlash;
|
||||
if (!n)
|
||||
goto ReturnSlash;
|
||||
}
|
||||
lua_pushlstring(L, p, n + 1);
|
||||
return 1;
|
||||
|
@ -82,7 +87,8 @@ static int LuaPathJoin(lua_State *L) {
|
|||
gotstr = false;
|
||||
needslash = false;
|
||||
for (i = 1; i <= n; ++i) {
|
||||
if (lua_isnoneornil(L, i)) continue;
|
||||
if (lua_isnoneornil(L, i))
|
||||
continue;
|
||||
gotstr = true;
|
||||
c = luaL_checklstring(L, i, &z);
|
||||
if (z) {
|
||||
|
|
|
@ -644,11 +644,14 @@ static bool ShouldAvoidGzip(void) {
|
|||
static char *MergePaths(const char *p, size_t n, const char *q, size_t m,
|
||||
size_t *z) {
|
||||
char *r;
|
||||
if (n && p[n - 1] == '/') --n;
|
||||
if (m && q[0] == '/') ++q, --m;
|
||||
if (n && p[n - 1] == '/')
|
||||
--n;
|
||||
if (m && q[0] == '/')
|
||||
++q, --m;
|
||||
r = xmalloc(n + 1 + m + 1);
|
||||
mempcpy(mempcpy(mempcpy(mempcpy(r, p, n), "/", 1), q, m), "", 1);
|
||||
if (z) *z = n + 1 + m;
|
||||
if (z)
|
||||
*z = n + 1 + m;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -698,7 +701,8 @@ static void AppendCert(mbedtls_x509_crt *cert, mbedtls_pk_context *key) {
|
|||
static void InternCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *prev) {
|
||||
int r;
|
||||
size_t i;
|
||||
if (cert->next) InternCertificate(cert->next, cert);
|
||||
if (cert->next)
|
||||
InternCertificate(cert->next, cert);
|
||||
if (prev) {
|
||||
if (mbedtls_x509_crt_check_parent(prev, cert, 1)) {
|
||||
DEBUGF("(ssl) unbundling %`'s from %`'s",
|
||||
|
@ -728,18 +732,22 @@ static void InternCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *prev) {
|
|||
LogCertificate("loaded certificate", cert);
|
||||
if (!cert->next && !IsSelfSigned(cert) && cert->max_pathlen) {
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (mbedtls_pk_can_do(&cert->pk, certs.p[i].cert->sig_pk) &&
|
||||
!mbedtls_x509_crt_check_parent(cert, certs.p[i].cert, 1) &&
|
||||
!IsSelfSigned(certs.p[i].cert)) {
|
||||
if (ChainCertificate(cert, certs.p[i].cert)) break;
|
||||
if (ChainCertificate(cert, certs.p[i].cert))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IsSelfSigned(cert)) {
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (certs.p[i].cert->next) continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (certs.p[i].cert->next)
|
||||
continue;
|
||||
if (certs.p[i].cert->max_pathlen &&
|
||||
mbedtls_pk_can_do(&certs.p[i].cert->pk, cert->sig_pk) &&
|
||||
!mbedtls_x509_crt_check_parent(certs.p[i].cert, cert, 1)) {
|
||||
|
@ -782,7 +790,8 @@ static void ProgramPrivateKey(const char *p, size_t n) {
|
|||
rc = mbedtls_pk_parse_key(key, waqapi, n + 1, 0, 0);
|
||||
mbedtls_platform_zeroize(waqapi, n);
|
||||
free(waqapi);
|
||||
if (rc != 0) FATALF("(ssl) error: load key (grep -0x%04x)", -rc);
|
||||
if (rc != 0)
|
||||
FATALF("(ssl) error: load key (grep -0x%04x)", -rc);
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (certs.p[i].cert && !certs.p[i].key &&
|
||||
!mbedtls_pk_check_pair(&certs.p[i].cert->pk, key)) {
|
||||
|
@ -811,7 +820,8 @@ static void ProgramPort(long port) {
|
|||
if (!(0 <= port && port <= 65535)) {
|
||||
FATALF("(cfg) error: bad port: %d", port);
|
||||
}
|
||||
if (port == 443) listeningonport443 = true;
|
||||
if (port == 443)
|
||||
listeningonport443 = true;
|
||||
ports.p = realloc(ports.p, ++ports.n * sizeof(*ports.p));
|
||||
ports.p[ports.n - 1] = port;
|
||||
}
|
||||
|
@ -942,13 +952,15 @@ static void DescribeAddress(char buf[40], uint32_t addr, uint16_t port) {
|
|||
|
||||
static inline int GetServerAddr(uint32_t *ip, uint16_t *port) {
|
||||
*ip = ntohl(serveraddr->sin_addr.s_addr);
|
||||
if (port) *port = ntohs(serveraddr->sin_port);
|
||||
if (port)
|
||||
*port = ntohs(serveraddr->sin_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int GetClientAddr(uint32_t *ip, uint16_t *port) {
|
||||
*ip = ntohl(clientaddr.sin_addr.s_addr);
|
||||
if (port) *port = ntohs(clientaddr.sin_port);
|
||||
if (port)
|
||||
*port = ntohs(clientaddr.sin_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1050,8 @@ static void ProgramTimeout(long ms) {
|
|||
|
||||
static void ProgramCache(long x, const char *s) {
|
||||
cacheseconds = x;
|
||||
if (s) cachedirective = strdup(s);
|
||||
if (s)
|
||||
cachedirective = strdup(s);
|
||||
}
|
||||
|
||||
static void SetDefaults(void) {
|
||||
|
@ -1183,9 +1196,11 @@ static void ChangeUser(void) {
|
|||
}
|
||||
|
||||
static void Daemonize(void) {
|
||||
if (fork() > 0) exit(0);
|
||||
if (fork() > 0)
|
||||
exit(0);
|
||||
setsid();
|
||||
if (fork() > 0) _exit(0);
|
||||
if (fork() > 0)
|
||||
_exit(0);
|
||||
umask(0);
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1224,8 @@ static void LuaEvalCode(const char *code) {
|
|||
// handle `-F PATH` arg
|
||||
static void LuaEvalFile(const char *path) {
|
||||
char *f = gc(xslurp(path, 0));
|
||||
if (!f) FATALF("(cfg) error: failed to read file %`'s", path);
|
||||
if (!f)
|
||||
FATALF("(cfg) error: failed to read file %`'s", path);
|
||||
LuaEvalCode(f);
|
||||
}
|
||||
|
||||
|
@ -1465,8 +1481,10 @@ static ssize_t WritevAll(int fd, struct iovec *iov, int iovlen) {
|
|||
total = 0;
|
||||
do {
|
||||
if (i) {
|
||||
while (i < iovlen && !iov[i].iov_len) ++i;
|
||||
if (i == iovlen) break;
|
||||
while (i < iovlen && !iov[i].iov_len)
|
||||
++i;
|
||||
if (i == iovlen)
|
||||
break;
|
||||
}
|
||||
if ((rc = writev(fd, iov + i, iovlen - i)) != -1) {
|
||||
wrote = rc;
|
||||
|
@ -1501,7 +1519,8 @@ static int TlsFlush(struct TlsBio *bio, const unsigned char *buf, size_t len) {
|
|||
v[1].iov_base = (void *)buf;
|
||||
v[1].iov_len = len;
|
||||
if (WritevAll(bio->fd, v, 2) != -1) {
|
||||
if (bio->c > 0) bio->c = 0;
|
||||
if (bio->c > 0)
|
||||
bio->c = 0;
|
||||
} else if (errno == EINTR) {
|
||||
errno = 0;
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
|
@ -1526,7 +1545,8 @@ static int TlsSend(void *ctx, const unsigned char *buf, size_t len) {
|
|||
bio->c += len;
|
||||
return len;
|
||||
}
|
||||
if ((rc = TlsFlush(bio, buf, len)) < 0) return rc;
|
||||
if ((rc = TlsFlush(bio, buf, len)) < 0)
|
||||
return rc;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -1534,11 +1554,13 @@ static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
int r;
|
||||
struct iovec v[2];
|
||||
struct TlsBio *bio = ctx;
|
||||
if ((r = TlsFlush(bio, 0, 0)) < 0) return r;
|
||||
if ((r = TlsFlush(bio, 0, 0)) < 0)
|
||||
return r;
|
||||
if (bio->a < bio->b) {
|
||||
r = MIN(n, bio->b - bio->a);
|
||||
memcpy(p, bio->t + bio->a, r);
|
||||
if ((bio->a += r) == bio->b) bio->a = bio->b = 0;
|
||||
if ((bio->a += r) == bio->b)
|
||||
bio->a = bio->b = 0;
|
||||
return r;
|
||||
}
|
||||
v[0].iov_base = p;
|
||||
|
@ -1559,7 +1581,8 @@ static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
}
|
||||
if (r > n) bio->b = r - n;
|
||||
if (r > n)
|
||||
bio->b = r - n;
|
||||
return MIN(n, r);
|
||||
}
|
||||
|
||||
|
@ -1655,11 +1678,15 @@ static void NotifyClose(void) {
|
|||
|
||||
static void WipeSigningKeys(void) {
|
||||
size_t i;
|
||||
if (uniprocess) return;
|
||||
if (uniprocess)
|
||||
return;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].key) continue;
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (!certs.p[i].cert->ca_istrue) continue;
|
||||
if (!certs.p[i].key)
|
||||
continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (!certs.p[i].cert->ca_istrue)
|
||||
continue;
|
||||
mbedtls_pk_free(certs.p[i].key);
|
||||
Free(&certs.p[i].key);
|
||||
}
|
||||
|
@ -1695,7 +1722,8 @@ static void CertsDestroy(void) {
|
|||
}
|
||||
|
||||
static void WipeServingKeys(void) {
|
||||
if (uniprocess) return;
|
||||
if (uniprocess)
|
||||
return;
|
||||
mbedtls_ssl_ticket_free(&ssltick);
|
||||
mbedtls_ssl_key_cert_free(conf.key_cert), conf.key_cert = 0;
|
||||
CertsDestroy();
|
||||
|
@ -1897,13 +1925,15 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
//
|
||||
for (int i = 0; i < ips.n; ++i) {
|
||||
uint32_t ip = ips.p[i];
|
||||
if (IsLoopbackIp(ip)) continue;
|
||||
if (IsLoopbackIp(ip))
|
||||
continue;
|
||||
char rname[NI_MAXHOST];
|
||||
struct sockaddr_in addr4 = {AF_INET, 0, {htonl(ip)}};
|
||||
if (getnameinfo((struct sockaddr *)&addr4, sizeof(addr4), rname,
|
||||
sizeof(rname), 0, 0, NI_NAMEREQD) == 0) {
|
||||
char *s = gc(strdup(rname));
|
||||
if (!name) name = s;
|
||||
if (!name)
|
||||
name = s;
|
||||
bool isduplicate = false;
|
||||
for (int j = 0; j < nsan; ++j) {
|
||||
if (san[j].tag == MBEDTLS_X509_SAN_DNS_NAME &&
|
||||
|
@ -1925,7 +1955,8 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
// add san entry to cert for each ip address owned by system
|
||||
for (int i = 0; i < ips.n; ++i) {
|
||||
uint32_t ip = ips.p[i];
|
||||
if (IsLoopbackIp(ip)) continue;
|
||||
if (IsLoopbackIp(ip))
|
||||
continue;
|
||||
san = realloc(san, ++nsan * sizeof(*san));
|
||||
san[nsan - 1].tag = MBEDTLS_X509_SAN_IP_ADDRESS;
|
||||
san[nsan - 1].ip4 = ip;
|
||||
|
@ -1974,9 +2005,12 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
static struct Cert GetKeySigningKey(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].key) continue;
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (!certs.p[i].cert->ca_istrue) continue;
|
||||
if (!certs.p[i].key)
|
||||
continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (!certs.p[i].cert->ca_istrue)
|
||||
continue;
|
||||
if (mbedtls_x509_crt_check_key_usage(certs.p[i].cert,
|
||||
MBEDTLS_X509_KU_KEY_CERT_SIGN)) {
|
||||
continue;
|
||||
|
@ -2059,7 +2093,8 @@ static void LoadCertificates(void) {
|
|||
}
|
||||
#ifdef MBEDTLS_ECP_C
|
||||
ecp = GenerateEcpCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &ecp, "server");
|
||||
if (!havecert)
|
||||
UseCertificate(&conf, &ecp, "server");
|
||||
if (!haveclientcert && ksk.key) {
|
||||
UseCertificate(&confcli, &ecp, "client");
|
||||
}
|
||||
|
@ -2068,7 +2103,8 @@ static void LoadCertificates(void) {
|
|||
#ifdef MBEDTLS_RSA_C
|
||||
if (!norsagen) {
|
||||
rsa = GenerateRsaCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &rsa, "server");
|
||||
if (!havecert)
|
||||
UseCertificate(&conf, &rsa, "server");
|
||||
if (!haveclientcert && ksk.key) {
|
||||
UseCertificate(&confcli, &rsa, "client");
|
||||
}
|
||||
|
@ -2237,11 +2273,13 @@ static bool OpenZip(bool force) {
|
|||
|
||||
static struct Asset *GetAssetZip(const char *path, size_t pathlen) {
|
||||
uint32_t i, step, hash;
|
||||
if (pathlen > 1 && path[0] == '/') ++path, --pathlen;
|
||||
if (pathlen > 1 && path[0] == '/')
|
||||
++path, --pathlen;
|
||||
hash = Hash(path, pathlen);
|
||||
for (step = 0;; ++step) {
|
||||
i = (hash + ((step * (step + 1)) >> 1)) & (assets.n - 1);
|
||||
if (!assets.p[i].hash) return NULL;
|
||||
if (!assets.p[i].hash)
|
||||
return NULL;
|
||||
if (hash == assets.p[i].hash &&
|
||||
pathlen == ZIP_CFILE_NAMESIZE(zmap + assets.p[i].cf) &&
|
||||
memcmp(path, ZIP_CFILE_NAME(zmap + assets.p[i].cf), pathlen) == 0) {
|
||||
|
@ -2288,7 +2326,8 @@ static struct Asset *GetAsset(const char *path, size_t pathlen) {
|
|||
}
|
||||
|
||||
static char *AppendHeader(char *p, const char *k, const char *v) {
|
||||
if (!v) return p;
|
||||
if (!v)
|
||||
return p;
|
||||
return AppendCrlf(stpcpy(stpcpy(stpcpy(p, k), ": "), v));
|
||||
}
|
||||
|
||||
|
@ -2316,7 +2355,8 @@ static char *AppendExpires(char *p, int64_t t) {
|
|||
}
|
||||
|
||||
static char *AppendCache(char *p, int64_t seconds, char *directive) {
|
||||
if (seconds < 0) return p;
|
||||
if (seconds < 0)
|
||||
return p;
|
||||
p = stpcpy(p, "Cache-Control: max-age=");
|
||||
p = FormatUint64(p, seconds);
|
||||
if (!seconds) {
|
||||
|
@ -2392,7 +2432,8 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
|||
}
|
||||
if (!a->file) {
|
||||
size = GetZipLfileUncompressedSize(zmap + a->lf);
|
||||
if (size == SIZE_MAX || !(data = malloc(size + 1))) return NULL;
|
||||
if (size == SIZE_MAX || !(data = malloc(size + 1)))
|
||||
return NULL;
|
||||
if (IsCompressed(a)) {
|
||||
if (!Inflate(data, size, ZIP_LFILE_CONTENT(zmap + a->lf),
|
||||
GetZipCfileCompressedSize(zmap + a->cf))) {
|
||||
|
@ -2407,7 +2448,8 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
|||
return NULL;
|
||||
}
|
||||
data[size] = '\0';
|
||||
if (out_size) *out_size = size;
|
||||
if (out_size)
|
||||
*out_size = size;
|
||||
return data;
|
||||
} else {
|
||||
LockInc(&shared->c.slurps);
|
||||
|
@ -2622,7 +2664,8 @@ static ssize_t YieldGenerator(struct iovec v[3]) {
|
|||
int nresults, status;
|
||||
if (cpm.isyielding > 1) {
|
||||
do {
|
||||
if (!YL || lua_status(YL) != LUA_YIELD) return 0; // done yielding
|
||||
if (!YL || lua_status(YL) != LUA_YIELD)
|
||||
return 0; // done yielding
|
||||
cpm.contentlength = 0;
|
||||
status = lua_resume(YL, NULL, 0, &nresults);
|
||||
if (status != LUA_OK && status != LUA_YIELD) {
|
||||
|
@ -2631,7 +2674,8 @@ static ssize_t YieldGenerator(struct iovec v[3]) {
|
|||
return -1;
|
||||
}
|
||||
lua_pop(YL, nresults);
|
||||
if (!cpm.contentlength) UseOutput();
|
||||
if (!cpm.contentlength)
|
||||
UseOutput();
|
||||
// continue yielding if nothing to return to keep generator running
|
||||
} while (!cpm.contentlength);
|
||||
}
|
||||
|
@ -2667,7 +2711,8 @@ static int LuaCallWithYield(lua_State *L) {
|
|||
CHECK_GT(lua_gettop(L), 0); // make sure that coroutine is anchored
|
||||
YL = co;
|
||||
cpm.generator = YieldGenerator;
|
||||
if (!cpm.isyielding) cpm.isyielding = 1;
|
||||
if (!cpm.isyielding)
|
||||
cpm.isyielding = 1;
|
||||
status = LUA_OK;
|
||||
}
|
||||
return status;
|
||||
|
@ -2770,7 +2815,8 @@ static ssize_t InflateGenerator(struct iovec v[3]) {
|
|||
dg.s.next_out = dg.b;
|
||||
dg.s.avail_out = dg.z;
|
||||
rc = inflate(&dg.s, Z_NO_FLUSH);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END) DIEF("(zip) inflate()→%d", rc);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END)
|
||||
DIEF("(zip) inflate()→%d", rc);
|
||||
no = dg.z - dg.s.avail_out;
|
||||
if (no) {
|
||||
v[i].iov_base = dg.b;
|
||||
|
@ -2877,7 +2923,8 @@ static char *GetAssetPath(uint8_t *zcf, size_t *out_size) {
|
|||
p2[0] = '/';
|
||||
memcpy(p2 + 1, p1, n1);
|
||||
p2[1 + n1] = '\0';
|
||||
if (out_size) *out_size = 1 + n1;
|
||||
if (out_size)
|
||||
*out_size = 1 + n1;
|
||||
return p2;
|
||||
}
|
||||
|
||||
|
@ -2928,8 +2975,10 @@ static void LaunchBrowser(const char *path) {
|
|||
port = ntohs(servers.p[0].addr.sin_port);
|
||||
}
|
||||
// assign a loopback address if no server or unknown server address
|
||||
if (!servers.n || !addr.s_addr) addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if (*path != '/') path = gc(xasprintf("/%s", path));
|
||||
if (!servers.n || !addr.s_addr)
|
||||
addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if (*path != '/')
|
||||
path = gc(xasprintf("/%s", path));
|
||||
launch_browser(gc(xasprintf("http://%s:%d%s", inet_ntoa(addr), port, path)));
|
||||
}
|
||||
|
||||
|
@ -3102,11 +3151,13 @@ static const char *MergeNames(const char *a, const char *b) {
|
|||
}
|
||||
|
||||
static void AppendLong1(const char *a, long x) {
|
||||
if (x) appendf(&cpm.outbuf, "%s: %ld\r\n", a, x);
|
||||
if (x)
|
||||
appendf(&cpm.outbuf, "%s: %ld\r\n", a, x);
|
||||
}
|
||||
|
||||
static void AppendLong2(const char *a, const char *b, long x) {
|
||||
if (x) appendf(&cpm.outbuf, "%s.%s: %ld\r\n", a, b, x);
|
||||
if (x)
|
||||
appendf(&cpm.outbuf, "%s.%s: %ld\r\n", a, b, x);
|
||||
}
|
||||
|
||||
static void AppendTimeval(const char *a, struct timeval *tv) {
|
||||
|
@ -3282,7 +3333,8 @@ static char *HandleRedirect(struct Redirect *r) {
|
|||
} else {
|
||||
LockInc(&shared->c.redirects);
|
||||
code = r->code;
|
||||
if (!code) code = 307;
|
||||
if (!code)
|
||||
code = 307;
|
||||
DEBUGF("(rsp) %d redirect to %`'s", code, r->location.s);
|
||||
return AppendHeader(
|
||||
SetStatus(code, GetHttpReason(code)), "Location",
|
||||
|
@ -3629,8 +3681,10 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
|
|||
}
|
||||
INFOF("(srvr) storing asset %`'s", path);
|
||||
disk = gflags = iattrs = 0;
|
||||
if (isutf8(path, pathlen)) gflags |= kZipGflagUtf8;
|
||||
if (istext(data, datalen)) iattrs |= kZipIattrText;
|
||||
if (isutf8(path, pathlen))
|
||||
gflags |= kZipGflagUtf8;
|
||||
if (istext(data, datalen))
|
||||
iattrs |= kZipIattrText;
|
||||
crc = crc32_z(0, data, datalen);
|
||||
if (datalen < 100) {
|
||||
method = kZipCompressionNone;
|
||||
|
@ -3661,9 +3715,12 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
|
|||
OpenZip(false);
|
||||
now = timespec_real();
|
||||
a = GetAssetZip(path, pathlen);
|
||||
if (!mode) mode = a ? GetMode(a) : 0644;
|
||||
if (!(mode & S_IFMT)) mode |= S_IFREG;
|
||||
if (pathlen > 1 && path[0] == '/') ++path, --pathlen;
|
||||
if (!mode)
|
||||
mode = a ? GetMode(a) : 0644;
|
||||
if (!(mode & S_IFMT))
|
||||
mode |= S_IFREG;
|
||||
if (pathlen > 1 && path[0] == '/')
|
||||
++path, --pathlen;
|
||||
dosmode = !(mode & 0200) ? kNtFileAttributeReadonly : 0;
|
||||
ft = (now.tv_sec + MODERNITYSECONDS) * HECTONANOSECONDS;
|
||||
GetDosLocalTime(now.tv_sec, &mtime, &mdate);
|
||||
|
@ -3812,12 +3869,14 @@ static void StoreFile(const char *path) {
|
|||
struct stat st;
|
||||
size_t plen, tlen;
|
||||
const char *target = path;
|
||||
if (startswith(target, "./")) target += 2;
|
||||
if (startswith(target, "./"))
|
||||
target += 2;
|
||||
tlen = strlen(target);
|
||||
if (!IsReasonablePath(target, tlen))
|
||||
FATALF("(cfg) error: can't store %`'s: contains '.' or '..' segments",
|
||||
target);
|
||||
if (lstat(path, &st) == -1) FATALF("(cfg) error: can't stat %`'s: %m", path);
|
||||
if (lstat(path, &st) == -1)
|
||||
FATALF("(cfg) error: can't stat %`'s: %m", path);
|
||||
if (!(p = xslurp(path, &plen)))
|
||||
FATALF("(cfg) error: can't read %`'s: %m", path);
|
||||
StoreAsset(target, tlen, p, plen, st.st_mode & 0777);
|
||||
|
@ -3831,10 +3890,13 @@ static void StorePath(const char *dirpath) {
|
|||
if (!isdirectory(dirpath) && !endswith(dirpath, "/")) {
|
||||
return StoreFile(dirpath);
|
||||
}
|
||||
if (!(d = opendir(dirpath))) FATALF("(cfg) error: can't open %`'s", dirpath);
|
||||
if (!(d = opendir(dirpath)))
|
||||
FATALF("(cfg) error: can't open %`'s", dirpath);
|
||||
while ((e = readdir(d))) {
|
||||
if (strcmp(e->d_name, ".") == 0) continue;
|
||||
if (strcmp(e->d_name, "..") == 0) continue;
|
||||
if (strcmp(e->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(e->d_name, "..") == 0)
|
||||
continue;
|
||||
path = gc(xjoinpaths(dirpath, e->d_name));
|
||||
if (e->d_type == DT_DIR) {
|
||||
StorePath(path);
|
||||
|
@ -3861,7 +3923,8 @@ static int LuaStoreAsset(lua_State *L) {
|
|||
|
||||
static void ReseedRng(mbedtls_ctr_drbg_context *r, const char *s) {
|
||||
#ifndef UNSECURE
|
||||
if (unsecure) return;
|
||||
if (unsecure)
|
||||
return;
|
||||
CHECK_EQ(0, mbedtls_ctr_drbg_reseed(r, (void *)s, strlen(s)));
|
||||
#endif
|
||||
}
|
||||
|
@ -3869,8 +3932,10 @@ static void ReseedRng(mbedtls_ctr_drbg_context *r, const char *s) {
|
|||
static void LogMessage(const char *d, const char *s, size_t n) {
|
||||
size_t n2, n3;
|
||||
char *s2, *s3;
|
||||
if (!LOGGABLE(kLogInfo)) return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
||||
if (!LOGGABLE(kLogInfo))
|
||||
return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n'))
|
||||
--n;
|
||||
if ((s2 = DecodeLatin1(s, n, &n2))) {
|
||||
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
||||
INFOF("(stat) %s %,ld byte message\r\n%.*s", d, n, n3, s3);
|
||||
|
@ -3883,9 +3948,12 @@ static void LogMessage(const char *d, const char *s, size_t n) {
|
|||
static void LogBody(const char *d, const char *s, size_t n) {
|
||||
char *s2, *s3;
|
||||
size_t n2, n3;
|
||||
if (!n) return;
|
||||
if (!LOGGABLE(kLogInfo)) return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
||||
if (!n)
|
||||
return;
|
||||
if (!LOGGABLE(kLogInfo))
|
||||
return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n'))
|
||||
--n;
|
||||
if ((s2 = VisualizeControlCodes(s, n, &n2))) {
|
||||
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
||||
INFOF("(stat) %s %,ld byte payload\r\n%.*s", d, n, n3, s3);
|
||||
|
@ -4107,7 +4175,8 @@ static int LuaGetUser(lua_State *L) {
|
|||
if (url.user.p) {
|
||||
LuaPushUrlView(L, &url.user);
|
||||
} else if ((p = gc(GetBasicAuthorization(&n)))) {
|
||||
if (!(q = memchr(p, ':', n))) q = p + n;
|
||||
if (!(q = memchr(p, ':', n)))
|
||||
q = p + n;
|
||||
lua_pushlstring(L, p, q - p);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
|
@ -4148,8 +4217,10 @@ static int LuaGetHost(lua_State *L) {
|
|||
static int LuaGetPort(lua_State *L) {
|
||||
int i, x = 0;
|
||||
OnlyCallDuringRequest(L, "GetPort");
|
||||
for (i = 0; i < url.port.n; ++i) x = url.port.p[i] - '0' + x * 10;
|
||||
if (!x) x = ntohs(serveraddr->sin_port);
|
||||
for (i = 0; i < url.port.n; ++i)
|
||||
x = url.port.p[i] - '0' + x * 10;
|
||||
if (!x)
|
||||
x = ntohs(serveraddr->sin_port);
|
||||
lua_pushinteger(L, x);
|
||||
return 1;
|
||||
}
|
||||
|
@ -4219,7 +4290,8 @@ static int LuaSetHeader(lua_State *L) {
|
|||
OnlyCallDuringRequest(L, "SetHeader");
|
||||
key = luaL_checklstring(L, 1, &keylen);
|
||||
val = luaL_optlstring(L, 2, 0, &vallen);
|
||||
if (!val) return 0;
|
||||
if (!val)
|
||||
return 0;
|
||||
if ((h = GetHttpHeader(key, keylen)) == -1) {
|
||||
if (!IsValidHttpToken(key, keylen)) {
|
||||
luaL_argerror(L, 1, "invalid");
|
||||
|
@ -4283,7 +4355,8 @@ static int LuaGetCookie(lua_State *L) {
|
|||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
if (cookie) free(cookie);
|
||||
if (cookie)
|
||||
free(cookie);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4503,7 +4576,8 @@ static int LuaProgramUniprocess(lua_State *L) {
|
|||
return luaL_argerror(L, 1, "invalid uniprocess mode; boolean expected");
|
||||
}
|
||||
lua_pushboolean(L, uniprocess);
|
||||
if (lua_isboolean(L, 1)) uniprocess = lua_toboolean(L, 1);
|
||||
if (lua_isboolean(L, 1))
|
||||
uniprocess = lua_toboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4525,7 +4599,8 @@ static int LuaProgramMaxWorkers(lua_State *L) {
|
|||
return luaL_argerror(L, 1, "invalid number of workers; integer expected");
|
||||
}
|
||||
lua_pushinteger(L, maxworkers);
|
||||
if (lua_isinteger(L, 1)) maxworkers = lua_tointeger(L, 1);
|
||||
if (lua_isinteger(L, 1))
|
||||
maxworkers = lua_tointeger(L, 1);
|
||||
maxworkers = MAX(maxworkers, 1);
|
||||
return 1;
|
||||
}
|
||||
|
@ -4803,7 +4878,8 @@ static int LuaIsAssetCompressed(lua_State *L) {
|
|||
|
||||
static bool Blackhole(uint32_t ip) {
|
||||
char buf[4];
|
||||
if (blackhole.fd <= 0) return false;
|
||||
if (blackhole.fd <= 0)
|
||||
return false;
|
||||
WRITE32BE(buf, ip);
|
||||
if (sendto(blackhole.fd, &buf, 4, 0, (struct sockaddr *)&blackhole.addr,
|
||||
sizeof(blackhole.addr)) != -1) {
|
||||
|
@ -4927,8 +5003,10 @@ static int LuaProgramTokenBucket(lua_State *L) {
|
|||
reject, //
|
||||
ignore, //
|
||||
ban);
|
||||
if (ignore == -1) ignore = -128;
|
||||
if (ban == -1) ban = -128;
|
||||
if (ignore == -1)
|
||||
ignore = -128;
|
||||
if (ban == -1)
|
||||
ban = -128;
|
||||
if (ban >= 0 && (IsLinux() || IsBsd())) {
|
||||
uint32_t testip = 0;
|
||||
blackhole.addr.sun_family = AF_UNIX;
|
||||
|
@ -4955,14 +5033,16 @@ static int LuaProgramTokenBucket(lua_State *L) {
|
|||
tokenbucket.replenish = timespec_fromnanos(1 / replenish * 1e9);
|
||||
int pid = fork();
|
||||
npassert(pid != -1);
|
||||
if (!pid) Replenisher();
|
||||
if (!pid)
|
||||
Replenisher();
|
||||
++shared->workers;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *GetContentTypeExt(const char *path, size_t n) {
|
||||
const char *r = NULL, *e;
|
||||
if ((r = FindContentType(path, n))) return r;
|
||||
if ((r = FindContentType(path, n)))
|
||||
return r;
|
||||
#ifndef STATIC
|
||||
int top;
|
||||
lua_State *L = GL;
|
||||
|
@ -5053,7 +5133,8 @@ static bool LuaRunAsset(const char *path, bool mandatory) {
|
|||
if (status != LUA_OK || LuaCallWithTrace(L, 0, 0, NULL) != LUA_OK) {
|
||||
LogLuaError("lua code", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
if (mandatory) exit(1);
|
||||
if (mandatory)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5416,7 +5497,8 @@ static void LuaPrint(lua_State *L) {
|
|||
n = lua_gettop(L);
|
||||
if (n > 0) {
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (i > 1) appendw(&b, '\t');
|
||||
if (i > 1)
|
||||
appendw(&b, '\t');
|
||||
struct EncoderConfig conf = {
|
||||
.maxdepth = 64,
|
||||
.sorted = true,
|
||||
|
@ -5450,12 +5532,14 @@ static int LuaInterpreter(lua_State *L) {
|
|||
const char *script;
|
||||
if (optind < __argc) {
|
||||
script = __argv[optind];
|
||||
if (!strcmp(script, "-")) script = 0;
|
||||
if (!strcmp(script, "-"))
|
||||
script = 0;
|
||||
if ((status = luaL_loadfile(L, script)) == LUA_OK) {
|
||||
lua_getglobal(L, "arg");
|
||||
n = luaL_len(L, -1);
|
||||
luaL_checkstack(L, n + 3, "too many script args");
|
||||
for (i = 1; i <= n; i++) lua_rawgeti(L, -i, i);
|
||||
for (i = 1; i <= n; i++)
|
||||
lua_rawgeti(L, -i, i);
|
||||
lua_remove(L, -i); // remove arg table from stack
|
||||
TRACE_BEGIN;
|
||||
status = lua_runchunk(L, n, LUA_MULTRET);
|
||||
|
@ -5469,7 +5553,8 @@ static int LuaInterpreter(lua_State *L) {
|
|||
EnableRawMode();
|
||||
for (;;) {
|
||||
status = lua_loadline(L);
|
||||
if (status == -1) break; // eof
|
||||
if (status == -1)
|
||||
break; // eof
|
||||
if (status == -2) {
|
||||
if (errno == EINTR) {
|
||||
if ((sig = linenoiseGetInterrupt())) {
|
||||
|
@ -5579,10 +5664,14 @@ static void LuaOnServerReload(bool reindex) {
|
|||
}
|
||||
|
||||
static const char *DescribeClose(void) {
|
||||
if (killed) return "killed";
|
||||
if (meltdown) return "meltdown";
|
||||
if (terminated) return "terminated";
|
||||
if (connectionclose) return "connection closed";
|
||||
if (killed)
|
||||
return "killed";
|
||||
if (meltdown)
|
||||
return "meltdown";
|
||||
if (terminated)
|
||||
return "terminated";
|
||||
if (connectionclose)
|
||||
return "connection closed";
|
||||
return "destroyed";
|
||||
}
|
||||
|
||||
|
@ -5859,7 +5948,8 @@ static char *ReadMore(void) {
|
|||
ssize_t rc;
|
||||
LockInc(&shared->c.frags);
|
||||
if ((rc = reader(client, inbuf.p + amtread, inbuf.n - amtread)) != -1) {
|
||||
if (!(got = rc)) return HandlePayloadDisconnect();
|
||||
if (!(got = rc))
|
||||
return HandlePayloadDisconnect();
|
||||
amtread += got;
|
||||
} else if (errno == EINTR) {
|
||||
LockInc(&shared->c.readinterrupts);
|
||||
|
@ -5877,10 +5967,12 @@ static char *ReadMore(void) {
|
|||
static char *SynchronizeLength(void) {
|
||||
char *p;
|
||||
if (hdrsize + payloadlength > amtread) {
|
||||
if (hdrsize + payloadlength > inbuf.n) return HandleHugePayload();
|
||||
if (hdrsize + payloadlength > inbuf.n)
|
||||
return HandleHugePayload();
|
||||
SendContinueIfNeeded();
|
||||
while (amtread < hdrsize + payloadlength) {
|
||||
if ((p = ReadMore())) return p;
|
||||
if ((p = ReadMore()))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
cpm.msgsize = hdrsize + payloadlength;
|
||||
|
@ -5894,9 +5986,11 @@ static char *SynchronizeChunked(void) {
|
|||
SendContinueIfNeeded();
|
||||
while (!(transferlength = Unchunk(&u, inbuf.p + hdrsize, amtread - hdrsize,
|
||||
&payloadlength))) {
|
||||
if ((p = ReadMore())) return p;
|
||||
if ((p = ReadMore()))
|
||||
return p;
|
||||
}
|
||||
if (transferlength == -1) return HandleHugePayload();
|
||||
if (transferlength == -1)
|
||||
return HandleHugePayload();
|
||||
cpm.msgsize = hdrsize + transferlength;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5987,8 +6081,10 @@ static char *HandleRequest(void) {
|
|||
} else {
|
||||
return HandleVersionNotSupported();
|
||||
}
|
||||
if ((p = SynchronizeStream())) return p;
|
||||
if (logbodies) LogBody("received", inbuf.p + hdrsize, payloadlength);
|
||||
if ((p = SynchronizeStream()))
|
||||
return p;
|
||||
if (logbodies)
|
||||
LogBody("received", inbuf.p + hdrsize, payloadlength);
|
||||
if (cpm.msg.version < 11 || HeaderEqualCase(kHttpConnection, "close")) {
|
||||
connectionclose = true;
|
||||
}
|
||||
|
@ -6025,7 +6121,8 @@ static char *HandleRequest(void) {
|
|||
}
|
||||
FreeLater(url.params.p);
|
||||
#ifndef STATIC
|
||||
if (hasonhttprequest) return LuaOnHttpRequest();
|
||||
if (hasonhttprequest)
|
||||
return LuaOnHttpRequest();
|
||||
#endif
|
||||
return Route(url.host.p, url.host.n, url.path.p, url.path.n);
|
||||
}
|
||||
|
@ -6041,7 +6138,8 @@ static char *Route(const char *host, size_t hostlen, const char *path,
|
|||
return p;
|
||||
}
|
||||
if (SlicesEqual(path, pathlen, "/", 1)) {
|
||||
if ((p = ServeIndex("/", 1))) return p;
|
||||
if ((p = ServeIndex("/", 1)))
|
||||
return p;
|
||||
return ServeListing();
|
||||
} else if ((p = RoutePath(path, pathlen))) {
|
||||
return p;
|
||||
|
@ -6090,16 +6188,19 @@ static char *RouteHost(const char *host, size_t hostlen, const char *path,
|
|||
hp = hm <= sizeof(b) ? b : FreeLater(xmalloc(hm));
|
||||
hp[0] = '/';
|
||||
mempcpy(mempcpy(hp + 1, host, hostlen), path, pathlen);
|
||||
if ((p = RoutePath(hp, hn))) return p;
|
||||
if ((p = RoutePath(hp, hn)))
|
||||
return p;
|
||||
if (!isdigit(host[0])) {
|
||||
if (hostlen > 4 &&
|
||||
READ32LE(host) == ('w' | 'w' << 8 | 'w' << 16 | '.' << 24)) {
|
||||
mempcpy(mempcpy(hp + 1, host + 4, hostlen - 4), path, pathlen);
|
||||
if ((p = RoutePath(hp, hn - 4))) return p;
|
||||
if ((p = RoutePath(hp, hn - 4)))
|
||||
return p;
|
||||
} else {
|
||||
mempcpy(mempcpy(mempcpy(hp + 1, "www.", 4), host, hostlen), path,
|
||||
pathlen);
|
||||
if ((p = RoutePath(hp, hn + 4))) return p;
|
||||
if ((p = RoutePath(hp, hn + 4)))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6123,7 +6224,8 @@ static inline bool IsLua(struct Asset *a) {
|
|||
static char *HandleAsset(struct Asset *a, const char *path, size_t pathlen) {
|
||||
char *p;
|
||||
#ifndef STATIC
|
||||
if (IsLua(a)) return ServeLua(a, path, pathlen);
|
||||
if (IsLua(a))
|
||||
return ServeLua(a, path, pathlen);
|
||||
#endif
|
||||
if (cpm.msg.method == kHttpGet || cpm.msg.method == kHttpHead) {
|
||||
LockInc(&shared->c.staticrequests);
|
||||
|
@ -6150,8 +6252,10 @@ static const char *GetContentType(struct Asset *a, const char *path, size_t n) {
|
|||
}
|
||||
|
||||
static bool IsNotModified(struct Asset *a) {
|
||||
if (cpm.msg.version < 10) return false;
|
||||
if (!HasHeader(kHttpIfModifiedSince)) return false;
|
||||
if (cpm.msg.version < 10)
|
||||
return false;
|
||||
if (!HasHeader(kHttpIfModifiedSince))
|
||||
return false;
|
||||
return a->lastmodified <=
|
||||
ParseHttpDateTime(HeaderData(kHttpIfModifiedSince),
|
||||
HeaderLength(kHttpIfModifiedSince));
|
||||
|
@ -6217,8 +6321,10 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) {
|
|||
|
||||
static char *SetStatus(unsigned code, const char *reason) {
|
||||
if (cpm.msg.version == 10) {
|
||||
if (code == 307) code = 302;
|
||||
if (code == 308) code = 301;
|
||||
if (code == 307)
|
||||
code = 302;
|
||||
if (code == 308)
|
||||
code = 301;
|
||||
}
|
||||
cpm.statuscode = code;
|
||||
cpm.hascontenttype = false;
|
||||
|
@ -6321,7 +6427,8 @@ static bool StreamResponse(char *p) {
|
|||
iov[3].iov_len = 0;
|
||||
iov[4].iov_base = 0;
|
||||
iov[4].iov_len = 0;
|
||||
if ((rc = cpm.generator(iov + 2)) <= 0) break;
|
||||
if ((rc = cpm.generator(iov + 2)) <= 0)
|
||||
break;
|
||||
if (cpm.msg.version >= 11) {
|
||||
s = chunkbuf;
|
||||
s += uint64toarray_radix16(rc, s);
|
||||
|
@ -6329,7 +6436,8 @@ static bool StreamResponse(char *p) {
|
|||
iov[1].iov_base = chunkbuf;
|
||||
iov[1].iov_len = s - chunkbuf;
|
||||
}
|
||||
if (Send(iov, 6) == -1) break;
|
||||
if (Send(iov, 6) == -1)
|
||||
break;
|
||||
iov[0].iov_base = 0;
|
||||
iov[0].iov_len = 0;
|
||||
}
|
||||
|
@ -6351,7 +6459,8 @@ static bool HandleMessageActual(void) {
|
|||
char *p;
|
||||
struct timespec now;
|
||||
if ((rc = ParseHttpMessage(&cpm.msg, inbuf.p, amtread)) != -1) {
|
||||
if (!rc) return false;
|
||||
if (!rc)
|
||||
return false;
|
||||
hdrsize = rc;
|
||||
if (logmessages) {
|
||||
LogMessage("received", inbuf.p, hdrsize);
|
||||
|
@ -6373,8 +6482,10 @@ static bool HandleMessageActual(void) {
|
|||
}
|
||||
if (cpm.msg.version >= 10) {
|
||||
p = AppendCrlf(stpcpy(stpcpy(p, "Date: "), shared->currentdate));
|
||||
if (!cpm.branded) p = stpcpy(p, serverheader);
|
||||
if (extrahdrs) p = stpcpy(p, extrahdrs);
|
||||
if (!cpm.branded)
|
||||
p = stpcpy(p, serverheader);
|
||||
if (extrahdrs)
|
||||
p = stpcpy(p, extrahdrs);
|
||||
if (connectionclose) {
|
||||
p = stpcpy(p, "Connection: close\r\n");
|
||||
} else if (timeout.tv_sec < 0 && cpm.msg.version >= 11) {
|
||||
|
@ -6395,7 +6506,8 @@ static bool HandleMessageActual(void) {
|
|||
now = timespec_real();
|
||||
reqtime = timespec_tomicros(timespec_sub(now, startrequest));
|
||||
contime = timespec_tomicros(timespec_sub(now, startconnection));
|
||||
if (hasonloglatency) LuaOnLogLatency(reqtime, contime);
|
||||
if (hasonloglatency)
|
||||
LuaOnLogLatency(reqtime, contime);
|
||||
if (loglatency || LOGGABLE(kLogDebug))
|
||||
LOGF(kLogDebug, "(stat) %`'.*s latency r: %,ldµs c: %,ldµs",
|
||||
cpm.msg.uri.b - cpm.msg.uri.a, inbuf.p + cpm.msg.uri.a, reqtime,
|
||||
|
@ -6422,8 +6534,10 @@ static void InitRequest(void) {
|
|||
}
|
||||
|
||||
static bool IsSsl(unsigned char c) {
|
||||
if (c == 22) return true;
|
||||
if (!(c & 128)) return false;
|
||||
if (c == 22)
|
||||
return true;
|
||||
if (!(c & 128))
|
||||
return false;
|
||||
/* RHEL5 sends SSLv2 hello but supports TLS */
|
||||
DEBUGF("(ssl) %s SSLv2 hello D:", DescribeClient());
|
||||
return true;
|
||||
|
@ -6440,7 +6554,8 @@ static void HandleMessages(void) {
|
|||
for (;;) {
|
||||
if (!cpm.msg.i && amtread) {
|
||||
startrequest = timespec_real();
|
||||
if (HandleMessage()) break;
|
||||
if (HandleMessage())
|
||||
break;
|
||||
}
|
||||
if ((rc = reader(client, inbuf.p + amtread, inbuf.n - amtread)) != -1) {
|
||||
startrequest = timespec_real();
|
||||
|
@ -6483,7 +6598,8 @@ static void HandleMessages(void) {
|
|||
errno = 0;
|
||||
} else if (errno == EAGAIN) {
|
||||
LockInc(&shared->c.readtimeouts);
|
||||
if (amtread) SendTimeout();
|
||||
if (amtread)
|
||||
SendTimeout();
|
||||
NotifyClose();
|
||||
LogClose("read timeout");
|
||||
return;
|
||||
|
@ -6646,7 +6762,8 @@ static void *MemoryMonitor(void *arg) {
|
|||
if (tty != -1) {
|
||||
for (gen = 0, mi = 0, b = 0; !terminatemonitor;) {
|
||||
workers = atomic_load_explicit(&shared->workers, memory_order_relaxed);
|
||||
if (id) id = MAX(1, MIN(id, workers));
|
||||
if (id)
|
||||
id = MAX(1, MIN(id, workers));
|
||||
if (!id && workers) {
|
||||
usleep(50000);
|
||||
continue;
|
||||
|
@ -6931,11 +7048,16 @@ static int HandleConnection(size_t i) {
|
|||
static void MakeExecutableModifiable(void) {
|
||||
#ifdef __x86_64__
|
||||
int ft;
|
||||
if (!(SUPPORT_VECTOR & (_HOSTMETAL | _HOSTWINDOWS | _HOSTXNU))) return;
|
||||
if (IsWindows()) return; // TODO
|
||||
if (IsOpenbsd()) return; // TODO
|
||||
if (IsNetbsd()) return; // TODO
|
||||
if (endswith(zpath, ".dbg")) return;
|
||||
if (!(SUPPORT_VECTOR & (_HOSTMETAL | _HOSTWINDOWS | _HOSTXNU)))
|
||||
return;
|
||||
if (IsWindows())
|
||||
return; // TODO
|
||||
if (IsOpenbsd())
|
||||
return; // TODO
|
||||
if (IsNetbsd())
|
||||
return; // TODO
|
||||
if (endswith(zpath, ".dbg"))
|
||||
return;
|
||||
close(zfd);
|
||||
ft = ftrace_enabled(0);
|
||||
if ((zfd = __open_executable()) == -1) {
|
||||
|
@ -6999,8 +7121,10 @@ static int HandlePoll(int ms) {
|
|||
if (nfds) {
|
||||
// handle pollid/o events
|
||||
for (pollid = 0; pollid < 1 + servers.n; ++pollid) {
|
||||
if (!polls[pollid].revents) continue;
|
||||
if (polls[pollid].fd < 0) continue;
|
||||
if (!polls[pollid].revents)
|
||||
continue;
|
||||
if (polls[pollid].fd < 0)
|
||||
continue;
|
||||
if (polls[pollid].fd) {
|
||||
// handle listen socket
|
||||
lua_repl_lock();
|
||||
|
@ -7011,12 +7135,14 @@ static int HandlePoll(int ms) {
|
|||
rc = HandleConnection(serverid);
|
||||
ishandlingconnection = false;
|
||||
lua_repl_unlock();
|
||||
if (rc == -1) return -1;
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
#ifndef STATIC
|
||||
} else {
|
||||
// handle standard input
|
||||
rc = HandleReadline();
|
||||
if (rc == -1) return rc;
|
||||
if (rc == -1)
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -7024,7 +7150,8 @@ static int HandlePoll(int ms) {
|
|||
} else if (__ttyconf.replmode) {
|
||||
// handle refresh repl line
|
||||
rc = HandleReadline();
|
||||
if (rc < 0) return rc;
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
@ -7094,7 +7221,8 @@ static void Listen(void) {
|
|||
}
|
||||
port = ntohs(servers.p[n].addr.sin_port);
|
||||
ip = ntohl(servers.p[n].addr.sin_addr.s_addr);
|
||||
if (ip == INADDR_ANY) ip = INADDR_LOOPBACK;
|
||||
if (ip == INADDR_ANY)
|
||||
ip = INADDR_LOOPBACK;
|
||||
INFOF("(srvr) listen http://%hhu.%hhu.%hhu.%hhu:%d", ip >> 24, ip >> 16,
|
||||
ip >> 8, ip, port);
|
||||
if (printport && !ports.p[j]) {
|
||||
|
@ -7122,7 +7250,8 @@ static void HandleShutdown(void) {
|
|||
CloseServerFds();
|
||||
INFOF("(srvr) received %s", strsignal(shutdownsig));
|
||||
if (shutdownsig != SIGINT && shutdownsig != SIGQUIT) {
|
||||
if (!killed) terminated = false;
|
||||
if (!killed)
|
||||
terminated = false;
|
||||
INFOF("(srvr) killing process group");
|
||||
KillGroup();
|
||||
}
|
||||
|
@ -7193,7 +7322,8 @@ static void SigInit(void) {
|
|||
static void TlsInit(void) {
|
||||
#ifndef UNSECURE
|
||||
int suite;
|
||||
if (unsecure) return;
|
||||
if (unsecure)
|
||||
return;
|
||||
|
||||
if (suiteb && !mbedtls_aes_uses_hardware()) {
|
||||
WARNF("(srvr) requested suiteb crypto, but hardware aes not present");
|
||||
|
@ -7227,7 +7357,8 @@ static void TlsInit(void) {
|
|||
mbedtls_ssl_ticket_parse, &ssltick);
|
||||
}
|
||||
|
||||
if (sslinitialized) return;
|
||||
if (sslinitialized)
|
||||
return;
|
||||
sslinitialized = true;
|
||||
|
||||
LoadCertificates();
|
||||
|
@ -7257,7 +7388,8 @@ static void TlsInit(void) {
|
|||
|
||||
static void TlsDestroy(void) {
|
||||
#ifndef UNSECURE
|
||||
if (unsecure) return;
|
||||
if (unsecure)
|
||||
return;
|
||||
mbedtls_ssl_free(&ssl);
|
||||
mbedtls_ssl_free(&sslcli);
|
||||
mbedtls_ctr_drbg_free(&rng);
|
||||
|
@ -7352,9 +7484,11 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
// if storing asset(s) is requested, don't need to continue
|
||||
if (storeasset) exit(0);
|
||||
if (storeasset)
|
||||
exit(0);
|
||||
// we don't want to drop into a repl after using -e in -i mode
|
||||
if (interpretermode && got_e_arg) exit(0);
|
||||
if (interpretermode && got_e_arg)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void RedBean(int argc, char *argv[]) {
|
||||
|
@ -7362,7 +7496,8 @@ void RedBean(int argc, char *argv[]) {
|
|||
int fd;
|
||||
// don't complain about --assimilate if it's the only parameter,
|
||||
// as it can only get here if it's already native or assimilated
|
||||
if (argc == 2 && strcmp(argv[1], "--assimilate") == 0) return;
|
||||
if (argc == 2 && strcmp(argv[1], "--assimilate") == 0)
|
||||
return;
|
||||
if (IsLinux()) {
|
||||
// disable weird linux capabilities
|
||||
for (int e = errno, i = 0;; ++i) {
|
||||
|
@ -7415,7 +7550,8 @@ void RedBean(int argc, char *argv[]) {
|
|||
shared->workers = 1;
|
||||
}
|
||||
if (daemonize) {
|
||||
if (!logpath) ProgramLogPath("/dev/null");
|
||||
if (!logpath)
|
||||
ProgramLogPath("/dev/null");
|
||||
dup2(2, 1);
|
||||
}
|
||||
SigInit();
|
||||
|
|
|
@ -24,9 +24,12 @@ pureconst bool IsHex(int c) {
|
|||
}
|
||||
|
||||
pureconst int GetDiglet(int c) {
|
||||
if (IsDigit(c)) return c - L'0';
|
||||
if (IsUpper(c)) return c - L'A' + 10;
|
||||
if (IsLower(c)) return c - L'a' + 10;
|
||||
if (IsDigit(c))
|
||||
return c - L'0';
|
||||
if (IsUpper(c))
|
||||
return c - L'A' + 10;
|
||||
if (IsLower(c))
|
||||
return c - L'a' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,20 +50,29 @@
|
|||
int Cmp(int x, int y) {
|
||||
int c;
|
||||
dword t, u;
|
||||
if (x == y) return 0;
|
||||
if (x == y)
|
||||
return 0;
|
||||
if (x > 1 && y > 1) {
|
||||
if (LO(Get(x)) < LO(Get(x))) return -1;
|
||||
if (LO(Get(x)) > LO(Get(x))) return +1;
|
||||
if (LO(Get(x)) < LO(Get(x)))
|
||||
return -1;
|
||||
if (LO(Get(x)) > LO(Get(x)))
|
||||
return +1;
|
||||
}
|
||||
for (;; x = Cdr(x), y = Cdr(y)) {
|
||||
if (x == y) return 0;
|
||||
if (!x) return -1;
|
||||
if (!y) return +1;
|
||||
if (x == y)
|
||||
return 0;
|
||||
if (!x)
|
||||
return -1;
|
||||
if (!y)
|
||||
return +1;
|
||||
if (x < 0) {
|
||||
if (y >= 0) return +1;
|
||||
if ((c = Cmp(Car(x), Car(y)))) return c;
|
||||
if (y >= 0)
|
||||
return +1;
|
||||
if ((c = Cmp(Car(x), Car(y))))
|
||||
return c;
|
||||
} else {
|
||||
if (y < 0) return -1;
|
||||
if (y < 0)
|
||||
return -1;
|
||||
for (;;) {
|
||||
t = x != 1 ? Get(x) : MAKE(L'T', TERM);
|
||||
u = y != 1 ? Get(y) : MAKE(L'T', TERM);
|
||||
|
@ -72,9 +81,12 @@ int Cmp(int x, int y) {
|
|||
}
|
||||
x = HI(t);
|
||||
y = HI(u);
|
||||
if (x == y) return 0;
|
||||
if (x == TERM) return -1;
|
||||
if (y == TERM) return +1;
|
||||
if (x == y)
|
||||
return 0;
|
||||
if (x == TERM)
|
||||
return -1;
|
||||
if (y == TERM)
|
||||
return +1;
|
||||
}
|
||||
if (Car(x) != Car(y)) {
|
||||
return Car(x) < Car(y) ? -1 : +1;
|
||||
|
|
|
@ -38,7 +38,8 @@ int Shadow(int p, int s) {
|
|||
|
||||
int GetCommonCons(int x, int y) {
|
||||
if (!y) {
|
||||
if (!x) return -1;
|
||||
if (!x)
|
||||
return -1;
|
||||
if (x > 0 && cFrost < -1 && IsUpper(LO(Get(x))) && HI(Get(x)) == TERM) {
|
||||
return kConsAlphabet[LO(Get(x)) - L'A'];
|
||||
}
|
||||
|
@ -48,7 +49,8 @@ int GetCommonCons(int x, int y) {
|
|||
|
||||
int ShareCons(int x, int y) {
|
||||
int i;
|
||||
if ((i = GetCommonCons(x, y))) return i;
|
||||
if ((i = GetCommonCons(x, y)))
|
||||
return i;
|
||||
#if 0
|
||||
t = MAKE(x, y);
|
||||
for (i = cx, n = MIN(0, i + 64); i < n; ++i) {
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "tool/plinko/lib/plinko.h"
|
||||
|
||||
nosideeffect int CountAtoms(int x, int max, int res) {
|
||||
if (!x || res >= max) return res;
|
||||
if (x > 0) return res + 1;
|
||||
if (!x || res >= max)
|
||||
return res;
|
||||
if (x > 0)
|
||||
return res + 1;
|
||||
return CountAtoms(Cdr(x), max, CountAtoms(Car(x), max, res));
|
||||
}
|
||||
|
|
|
@ -36,8 +36,10 @@ int Define(int e, int a) {
|
|||
struct Gc *G;
|
||||
int k, v, x, r, o;
|
||||
DCHECK_EQ(kDefine, Car(e));
|
||||
if (Cdr(e) >= 0) Error("bad define: %S", e);
|
||||
if (Cadr(e) <= 0) Error("scheme define: %S", e);
|
||||
if (Cdr(e) >= 0)
|
||||
Error("bad define: %S", e);
|
||||
if (Cadr(e) <= 0)
|
||||
Error("scheme define: %S", e);
|
||||
if (Cddr(e) >= 0 || Caddr(e) == kLambda) {
|
||||
/*
|
||||
* compatibility with sectorlisp friendly branch, e.g.
|
||||
|
|
|
@ -55,7 +55,8 @@ struct T DispatchYcombine(dword ea, dword tm, dword r, dword p1, dword p2,
|
|||
lambda = recurse(MAKE(Cadr(ea), HI(ea)), p1, p2);
|
||||
closure =
|
||||
recurse(MAKE(Caddr(ycomb), Alist(Car(Cadr(ycomb)), lambda, 0)), 0, 0);
|
||||
if (Car(lambda) == kClosure) lambda = Car(Cdr(lambda));
|
||||
if (Car(lambda) == kClosure)
|
||||
lambda = Car(Cdr(lambda));
|
||||
DCHECK_EQ(kClosure, Car(closure));
|
||||
DCHECK_EQ(kLambda, Car(lambda));
|
||||
DCHECK_EQ(kLambda, Car(Car(Cdr(closure))));
|
||||
|
|
|
@ -51,7 +51,8 @@ relegated wontreturn void StackOverflow(void) {
|
|||
}
|
||||
|
||||
relegated wontreturn void React(int e, int x, int k) {
|
||||
if (!sp || e != LO(GetCurrentFrame())) Push(e);
|
||||
if (!sp || e != LO(GetCurrentFrame()))
|
||||
Push(e);
|
||||
Push(x);
|
||||
Raise(k);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
#include "tool/plinko/lib/plinko.h"
|
||||
|
||||
int Evlis(int x, int a, dword p1, dword p2) {
|
||||
if (!x) return x;
|
||||
if (x > 0) return FasterRecurse(x, a, p1, p2);
|
||||
if (!x)
|
||||
return x;
|
||||
if (x > 0)
|
||||
return FasterRecurse(x, a, p1, p2);
|
||||
int y = FasterRecurse(Car(x), a, p1, p2);
|
||||
return Cons(y, Evlis(Cdr(x), a, p1, p2));
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
|
||||
int Exlis(int x, int a) {
|
||||
int y;
|
||||
if (!x) return x;
|
||||
if (x > 0) return expand(x, a);
|
||||
if (!x)
|
||||
return x;
|
||||
if (x > 0)
|
||||
return expand(x, a);
|
||||
y = expand(Car(x), a);
|
||||
return Keep(x, Cons(y, Exlis(Cdr(x), a)));
|
||||
}
|
||||
|
@ -37,10 +39,13 @@ static int Expander(int e, int a) {
|
|||
for (s = 0;;) {
|
||||
DCHECK_LT(e, TERM);
|
||||
DCHECK_LE(a, 0);
|
||||
if (e >= 0) return e;
|
||||
if (e >= 0)
|
||||
return e;
|
||||
if ((f = Car(e)) > 0) {
|
||||
if (f == kQuote) return e;
|
||||
if (f == kClosure) return e;
|
||||
if (f == kQuote)
|
||||
return e;
|
||||
if (f == kClosure)
|
||||
return e;
|
||||
if (f == kTrace) {
|
||||
START_TRACE;
|
||||
x = Cadr(e);
|
||||
|
@ -49,14 +54,17 @@ static int Expander(int e, int a) {
|
|||
END_TRACE;
|
||||
return e;
|
||||
}
|
||||
if (HasAtom(f, s)) return e;
|
||||
if (HasAtom(f, s))
|
||||
return e;
|
||||
s = Cons(f, s);
|
||||
}
|
||||
e = Exlis(e, a);
|
||||
if (f >= 0) {
|
||||
if (!(f = Assoc(f, a))) return e;
|
||||
if (!(f = Assoc(f, a)))
|
||||
return e;
|
||||
f = Cdr(f);
|
||||
if (f >= 0) return e;
|
||||
if (f >= 0)
|
||||
return e;
|
||||
}
|
||||
if (Car(f) == kClosure) {
|
||||
u = Cddr(f);
|
||||
|
@ -64,7 +72,8 @@ static int Expander(int e, int a) {
|
|||
} else {
|
||||
u = a;
|
||||
}
|
||||
if (Head(f) != kMacro) return e;
|
||||
if (Head(f) != kMacro)
|
||||
return e;
|
||||
e = eval(Caddr(f), pairlis(Cadr(f), Cdr(e), u));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ struct Gc *NewGc(int A) {
|
|||
struct Gc *G;
|
||||
DCHECK_LE(B, A);
|
||||
DCHECK_LE(A, 0);
|
||||
if (B < cHeap) cHeap = B;
|
||||
if (B < cHeap)
|
||||
cHeap = B;
|
||||
n = ROUNDUP(A - B, DWBITS) / DWBITS;
|
||||
G = Addr(BANE);
|
||||
bzero(G->M, n * sizeof(G->M[0]));
|
||||
|
@ -65,7 +66,8 @@ void Marker(const dword M[], int A, int x) {
|
|||
dword t;
|
||||
do {
|
||||
i = ~(x - A);
|
||||
if (HasBit(M, i)) return;
|
||||
if (HasBit(M, i))
|
||||
return;
|
||||
SetBit((void *)M, i);
|
||||
if (HI(GetShadow(x)) < A) {
|
||||
Marker(M, A, HI(GetShadow(x)));
|
||||
|
@ -118,7 +120,8 @@ int Relocater(const dword M[], const unsigned P[], int A, int x) {
|
|||
void Sweep(struct Gc *G) {
|
||||
dword m;
|
||||
int a, b, d, i, j;
|
||||
if (G->noop) return;
|
||||
if (G->noop)
|
||||
return;
|
||||
i = 0;
|
||||
b = d = G->A;
|
||||
for (; i < G->n; ++i) {
|
||||
|
@ -146,7 +149,8 @@ void Sweep(struct Gc *G) {
|
|||
|
||||
int MarkSweep(int A, int x) {
|
||||
struct Gc *G;
|
||||
if (x >= A) return cx = A, x;
|
||||
if (x >= A)
|
||||
return cx = A, x;
|
||||
G = NewGc(A);
|
||||
Mark(G, x);
|
||||
Census(G);
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "tool/plinko/lib/plinko.h"
|
||||
|
||||
nosideeffect bool HasAtom(int v, int x) {
|
||||
if (!x) return false;
|
||||
if (x > 0) return v == x;
|
||||
if (!x)
|
||||
return false;
|
||||
if (x > 0)
|
||||
return v == x;
|
||||
return HasAtom(v, Car(x)) || HasAtom(v, Cdr(x));
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@ void PrintHistogram(int fd, const char *s, const long *h, size_t n) {
|
|||
int j, p, m;
|
||||
char buf[101];
|
||||
size_t i, logos;
|
||||
if (!(t = GetLongSum(h, n))) return;
|
||||
if (!(t = GetLongSum(h, n)))
|
||||
return;
|
||||
Fprintf(fd, "%s%n", s);
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!h[i]) continue;
|
||||
if (!h[i])
|
||||
continue;
|
||||
p = h[i] * 1000000 / t;
|
||||
assert(0 <= p && p <= 1000000);
|
||||
for (j = 0, m = p / 10000; j < m; ++j) {
|
||||
|
|
|
@ -28,16 +28,20 @@
|
|||
*/
|
||||
int IsCar(int x_) {
|
||||
dword w_;
|
||||
if (x_ >= 0) return 0;
|
||||
if (x_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(x_); // (⍅ X)
|
||||
int ax_ = LO(w_);
|
||||
int dx_ = HI(w_);
|
||||
if (ax_ != kCar) return 0;
|
||||
if (dx_ >= 0) return 0;
|
||||
if (ax_ != kCar)
|
||||
return 0;
|
||||
if (dx_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(dx_); // (X)
|
||||
int adx_ = LO(w_);
|
||||
int ddx_ = HI(w_);
|
||||
int X = adx_;
|
||||
if (ddx_) return 0;
|
||||
if (ddx_)
|
||||
return 0;
|
||||
return X;
|
||||
}
|
||||
|
|
|
@ -28,16 +28,20 @@
|
|||
*/
|
||||
int IsCdr(int x_) {
|
||||
dword w_;
|
||||
if (x_ >= 0) return 0;
|
||||
if (x_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(x_); // (⍆ X)
|
||||
int ax_ = LO(w_);
|
||||
int dx_ = HI(w_);
|
||||
if (ax_ != kCdr) return 0;
|
||||
if (dx_ >= 0) return 0;
|
||||
if (ax_ != kCdr)
|
||||
return 0;
|
||||
if (dx_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(dx_); // (X)
|
||||
int adx_ = LO(w_);
|
||||
int ddx_ = HI(w_);
|
||||
int X = adx_;
|
||||
if (ddx_) return 0;
|
||||
if (ddx_)
|
||||
return 0;
|
||||
return X;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,13 @@
|
|||
|
||||
pureconst bool IsConstant(int e) {
|
||||
unsigned f = LO(GetShadow(e));
|
||||
if (f == EncodeDispatchFn(DispatchNil)) return true;
|
||||
if (f == EncodeDispatchFn(DispatchTrue)) return true;
|
||||
if (f == EncodeDispatchFn(DispatchPrecious)) return true;
|
||||
if (f == EncodeDispatchFn(DispatchQuote)) return true;
|
||||
if (f == EncodeDispatchFn(DispatchNil))
|
||||
return true;
|
||||
if (f == EncodeDispatchFn(DispatchTrue))
|
||||
return true;
|
||||
if (f == EncodeDispatchFn(DispatchPrecious))
|
||||
return true;
|
||||
if (f == EncodeDispatchFn(DispatchQuote))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -30,25 +30,32 @@
|
|||
*/
|
||||
int IsDelegate(int x_) {
|
||||
dword w_;
|
||||
if (x_ >= 0) return 0;
|
||||
if (x_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(x_); // (λ V (F . V) . Q)
|
||||
int ax_ = LO(w_);
|
||||
int dx_ = HI(w_);
|
||||
if (ax_ != kLambda) return 0;
|
||||
if (dx_ >= 0) return 0;
|
||||
if (ax_ != kLambda)
|
||||
return 0;
|
||||
if (dx_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(dx_); // (V (F . V) . Q)
|
||||
int adx_ = LO(w_);
|
||||
int ddx_ = HI(w_);
|
||||
int V = adx_;
|
||||
if (V <= 0) return 0;
|
||||
if (ddx_ >= 0) return 0;
|
||||
if (V <= 0)
|
||||
return 0;
|
||||
if (ddx_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(ddx_); // ((F . V) . Q)
|
||||
int addx_ = LO(w_);
|
||||
if (addx_ >= 0) return 0;
|
||||
if (addx_ >= 0)
|
||||
return 0;
|
||||
w_ = Get(addx_); // (F . V)
|
||||
int aaddx_ = LO(w_);
|
||||
int daddx_ = HI(w_);
|
||||
int F = aaddx_;
|
||||
if (daddx_ != V) return 0;
|
||||
if (daddx_ != V)
|
||||
return 0;
|
||||
return F;
|
||||
}
|
||||
|
|
|
@ -28,36 +28,46 @@
|
|||
*/
|
||||
struct qword IsIf(int x_) {
|
||||
dword w_;
|
||||
if (x_ >= 0) return ZERO4;
|
||||
if (x_ >= 0)
|
||||
return ZERO4;
|
||||
w_ = Get(x_); // (ζ (X Y) (Z))
|
||||
int ax_ = LO(w_);
|
||||
int dx_ = HI(w_);
|
||||
if (ax_ != kCond) return ZERO4;
|
||||
if (dx_ >= 0) return ZERO4;
|
||||
if (ax_ != kCond)
|
||||
return ZERO4;
|
||||
if (dx_ >= 0)
|
||||
return ZERO4;
|
||||
w_ = Get(dx_); // ((X Y) (Z))
|
||||
int adx_ = LO(w_);
|
||||
int ddx_ = HI(w_);
|
||||
if (adx_ >= 0) return ZERO4;
|
||||
if (adx_ >= 0)
|
||||
return ZERO4;
|
||||
w_ = Get(adx_); // (X Y)
|
||||
int aadx_ = LO(w_);
|
||||
int dadx_ = HI(w_);
|
||||
if (ddx_ >= 0) return ZERO4;
|
||||
if (ddx_ >= 0)
|
||||
return ZERO4;
|
||||
w_ = Get(ddx_); // ((Z))
|
||||
int addx_ = LO(w_);
|
||||
int dddx_ = HI(w_);
|
||||
int X = aadx_;
|
||||
if (addx_ >= 0) return ZERO4;
|
||||
if (addx_ >= 0)
|
||||
return ZERO4;
|
||||
w_ = Get(addx_); // (Z)
|
||||
int aaddx_ = LO(w_);
|
||||
int daddx_ = HI(w_);
|
||||
if (dadx_ >= 0) return ZERO4;
|
||||
if (dadx_ >= 0)
|
||||
return ZERO4;
|
||||
w_ = Get(dadx_); // (Y)
|
||||
int adadx_ = LO(w_);
|
||||
int ddadx_ = HI(w_);
|
||||
if (dddx_) return ZERO4;
|
||||
if (dddx_)
|
||||
return ZERO4;
|
||||
int Y = adadx_;
|
||||
int Z = aaddx_;
|
||||
if (ddadx_) return ZERO4;
|
||||
if (daddx_) return ZERO4;
|
||||
if (ddadx_)
|
||||
return ZERO4;
|
||||
if (daddx_)
|
||||
return ZERO4;
|
||||
return MAKE4(X, Y, Z, 0);
|
||||
}
|
||||
|
|
|
@ -34,138 +34,190 @@
|
|||
*/
|
||||
bool IsYcombinator(int x_) {
|
||||
dword w_;
|
||||
if (x_ >= 0) return false;
|
||||
if (x_ >= 0)
|
||||
return false;
|
||||
w_ = Get(x_);
|
||||
int ax_ = LO(w_);
|
||||
int dx_ = HI(w_);
|
||||
if (ax_ != kClosure) return false;
|
||||
if (dx_ >= 0) return false;
|
||||
if (ax_ != kClosure)
|
||||
return false;
|
||||
if (dx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(dx_); // ((λ (N) ((λ (W) (W W)) (λ (V) (N (λ M ((V V) . M)))))) . Q)
|
||||
int adx_ = LO(w_);
|
||||
if (adx_ >= 0) return false;
|
||||
if (adx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(adx_); // (λ (N) ((λ (W) (W W)) (λ (V) (N (λ M ((V V) . M))))))
|
||||
int aadx_ = LO(w_);
|
||||
int dadx_ = HI(w_);
|
||||
if (aadx_ != kLambda) return false;
|
||||
if (dadx_ >= 0) return false;
|
||||
if (aadx_ != kLambda)
|
||||
return false;
|
||||
if (dadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(dadx_); // ((N) ((λ (W) (W W)) (λ (V) (N (λ M ((V V) . M))))))
|
||||
int adadx_ = LO(w_);
|
||||
int ddadx_ = HI(w_);
|
||||
if (adadx_ >= 0) return false;
|
||||
if (adadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(adadx_); // (N)
|
||||
int aadadx_ = LO(w_);
|
||||
int dadadx_ = HI(w_);
|
||||
if (ddadx_ >= 0) return false;
|
||||
if (ddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(ddadx_); // (((λ (W) (W W)) (λ (V) (N (λ M ((V V) . M))))))
|
||||
int addadx_ = LO(w_);
|
||||
int dddadx_ = HI(w_);
|
||||
int N = aadadx_;
|
||||
if (N <= 0) return false;
|
||||
if (addadx_ >= 0) return false;
|
||||
if (N <= 0)
|
||||
return false;
|
||||
if (addadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(addadx_); // ((λ (W) (W W)) (λ (V) (N (λ M ((V V) . M)))))
|
||||
int aaddadx_ = LO(w_);
|
||||
int daddadx_ = HI(w_);
|
||||
if (dadadx_) return false;
|
||||
if (dddadx_) return false;
|
||||
if (aaddadx_ >= 0) return false;
|
||||
if (dadadx_)
|
||||
return false;
|
||||
if (dddadx_)
|
||||
return false;
|
||||
if (aaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(aaddadx_); // (λ (W) (W W))
|
||||
int aaaddadx_ = LO(w_);
|
||||
int daaddadx_ = HI(w_);
|
||||
if (daddadx_ >= 0) return false;
|
||||
if (daddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(daddadx_); // ((λ (V) (N (λ M ((V V) . M)))))
|
||||
int adaddadx_ = LO(w_);
|
||||
int ddaddadx_ = HI(w_);
|
||||
if (aaaddadx_ != kLambda) return false;
|
||||
if (adaddadx_ >= 0) return false;
|
||||
if (aaaddadx_ != kLambda)
|
||||
return false;
|
||||
if (adaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(adaddadx_); // (λ (V) (N (λ M ((V V) . M))))
|
||||
int aadaddadx_ = LO(w_);
|
||||
int dadaddadx_ = HI(w_);
|
||||
if (daaddadx_ >= 0) return false;
|
||||
if (daaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(daaddadx_); // ((W) (W W))
|
||||
int adaaddadx_ = LO(w_);
|
||||
int ddaaddadx_ = HI(w_);
|
||||
if (ddaddadx_) return false;
|
||||
if (adaaddadx_ >= 0) return false;
|
||||
if (ddaddadx_)
|
||||
return false;
|
||||
if (adaaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(adaaddadx_); // (W)
|
||||
int aadaaddadx_ = LO(w_);
|
||||
int dadaaddadx_ = HI(w_);
|
||||
if (aadaddadx_ != kLambda) return false;
|
||||
if (ddaaddadx_ >= 0) return false;
|
||||
if (aadaddadx_ != kLambda)
|
||||
return false;
|
||||
if (ddaaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(ddaaddadx_); // ((W W))
|
||||
int addaaddadx_ = LO(w_);
|
||||
int dddaaddadx_ = HI(w_);
|
||||
if (dadaddadx_ >= 0) return false;
|
||||
if (dadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(dadaddadx_); // ((V) (N (λ M ((V V) . M))))
|
||||
int adadaddadx_ = LO(w_);
|
||||
int ddadaddadx_ = HI(w_);
|
||||
int W = aadaaddadx_;
|
||||
if (W <= 0) return false;
|
||||
if (adadaddadx_ >= 0) return false;
|
||||
if (W <= 0)
|
||||
return false;
|
||||
if (adadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(adadaddadx_); // (V)
|
||||
int aadadaddadx_ = LO(w_);
|
||||
int dadadaddadx_ = HI(w_);
|
||||
if (addaaddadx_ >= 0) return false;
|
||||
if (addaaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(addaaddadx_); // (W W)
|
||||
int aaddaaddadx_ = LO(w_);
|
||||
int daddaaddadx_ = HI(w_);
|
||||
if (ddadaddadx_ >= 0) return false;
|
||||
if (ddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(ddadaddadx_); // ((N (λ M ((V V) . M))))
|
||||
int addadaddadx_ = LO(w_);
|
||||
int dddadaddadx_ = HI(w_);
|
||||
if (dadaaddadx_) return false;
|
||||
if (dadaaddadx_)
|
||||
return false;
|
||||
int V = aadadaddadx_;
|
||||
if (V <= 0) return false;
|
||||
if (dddaaddadx_) return false;
|
||||
if (addadaddadx_ >= 0) return false;
|
||||
if (V <= 0)
|
||||
return false;
|
||||
if (dddaaddadx_)
|
||||
return false;
|
||||
if (addadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(addadaddadx_); // (N (λ M ((V V) . M)))
|
||||
int aaddadaddadx_ = LO(w_);
|
||||
int daddadaddadx_ = HI(w_);
|
||||
if (aaddaaddadx_ != W) return false;
|
||||
if (dadadaddadx_) return false;
|
||||
if (daddaaddadx_ >= 0) return false;
|
||||
if (aaddaaddadx_ != W)
|
||||
return false;
|
||||
if (dadadaddadx_)
|
||||
return false;
|
||||
if (daddaaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(daddaaddadx_); // (W)
|
||||
int adaddaaddadx_ = LO(w_);
|
||||
int ddaddaaddadx_ = HI(w_);
|
||||
if (dddadaddadx_) return false;
|
||||
if (adaddaaddadx_ != W) return false;
|
||||
if (aaddadaddadx_ != N) return false;
|
||||
if (ddaddaaddadx_) return false;
|
||||
if (daddadaddadx_ >= 0) return false;
|
||||
if (dddadaddadx_)
|
||||
return false;
|
||||
if (adaddaaddadx_ != W)
|
||||
return false;
|
||||
if (aaddadaddadx_ != N)
|
||||
return false;
|
||||
if (ddaddaaddadx_)
|
||||
return false;
|
||||
if (daddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(daddadaddadx_); // ((λ M ((V V) . M)))
|
||||
int adaddadaddadx_ = LO(w_);
|
||||
int ddaddadaddadx_ = HI(w_);
|
||||
if (adaddadaddadx_ >= 0) return false;
|
||||
if (adaddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(adaddadaddadx_); // (λ M ((V V) . M))
|
||||
int aadaddadaddadx_ = LO(w_);
|
||||
int dadaddadaddadx_ = HI(w_);
|
||||
if (ddaddadaddadx_) return false;
|
||||
if (aadaddadaddadx_ != kLambda) return false;
|
||||
if (dadaddadaddadx_ >= 0) return false;
|
||||
if (ddaddadaddadx_)
|
||||
return false;
|
||||
if (aadaddadaddadx_ != kLambda)
|
||||
return false;
|
||||
if (dadaddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(dadaddadaddadx_); // (M ((V V) . M))
|
||||
int adadaddadaddadx_ = LO(w_);
|
||||
int ddadaddadaddadx_ = HI(w_);
|
||||
int M = adadaddadaddadx_;
|
||||
if (M <= 0) return false;
|
||||
if (ddadaddadaddadx_ >= 0) return false;
|
||||
if (M <= 0)
|
||||
return false;
|
||||
if (ddadaddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(ddadaddadaddadx_); // (((V V) . M))
|
||||
int addadaddadaddadx_ = LO(w_);
|
||||
int dddadaddadaddadx_ = HI(w_);
|
||||
if (addadaddadaddadx_ >= 0) return false;
|
||||
if (addadaddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(addadaddadaddadx_); // ((V V) . M)
|
||||
int aaddadaddadaddadx_ = LO(w_);
|
||||
int daddadaddadaddadx_ = HI(w_);
|
||||
if (dddadaddadaddadx_) return false;
|
||||
if (aaddadaddadaddadx_ >= 0) return false;
|
||||
if (dddadaddadaddadx_)
|
||||
return false;
|
||||
if (aaddadaddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(aaddadaddadaddadx_); // (V V)
|
||||
int aaaddadaddadaddadx_ = LO(w_);
|
||||
int daaddadaddadaddadx_ = HI(w_);
|
||||
if (daddadaddadaddadx_ != M) return false;
|
||||
if (aaaddadaddadaddadx_ != V) return false;
|
||||
if (daaddadaddadaddadx_ >= 0) return false;
|
||||
if (daddadaddadaddadx_ != M)
|
||||
return false;
|
||||
if (aaaddadaddadaddadx_ != V)
|
||||
return false;
|
||||
if (daaddadaddadaddadx_ >= 0)
|
||||
return false;
|
||||
w_ = Get(daaddadaddadaddadx_); // (V)
|
||||
int adaaddadaddadaddadx_ = LO(w_);
|
||||
int ddaaddadaddadaddadx_ = HI(w_);
|
||||
if (adaaddadaddadaddadx_ != V) return false;
|
||||
if (ddaaddadaddadaddadx_) return false;
|
||||
if (adaaddadaddadaddadx_ != V)
|
||||
return false;
|
||||
if (ddaaddadaddadaddadx_)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,14 +21,18 @@
|
|||
bool MakesClosures(int x) {
|
||||
int h;
|
||||
if (x < 0 && (h = Car(x)) != kQuote && h != kClosure) {
|
||||
if (h == kMacro) return true;
|
||||
if (h == kLambda) return true;
|
||||
if (h == kMacro)
|
||||
return true;
|
||||
if (h == kLambda)
|
||||
return true;
|
||||
if (h == kCond) {
|
||||
while ((x = Cdr(x)) < 0) {
|
||||
if ((h = Car(x)) < 0) {
|
||||
if (MakesClosures(Car(h))) return true;
|
||||
if (MakesClosures(Car(h)))
|
||||
return true;
|
||||
if ((h = Cdr(h)) < 0) {
|
||||
if (MakesClosures(Car(h))) return true;
|
||||
if (MakesClosures(Car(h)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
#include "tool/plinko/lib/plinko.h"
|
||||
|
||||
int Pairlis(int x, int y, int a) {
|
||||
if (!x) return a;
|
||||
if (x > 0) return Alist(x, y, a);
|
||||
if (!x)
|
||||
return a;
|
||||
if (x > 0)
|
||||
return Alist(x, y, a);
|
||||
if (y <= 0) {
|
||||
a = pairlis(Cdr(x), Cdr(y), a);
|
||||
return Car(x) ? pairlis(Car(x), Car(y), a) : a;
|
||||
|
|
|
@ -28,9 +28,12 @@
|
|||
nosideeffect int CountSimpleParameters(int x) {
|
||||
int i;
|
||||
for (i = 0; x; ++i, x = Cdr(x)) {
|
||||
if (x > 0) return -1; // variadic args aren't simple
|
||||
if (!Car(x)) return -1; // nil parameters aren't simple
|
||||
if (Car(x) < 0) return -1; // destructured parameters aren't simple
|
||||
if (x > 0)
|
||||
return -1; // variadic args aren't simple
|
||||
if (!Car(x))
|
||||
return -1; // nil parameters aren't simple
|
||||
if (Car(x) < 0)
|
||||
return -1; // destructured parameters aren't simple
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -38,157 +41,201 @@ nosideeffect int CountSimpleParameters(int x) {
|
|||
nosideeffect int CountSimpleArguments(int x) {
|
||||
int i;
|
||||
for (i = 0; x; ++i, x = Cdr(x)) {
|
||||
if (x > 0) return -1; // apply isn't simple
|
||||
if (x > 0)
|
||||
return -1; // apply isn't simple
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static dword PlanQuote(int e, int a, int s) {
|
||||
if (Cdr(e) >= 0) React(e, e, kQuote); // one normal parameter required
|
||||
if (Cdr(e) >= 0)
|
||||
React(e, e, kQuote); // one normal parameter required
|
||||
return MAKE(DF(DispatchQuote), Cadr(e)); // >1 prms is sectorlisp comment
|
||||
}
|
||||
|
||||
static dword PlanCar(int e, int a, int s) {
|
||||
if (!Cdr(e)) return DF(DispatchNil); // (⍅) ⟺ (⍅ ⊥)
|
||||
if (Cddr(e)) React(e, e, kCar); // too many args
|
||||
if (!Cadr(e)) return DF(DispatchNil);
|
||||
if (!Cdr(e))
|
||||
return DF(DispatchNil); // (⍅) ⟺ (⍅ ⊥)
|
||||
if (Cddr(e))
|
||||
React(e, e, kCar); // too many args
|
||||
if (!Cadr(e))
|
||||
return DF(DispatchNil);
|
||||
return MAKE(DF(DispatchCar), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanCdr(int e, int a, int s) {
|
||||
if (!Cdr(e)) return DF(DispatchNil); // (⍆) ⟺ (⍆ ⊥)
|
||||
if (Cddr(e)) React(e, e, kCdr); // too many args
|
||||
if (!ARG1(e)) return DF(DispatchNil);
|
||||
if (!Cdr(e))
|
||||
return DF(DispatchNil); // (⍆) ⟺ (⍆ ⊥)
|
||||
if (Cddr(e))
|
||||
React(e, e, kCdr); // too many args
|
||||
if (!ARG1(e))
|
||||
return DF(DispatchNil);
|
||||
return MAKE(DF(DispatchCdr), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanAtom(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 1) React(e, e, kAtom);
|
||||
if (CountSimpleArguments(Cdr(e)) != 1)
|
||||
React(e, e, kAtom);
|
||||
return MAKE(DF(DispatchAtom), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanEq(int e, int a, int s) {
|
||||
int n = CountSimpleArguments(Cdr(e));
|
||||
if (n != 2 && n != 1) React(e, e, kAtom); // (≡ 𝑥) is our (null 𝑥)
|
||||
if (n != 2 && n != 1)
|
||||
React(e, e, kAtom); // (≡ 𝑥) is our (null 𝑥)
|
||||
return MAKE(DF(DispatchEq), Caddr(e));
|
||||
}
|
||||
|
||||
static dword PlanCmp(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 2) React(e, e, kCmp);
|
||||
if (CountSimpleArguments(Cdr(e)) != 2)
|
||||
React(e, e, kCmp);
|
||||
return MAKE(DF(DispatchCmp), Caddr(e));
|
||||
}
|
||||
|
||||
static dword PlanOrder(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 2) React(e, e, kOrder);
|
||||
if (CountSimpleArguments(Cdr(e)) != 2)
|
||||
React(e, e, kOrder);
|
||||
return MAKE(DF(DispatchOrder), Caddr(e));
|
||||
}
|
||||
|
||||
static dword PlanCons(int e, int a, int s) {
|
||||
int p = CountSimpleArguments(Cdr(e));
|
||||
if (p == -1) Error("cons dot arg");
|
||||
if (p > 2) Error("too many args");
|
||||
if (p == -1)
|
||||
Error("cons dot arg");
|
||||
if (p > 2)
|
||||
Error("too many args");
|
||||
return MAKE(DF(DispatchCons), Caddr(e));
|
||||
}
|
||||
|
||||
static dword PlanLambda(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) == -1) Error("bad lambda: %S", e);
|
||||
if (CountSimpleArguments(Cdr(e)) == -1)
|
||||
Error("bad lambda: %S", e);
|
||||
return DF(DispatchLambda);
|
||||
}
|
||||
|
||||
static dword PlanCond(int e, int a, int s) {
|
||||
int x;
|
||||
if (!Cdr(e)) return DF(DispatchNil); // (ζ) ⟺ ⊥
|
||||
if (!Cdr(e))
|
||||
return DF(DispatchNil); // (ζ) ⟺ ⊥
|
||||
for (x = e; (x = Cdr(x));) {
|
||||
if (x > 0) React(e, e, kCond); // (ζ . 𝑣) not allowed
|
||||
if (Car(x) >= 0) React(e, e, kCond); // (ζ 𝑣) not allowed
|
||||
if (Cdr(Car(x)) > 0) React(e, e, kCond); // (ζ (𝑥 . 𝑣)) not allowed
|
||||
if (x > 0)
|
||||
React(e, e, kCond); // (ζ . 𝑣) not allowed
|
||||
if (Car(x) >= 0)
|
||||
React(e, e, kCond); // (ζ 𝑣) not allowed
|
||||
if (Cdr(Car(x)) > 0)
|
||||
React(e, e, kCond); // (ζ (𝑥 . 𝑣)) not allowed
|
||||
}
|
||||
return MAKE(DF(DispatchCond), Cdr(e));
|
||||
}
|
||||
|
||||
static dword PlanProgn(int e, int a, int s) {
|
||||
if (!Cdr(e)) return DF(DispatchNil); // (progn) ⟺ ⊥
|
||||
if (CountSimpleArguments(Cdr(e)) == -1) React(e, e, kProgn);
|
||||
if (!Cdr(e))
|
||||
return DF(DispatchNil); // (progn) ⟺ ⊥
|
||||
if (CountSimpleArguments(Cdr(e)) == -1)
|
||||
React(e, e, kProgn);
|
||||
return MAKE(DF(DispatchProgn), Cdr(e));
|
||||
}
|
||||
|
||||
static dword PlanQuiet(int e, int a, int s) {
|
||||
if (Cdr(e) > 0) React(e, e, kQuiet); // apply not allowed
|
||||
if (!Cdr(e)) React(e, e, kQuiet); // zero args not allowed
|
||||
if (Cdr(Cdr(e))) React(e, e, kQuiet); // >1 args not allowed
|
||||
if (Cdr(e) > 0)
|
||||
React(e, e, kQuiet); // apply not allowed
|
||||
if (!Cdr(e))
|
||||
React(e, e, kQuiet); // zero args not allowed
|
||||
if (Cdr(Cdr(e)))
|
||||
React(e, e, kQuiet); // >1 args not allowed
|
||||
return DF(DispatchQuiet);
|
||||
}
|
||||
|
||||
static dword PlanTrace(int e, int a, int s) {
|
||||
if (Cdr(e) > 0) React(e, e, kTrace); // apply not allowed
|
||||
if (!Cdr(e)) React(e, e, kTrace); // zero args not allowed
|
||||
if (Cdr(Cdr(e))) React(e, e, kTrace); // >1 args not allowed
|
||||
if (Cdr(e) > 0)
|
||||
React(e, e, kTrace); // apply not allowed
|
||||
if (!Cdr(e))
|
||||
React(e, e, kTrace); // zero args not allowed
|
||||
if (Cdr(Cdr(e)))
|
||||
React(e, e, kTrace); // >1 args not allowed
|
||||
return DF(DispatchTrace);
|
||||
}
|
||||
|
||||
static dword PlanFtrace(int e, int a, int s) {
|
||||
if (Cdr(e) > 0) React(e, e, kFtrace); // apply not allowed
|
||||
if (!Cdr(e)) React(e, e, kFtrace); // zero args not allowed
|
||||
if (Cdr(Cdr(e))) React(e, e, kFtrace); // >1 args not allowed
|
||||
if (Cdr(e) > 0)
|
||||
React(e, e, kFtrace); // apply not allowed
|
||||
if (!Cdr(e))
|
||||
React(e, e, kFtrace); // zero args not allowed
|
||||
if (Cdr(Cdr(e)))
|
||||
React(e, e, kFtrace); // >1 args not allowed
|
||||
return DF(DispatchFtrace);
|
||||
}
|
||||
|
||||
static dword PlanFunction(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 1) Raise(kFunction);
|
||||
if (CountSimpleArguments(Cdr(e)) != 1)
|
||||
Raise(kFunction);
|
||||
return MAKE(DF(DispatchFunction), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanBeta(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 1) Raise(kBeta);
|
||||
if (CountSimpleArguments(Cdr(e)) != 1)
|
||||
Raise(kBeta);
|
||||
return MAKE(DF(DispatchBeta), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanIgnore(int e, int a, int s) {
|
||||
if (!Cdr(e)) return DF(DispatchIgnore0);
|
||||
if (Cdr(e) > 0) React(e, e, kIgnore); // apply not allowed
|
||||
if (!Cdr(e)) React(e, e, kIgnore); // zero args not allowed
|
||||
if (Cdr(Cdr(e))) React(e, e, kIgnore); // >1 args not allowed
|
||||
if (!Cdr(e))
|
||||
return DF(DispatchIgnore0);
|
||||
if (Cdr(e) > 0)
|
||||
React(e, e, kIgnore); // apply not allowed
|
||||
if (!Cdr(e))
|
||||
React(e, e, kIgnore); // zero args not allowed
|
||||
if (Cdr(Cdr(e)))
|
||||
React(e, e, kIgnore); // >1 args not allowed
|
||||
return DF(DispatchIgnore1);
|
||||
}
|
||||
|
||||
static dword PlanExpand(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 1) React(e, e, kExpand);
|
||||
if (CountSimpleArguments(Cdr(e)) != 1)
|
||||
React(e, e, kExpand);
|
||||
return MAKE(DF(DispatchExpand), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanPrint(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) == -1) React(e, e, kPrint);
|
||||
if (CountSimpleArguments(Cdr(e)) == -1)
|
||||
React(e, e, kPrint);
|
||||
return DF(DispatchPrint);
|
||||
}
|
||||
|
||||
static dword PlanGensym(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e))) React(e, e, kGensym);
|
||||
if (CountSimpleArguments(Cdr(e)))
|
||||
React(e, e, kGensym);
|
||||
return DF(DispatchGensym);
|
||||
}
|
||||
|
||||
static dword PlanPprint(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) == -1) React(e, e, kPprint);
|
||||
if (CountSimpleArguments(Cdr(e)) == -1)
|
||||
React(e, e, kPprint);
|
||||
return DF(DispatchPprint);
|
||||
}
|
||||
|
||||
static dword PlanPrintheap(int e, int a, int s) {
|
||||
int p = CountSimpleArguments(Cdr(e));
|
||||
if (p != 0 && p != 1) React(e, e, kPrintheap);
|
||||
if (p != 0 && p != 1)
|
||||
React(e, e, kPrintheap);
|
||||
return DF(DispatchPrintheap);
|
||||
}
|
||||
|
||||
static dword PlanGc(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) != 1) React(e, e, kGc);
|
||||
if (CountSimpleArguments(Cdr(e)) != 1)
|
||||
React(e, e, kGc);
|
||||
return MAKE(DF(DispatchGc), Cadr(e));
|
||||
}
|
||||
|
||||
static dword PlanPrinc(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) == -1) React(e, e, kPrinc);
|
||||
if (CountSimpleArguments(Cdr(e)) == -1)
|
||||
React(e, e, kPrinc);
|
||||
return DF(DispatchPrinc);
|
||||
}
|
||||
|
||||
static dword PlanFlush(int e, int a, int s) {
|
||||
if (CountSimpleArguments(Cdr(e)) == -1) React(e, e, kFlush);
|
||||
if (CountSimpleArguments(Cdr(e)) == -1)
|
||||
React(e, e, kFlush);
|
||||
return DF(DispatchFlush);
|
||||
}
|
||||
|
||||
|
@ -197,12 +244,14 @@ static dword PlanError(int e, int a, int s) {
|
|||
}
|
||||
|
||||
static dword PlanExit(int e, int a, int s) {
|
||||
if (Cdr(e)) React(e, e, kExit);
|
||||
if (Cdr(e))
|
||||
React(e, e, kExit);
|
||||
return DF(DispatchExit);
|
||||
}
|
||||
|
||||
static dword PlanRead(int e, int a, int s) {
|
||||
if (Cdr(e)) React(e, e, kRead);
|
||||
if (Cdr(e))
|
||||
React(e, e, kRead);
|
||||
return DF(DispatchRead);
|
||||
}
|
||||
|
||||
|
@ -216,16 +265,20 @@ static dword PlanClosure(int e, int a, int s) {
|
|||
|
||||
static dword PlanLet(int e, int a, int s) {
|
||||
int n;
|
||||
if ((n = CountSimpleArguments(Cdr(e))) == -1) return DF(DispatchFuncall);
|
||||
if (CountSimpleArguments(Car(e)) < 3) React(e, e, kLambda); // need (λ 𝑥 𝑦)
|
||||
if ((n = CountSimpleArguments(Cdr(e))) == -1)
|
||||
return DF(DispatchFuncall);
|
||||
if (CountSimpleArguments(Car(e)) < 3)
|
||||
React(e, e, kLambda); // need (λ 𝑥 𝑦)
|
||||
switch (CountSimpleParameters(Cadr(Car(e)))) {
|
||||
case -1:
|
||||
return DF(DispatchFuncall);
|
||||
case 0:
|
||||
if (n != 0) Error("let argument count mismatch: %S", e);
|
||||
if (n != 0)
|
||||
Error("let argument count mismatch: %S", e);
|
||||
return MAKE(DF(DispatchShortcut), Caddr(Car(e))); // ((λ ⊥ 𝑦)) becomes 𝑦
|
||||
case 1:
|
||||
if (n != 1) Error("let argument count mismatch: %S", e);
|
||||
if (n != 1)
|
||||
Error("let argument count mismatch: %S", e);
|
||||
return MAKE(DF(DispatchLet1), Cdar(e));
|
||||
default:
|
||||
return MAKE(DF(DispatchFuncall), 0);
|
||||
|
@ -234,37 +287,68 @@ static dword PlanLet(int e, int a, int s) {
|
|||
|
||||
static dontinline dword PlanPrecious(int e, int a, int s, int f) {
|
||||
DCHECK_GT(f, 0);
|
||||
if (f == kCar) return PlanCar(e, a, s);
|
||||
if (f == kCdr) return PlanCdr(e, a, s);
|
||||
if (f == kGc) return PlanGc(e, a, s);
|
||||
if (f == kEq) return PlanEq(e, a, s);
|
||||
if (f == kCmp) return PlanCmp(e, a, s);
|
||||
if (f == kBeta) return PlanBeta(e, a, s);
|
||||
if (f == kCond) return PlanCond(e, a, s);
|
||||
if (f == kAtom) return PlanAtom(e, a, s);
|
||||
if (f == kCons) return PlanCons(e, a, s);
|
||||
if (f == kExit) return PlanExit(e, a, s);
|
||||
if (f == kRead) return PlanRead(e, a, s);
|
||||
if (f == kOrder) return PlanOrder(e, a, s);
|
||||
if (f == kQuote) return PlanQuote(e, a, s);
|
||||
if (f == kProgn) return PlanProgn(e, a, s);
|
||||
if (f == kQuiet) return PlanQuiet(e, a, s);
|
||||
if (f == kTrace) return PlanTrace(e, a, s);
|
||||
if (f == kPrint) return PlanPrint(e, a, s);
|
||||
if (f == kPrinc) return PlanPrinc(e, a, s);
|
||||
if (f == kFlush) return PlanFlush(e, a, s);
|
||||
if (f == kError) return PlanError(e, a, s);
|
||||
if (f == kMacro) return PlanLambda(e, a, s);
|
||||
if (f == kFtrace) return PlanFtrace(e, a, s);
|
||||
if (f == kLambda) return PlanLambda(e, a, s);
|
||||
if (f == kGensym) return PlanGensym(e, a, s);
|
||||
if (f == kPprint) return PlanPprint(e, a, s);
|
||||
if (f == kIgnore) return PlanIgnore(e, a, s);
|
||||
if (f == kExpand) return PlanExpand(e, a, s);
|
||||
if (f == kDefine) return PlanDefine(e, a, s);
|
||||
if (f == kClosure) return PlanClosure(e, a, s);
|
||||
if (f == kFunction) return PlanFunction(e, a, s);
|
||||
if (f == kPrintheap) return PlanPrintheap(e, a, s);
|
||||
if (f == kCar)
|
||||
return PlanCar(e, a, s);
|
||||
if (f == kCdr)
|
||||
return PlanCdr(e, a, s);
|
||||
if (f == kGc)
|
||||
return PlanGc(e, a, s);
|
||||
if (f == kEq)
|
||||
return PlanEq(e, a, s);
|
||||
if (f == kCmp)
|
||||
return PlanCmp(e, a, s);
|
||||
if (f == kBeta)
|
||||
return PlanBeta(e, a, s);
|
||||
if (f == kCond)
|
||||
return PlanCond(e, a, s);
|
||||
if (f == kAtom)
|
||||
return PlanAtom(e, a, s);
|
||||
if (f == kCons)
|
||||
return PlanCons(e, a, s);
|
||||
if (f == kExit)
|
||||
return PlanExit(e, a, s);
|
||||
if (f == kRead)
|
||||
return PlanRead(e, a, s);
|
||||
if (f == kOrder)
|
||||
return PlanOrder(e, a, s);
|
||||
if (f == kQuote)
|
||||
return PlanQuote(e, a, s);
|
||||
if (f == kProgn)
|
||||
return PlanProgn(e, a, s);
|
||||
if (f == kQuiet)
|
||||
return PlanQuiet(e, a, s);
|
||||
if (f == kTrace)
|
||||
return PlanTrace(e, a, s);
|
||||
if (f == kPrint)
|
||||
return PlanPrint(e, a, s);
|
||||
if (f == kPrinc)
|
||||
return PlanPrinc(e, a, s);
|
||||
if (f == kFlush)
|
||||
return PlanFlush(e, a, s);
|
||||
if (f == kError)
|
||||
return PlanError(e, a, s);
|
||||
if (f == kMacro)
|
||||
return PlanLambda(e, a, s);
|
||||
if (f == kFtrace)
|
||||
return PlanFtrace(e, a, s);
|
||||
if (f == kLambda)
|
||||
return PlanLambda(e, a, s);
|
||||
if (f == kGensym)
|
||||
return PlanGensym(e, a, s);
|
||||
if (f == kPprint)
|
||||
return PlanPprint(e, a, s);
|
||||
if (f == kIgnore)
|
||||
return PlanIgnore(e, a, s);
|
||||
if (f == kExpand)
|
||||
return PlanExpand(e, a, s);
|
||||
if (f == kDefine)
|
||||
return PlanDefine(e, a, s);
|
||||
if (f == kClosure)
|
||||
return PlanClosure(e, a, s);
|
||||
if (f == kFunction)
|
||||
return PlanFunction(e, a, s);
|
||||
if (f == kPrintheap)
|
||||
return PlanPrintheap(e, a, s);
|
||||
if (!a) {
|
||||
Push(e);
|
||||
Push(f);
|
||||
|
@ -280,26 +364,34 @@ dontinline dword Plan(int e, int a, int s) {
|
|||
if ((x1 = IsCar(e))) {
|
||||
if ((x2 = IsCar(x1))) {
|
||||
if ((x3 = IsCar(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCaaaar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCaaadr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCaaaar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCaaadr), x4);
|
||||
return MAKE(DF(DispatchCaaar), x3);
|
||||
}
|
||||
if ((x3 = IsCdr(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCaadar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCaaddr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCaadar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCaaddr), x4);
|
||||
return MAKE(DF(DispatchCaaar), x3);
|
||||
}
|
||||
return MAKE(DF(DispatchCaar), x2);
|
||||
}
|
||||
if ((x2 = IsCdr(x1))) {
|
||||
if ((x3 = IsCar(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCadaar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCadadr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCadaar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCadadr), x4);
|
||||
return MAKE(DF(DispatchCadar), x3);
|
||||
}
|
||||
if ((x3 = IsCdr(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCaddar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCadddr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCaddar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCadddr), x4);
|
||||
return MAKE(DF(DispatchCaddr), x3);
|
||||
}
|
||||
return MAKE(DF(DispatchCadr), x2);
|
||||
|
@ -310,26 +402,34 @@ dontinline dword Plan(int e, int a, int s) {
|
|||
if ((x1 = IsCdr(e))) {
|
||||
if ((x2 = IsCar(x1))) {
|
||||
if ((x3 = IsCar(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCdaaar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCdaadr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCdaaar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCdaadr), x4);
|
||||
return MAKE(DF(DispatchCdaar), x3);
|
||||
}
|
||||
if ((x3 = IsCdr(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCdadar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCdaddr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCdadar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCdaddr), x4);
|
||||
return MAKE(DF(DispatchCdadr), x3);
|
||||
}
|
||||
return MAKE(DF(DispatchCdar), x2);
|
||||
}
|
||||
if ((x2 = IsCdr(x1))) {
|
||||
if ((x3 = IsCar(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCddaar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCddadr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCddaar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCddadr), x4);
|
||||
return MAKE(DF(DispatchCddar), x3);
|
||||
}
|
||||
if ((x3 = IsCdr(x2))) {
|
||||
if ((x4 = IsCar(x3))) return MAKE(DF(DispatchCdddar), x4);
|
||||
if ((x4 = IsCdr(x3))) return MAKE(DF(DispatchCddddr), x4);
|
||||
if ((x4 = IsCar(x3)))
|
||||
return MAKE(DF(DispatchCdddar), x4);
|
||||
if ((x4 = IsCdr(x3)))
|
||||
return MAKE(DF(DispatchCddddr), x4);
|
||||
return MAKE(DF(DispatchCdddr), x3);
|
||||
}
|
||||
return MAKE(DF(DispatchCddr), x2);
|
||||
|
|
|
@ -83,8 +83,10 @@ static void Backtrace(int S) {
|
|||
|
||||
forceinline bool ShouldIgnoreGarbage(int A) {
|
||||
static unsigned cadence;
|
||||
if (DEBUG_GARBAGE) return false;
|
||||
if (!(++cadence & AVERSIVENESS)) return false;
|
||||
if (DEBUG_GARBAGE)
|
||||
return false;
|
||||
if (!(++cadence & AVERSIVENESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -101,13 +103,16 @@ static relegated dontinline int ErrorExpr(void) {
|
|||
}
|
||||
|
||||
static int Order(int x, int y) {
|
||||
if (x < y) return -1;
|
||||
if (x > y) return +1;
|
||||
if (x < y)
|
||||
return -1;
|
||||
if (x > y)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Append(int x, int y) {
|
||||
if (!x) return y;
|
||||
if (!x)
|
||||
return y;
|
||||
return Cons(Car(x), Append(Cdr(x), y));
|
||||
}
|
||||
|
||||
|
@ -129,21 +134,25 @@ static int ReconstructAlist(int a) {
|
|||
static bool AtomEquals(int x, const char *s) {
|
||||
dword t;
|
||||
do {
|
||||
if (!*s) return false;
|
||||
if (!*s)
|
||||
return false;
|
||||
t = Get(x);
|
||||
if (LO(t) != *s++) return false; // xxx: ascii
|
||||
if (LO(t) != *s++)
|
||||
return false; // xxx: ascii
|
||||
} while ((x = HI(t)) != TERM);
|
||||
return !*s;
|
||||
}
|
||||
|
||||
static pureconst int LastCons(int x) {
|
||||
while (Cdr(x)) x = Cdr(x);
|
||||
while (Cdr(x))
|
||||
x = Cdr(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
static pureconst int LastChar(int x) {
|
||||
dword e;
|
||||
do e = Get(x);
|
||||
do
|
||||
e = Get(x);
|
||||
while ((x = HI(e)) != TERM);
|
||||
return LO(e);
|
||||
}
|
||||
|
@ -157,13 +166,16 @@ forceinline pureconst bool IsQuote(int x) {
|
|||
}
|
||||
|
||||
static int Quote(int x) {
|
||||
if (IsClosure(x)) return x;
|
||||
if (IsPrecious(x)) return x;
|
||||
if (IsClosure(x))
|
||||
return x;
|
||||
if (IsPrecious(x))
|
||||
return x;
|
||||
return List(kQuote, x);
|
||||
}
|
||||
|
||||
static int QuoteList(int x) {
|
||||
if (!x) return x;
|
||||
if (!x)
|
||||
return x;
|
||||
return Cons(Quote(Car(x)), QuoteList(Cdr(x)));
|
||||
}
|
||||
|
||||
|
@ -171,7 +183,8 @@ static int GetAtom(const char *s) {
|
|||
int x, y;
|
||||
ax = y = TERM;
|
||||
x = *s++ & 255;
|
||||
if (*s) y = GetAtom(s);
|
||||
if (*s)
|
||||
y = GetAtom(s);
|
||||
return Intern(x, y);
|
||||
}
|
||||
|
||||
|
@ -182,7 +195,8 @@ static int Gensym(void) {
|
|||
n = 0;
|
||||
x = g++;
|
||||
B[n++] = L'G';
|
||||
do B[n++] = L'0' + (x & 7);
|
||||
do
|
||||
B[n++] = L'0' + (x & 7);
|
||||
while ((x >>= 3));
|
||||
B[n] = 0;
|
||||
for (a = 1, b = n - 1; a < b; ++a, --b) {
|
||||
|
@ -195,8 +209,10 @@ static int Gensym(void) {
|
|||
|
||||
static nosideeffect bool Member(int v, int x) {
|
||||
while (x) {
|
||||
if (x > 0) return v == x;
|
||||
if (v == Car(x)) return true;
|
||||
if (x > 0)
|
||||
return v == x;
|
||||
if (v == Car(x))
|
||||
return true;
|
||||
x = Cdr(x);
|
||||
}
|
||||
return false;
|
||||
|
@ -216,8 +232,10 @@ static int GetBindings(int x, int a) {
|
|||
|
||||
static int Lambda(int e, int a, dword p1, dword p2) {
|
||||
int u;
|
||||
if (p1) a = Alist(LO(p1), HI(p1), a);
|
||||
if (p2) a = Alist(LO(p2), HI(p2), a);
|
||||
if (p1)
|
||||
a = Alist(LO(p1), HI(p1), a);
|
||||
if (p2)
|
||||
a = Alist(LO(p2), HI(p2), a);
|
||||
if (DEBUG_CLOSURE || logc) {
|
||||
u = FindFreeVariables(e, 0, 0);
|
||||
a = GetBindings(u, a);
|
||||
|
@ -227,8 +245,10 @@ static int Lambda(int e, int a, dword p1, dword p2) {
|
|||
|
||||
static int Function(int e, int a, dword p1, dword p2) {
|
||||
int u;
|
||||
if (e < 0 && Car(e) == kLambda) e = Lambda(e, a, p1, p2);
|
||||
if (e >= 0 || Car(e) != kClosure) Error("not a closure");
|
||||
if (e < 0 && Car(e) == kLambda)
|
||||
e = Lambda(e, a, p1, p2);
|
||||
if (e >= 0 || Car(e) != kClosure)
|
||||
Error("not a closure");
|
||||
a = Cddr(e);
|
||||
e = Cadr(e);
|
||||
u = FindFreeVariables(e, 0, 0);
|
||||
|
@ -421,8 +441,10 @@ struct T DispatchLookup(dword ea, dword tm, dword r, dword p1, dword p2,
|
|||
DCHECK(!IsPrecious(e));
|
||||
DCHECK_GT(e, 0);
|
||||
DCHECK_LE(a, 0);
|
||||
if (LO(p1) == LO(ea)) return Ret(MAKE(HI(p1), 0), tm, r);
|
||||
if (LO(p2) == LO(ea)) return Ret(MAKE(HI(p2), 0), tm, r);
|
||||
if (LO(p1) == LO(ea))
|
||||
return Ret(MAKE(HI(p1), 0), tm, r);
|
||||
if (LO(p2) == LO(ea))
|
||||
return Ret(MAKE(HI(p2), 0), tm, r);
|
||||
if ((kv = Assoc(e, a))) {
|
||||
return Ret(MAKE(Cdr(kv), 0), tm, r); // (eval 𝑘 (…(𝑘 𝑣)…)) ⟹ 𝑣
|
||||
} else {
|
||||
|
@ -473,10 +495,12 @@ struct T DispatchOrder(dword ea, dword tm, dword r, dword p1, dword p2,
|
|||
struct T DispatchCons(dword ea, dword tm, dword r, dword p1, dword p2,
|
||||
dword d) {
|
||||
int x;
|
||||
if (cx < cHeap) cHeap = cx;
|
||||
if (cx < cHeap)
|
||||
cHeap = cx;
|
||||
x = Car(Cdr(LO(ea)));
|
||||
x = FasterRecurse(x, HI(ea), p1, p2);
|
||||
if (!HI(d)) return Ret(MAKE(Cons(x, 0), 0), tm, r);
|
||||
if (!HI(d))
|
||||
return Ret(MAKE(Cons(x, 0), 0), tm, r);
|
||||
if (~r & NEED_POP) {
|
||||
r |= NEED_POP;
|
||||
Push(LO(ea));
|
||||
|
@ -720,7 +744,8 @@ struct T DispatchExpand(dword ea, dword tm, dword r, dword p1, dword p2,
|
|||
}
|
||||
|
||||
static int GrabArgs(int x, int a, dword p1, dword p2) {
|
||||
if (x >= 0) return x;
|
||||
if (x >= 0)
|
||||
return x;
|
||||
return Cons(recurse(MAKE(Car(x), a), p1, p2), GrabArgs(Cdr(x), a, p1, p2));
|
||||
}
|
||||
|
||||
|
@ -991,7 +1016,8 @@ int Plinko(int argc, char *argv[]) {
|
|||
kTail[5] = DispatchTailGc;
|
||||
kTail[6] = DispatchTailImpossible;
|
||||
kTail[7] = DispatchTailTmcGc;
|
||||
if (trace) EnableTracing();
|
||||
if (trace)
|
||||
EnableTracing();
|
||||
|
||||
cx = -1;
|
||||
cFrost = cx;
|
||||
|
@ -1006,7 +1032,8 @@ int Plinko(int argc, char *argv[]) {
|
|||
if (!(x = setjmp(crash))) {
|
||||
x = Read(0);
|
||||
x = expand(x, globals);
|
||||
if (stats) ResetStats();
|
||||
if (stats)
|
||||
ResetStats();
|
||||
if (x < 0 && Car(x) == kDefine) {
|
||||
globals = Define(x, globals);
|
||||
cFrost = cx;
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
static int CopyTree(int x) {
|
||||
int a, b;
|
||||
if (x >= 0) return x;
|
||||
if (x >= 0)
|
||||
return x;
|
||||
b = CopyTree(Cdr(x));
|
||||
a = CopyTree(Car(x));
|
||||
return Cons(a, b);
|
||||
|
@ -33,7 +34,8 @@ static int CopyTree(int x) {
|
|||
|
||||
static int PreplanCond(int e, int a, int s) {
|
||||
int f, g;
|
||||
if (!(e = Cdr(e))) return 0;
|
||||
if (!(e = Cdr(e)))
|
||||
return 0;
|
||||
if ((f = Car(e)) < 0) {
|
||||
if ((g = Cdr(f)) < 0) {
|
||||
f = List(Preplan(Car(f), a, s), Preplan(Car(g), a, s));
|
||||
|
@ -45,14 +47,16 @@ static int PreplanCond(int e, int a, int s) {
|
|||
}
|
||||
|
||||
static int PreplanList(int e, int a, int s) {
|
||||
if (e >= 0) return e;
|
||||
if (e >= 0)
|
||||
return e;
|
||||
return Cons(Preplan(Car(e), a, s), PreplanList(Cdr(e), a, s));
|
||||
}
|
||||
|
||||
int Preplan(int e, int a, int s) {
|
||||
int f, x;
|
||||
struct qword q;
|
||||
if (e >= 0) return e;
|
||||
if (e >= 0)
|
||||
return e;
|
||||
f = Car(e);
|
||||
if (f != kQuote) {
|
||||
if (f == kClosure) {
|
||||
|
|
|
@ -85,15 +85,18 @@ static void PrettyPrintList(int fd, int x, int n) {
|
|||
if (y >= 0) {
|
||||
argwidth += PrintSpace(fd);
|
||||
argwidth += PrintAtom(fd, y);
|
||||
if (!once) n += argwidth;
|
||||
if (!once)
|
||||
n += argwidth;
|
||||
} else {
|
||||
if (once && (y < 0 || mode)) {
|
||||
mode = 1;
|
||||
PrintNewline(fd);
|
||||
if (depth >= 0) PrintDepth(fd, depth);
|
||||
if (depth >= 0)
|
||||
PrintDepth(fd, depth);
|
||||
PrintIndent(fd, n);
|
||||
} else {
|
||||
if (y < 0) mode = 1;
|
||||
if (y < 0)
|
||||
mode = 1;
|
||||
PrintSpace(fd);
|
||||
}
|
||||
once = 1;
|
||||
|
|
|
@ -25,15 +25,18 @@ int PrintChar(int fd, int s) {
|
|||
unsigned c;
|
||||
int d, e, i, n;
|
||||
c = s & 0xffffffff;
|
||||
if (bp[fd] + 6 > sizeof(g_buffer[fd])) Flush(fd);
|
||||
if (bp[fd] + 6 > sizeof(g_buffer[fd]))
|
||||
Flush(fd);
|
||||
if (c < 0200) {
|
||||
g_buffer[fd][bp[fd]++] = c;
|
||||
if (c == L'\n') Flush(fd);
|
||||
if (c == L'\n')
|
||||
Flush(fd);
|
||||
} else {
|
||||
d = c;
|
||||
e = kTpEnc[bsrl(d) - 7];
|
||||
i = n = e & 255;
|
||||
do g_buffer[fd][bp[fd] + i--] = 0200 | (d & 077);
|
||||
do
|
||||
g_buffer[fd][bp[fd] + i--] = 0200 | (d & 077);
|
||||
while (d >>= 6, i);
|
||||
g_buffer[fd][bp[fd]] = d | e >> 8;
|
||||
bp[fd] += n + 1;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue