mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Brush up some more code
This commit is contained in:
parent
ee6566a152
commit
a2d269dc38
32 changed files with 251 additions and 335 deletions
Binary file not shown.
Binary file not shown.
|
@ -220,7 +220,7 @@ int unbing(int c) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kCp437i) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if ((kCp437i[m] >> 8) < c) {
|
||||
l = m + 1;
|
||||
} else if ((kCp437i[m] >> 8) > c) {
|
||||
|
|
|
@ -743,7 +743,7 @@ static void __asan_report_memory_origin_image(intptr_t a, int z) {
|
|||
r = n = st->count;
|
||||
k = a - st->addr_base;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (st->symbols[m].y < k) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/midpoint.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
|
||||
noasan unsigned FindMemoryInterval(const struct MemoryIntervals *mm, int x) {
|
||||
|
@ -25,7 +24,7 @@ noasan unsigned FindMemoryInterval(const struct MemoryIntervals *mm, int x) {
|
|||
l = 0;
|
||||
r = mm->i;
|
||||
while (l < r) {
|
||||
m = _midpoint(l, r);
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (mm->p[m].y < x) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -161,7 +161,7 @@ privileged static bool kismapped(int x) {
|
|||
if (kismemtrackhosed()) return false;
|
||||
r = _weaken(_mmi)->i;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (_weaken(_mmi)->p[m].y < x) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_
|
||||
#define COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_
|
||||
#include "libc/assert.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__)
|
||||
/**
|
||||
* Computes `(a + b) / 2` assuming unsigned.
|
||||
*
|
||||
* This implementation is the fastest on AMD Zen architecture.
|
||||
*/
|
||||
#define _midpoint(a, b) \
|
||||
({ \
|
||||
typeof((a) + (b)) a_ = (a); \
|
||||
typeof(a_) b_ = (b); \
|
||||
_unassert(a_ >= 0); \
|
||||
_unassert(b_ >= 0); \
|
||||
asm("add\t%1,%0\n\t" \
|
||||
"rcr\t%0" \
|
||||
: "+r"(a_) \
|
||||
: "r"(b_)); \
|
||||
a_; \
|
||||
})
|
||||
#else
|
||||
/**
|
||||
* Computes `(a + b) / 2` assuming unsigned.
|
||||
*/
|
||||
#define _midpoint(a, b) (((a) & (b)) + ((a) ^ (b)) / 2)
|
||||
#endif /* __GNUC__ && !__STRICT_ANSI__ && x86 */
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_BITS_MIDPOINT_H_ */
|
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/midpoint.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/sortedints.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -28,7 +27,7 @@ bool ContainsInt(const struct SortedInts *t, int k) {
|
|||
l = 0;
|
||||
r = t->n - 1;
|
||||
while (l <= r) {
|
||||
m = _midpoint(l, r);
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (t->p[m] < k) {
|
||||
l = m + 1;
|
||||
} else if (t->p[m] > k) {
|
||||
|
@ -45,7 +44,7 @@ int LeftmostInt(const struct SortedInts *t, int k) {
|
|||
l = 0;
|
||||
r = t->n;
|
||||
while (l < r) {
|
||||
m = _midpoint(l, r);
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (t->p[m] < k) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -41,7 +41,7 @@ dontinstrument privileged int __get_symbol(struct SymbolTable *t, intptr_t a) {
|
|||
r = n = t->count;
|
||||
k = a - t->addr_base;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (t->symbols[m].y < k) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -30,7 +30,8 @@ textwindows int sys_closesocket_nt(struct Fd *fd) {
|
|||
struct SockFd *sockfd;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
free(sockfd);
|
||||
if (__sys_closesocket_nt(fd->handle) != -1) {
|
||||
int rc = __sys_closesocket_nt(fd->handle);
|
||||
if (rc != -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winsockerr();
|
||||
|
|
|
@ -39,7 +39,7 @@ uint32_t crc32c(uint32_t init, const void *data, size_t size) {
|
|||
static uint32_t kCrc32cTab[256];
|
||||
if (!once) {
|
||||
crc32init(kCrc32cTab, 0x82f63b78);
|
||||
once = 0;
|
||||
once = 1;
|
||||
}
|
||||
p = data;
|
||||
pe = p + size;
|
||||
|
|
|
@ -399,7 +399,7 @@ int iswseparator(wint_t c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kCodes) / sizeof(kCodes[0]);
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kCodes[m][1] < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
@ -411,7 +411,7 @@ int iswseparator(wint_t c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kAstralCodes) / sizeof(kAstralCodes[0]);
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kAstralCodes[m][1] < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -24,39 +24,6 @@
|
|||
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
||||
* 2. If SRC is too short, the remainder is zero-filled.
|
||||
*
|
||||
* Please note this function isn't designed to prevent untrustworthy
|
||||
* data from modifying memory without authorization; the memccpy()
|
||||
* function can be used for that purpose.
|
||||
*
|
||||
* Here's an example of the only use case we know of for strncpy:
|
||||
*
|
||||
* static const struct People {
|
||||
* char name[8];
|
||||
* int age;
|
||||
* } kPeople[] = {
|
||||
* {"alice", 29}, //
|
||||
* {"bob", 42}, //
|
||||
* };
|
||||
*
|
||||
* int GetAge(const char *name) {
|
||||
* char k[8];
|
||||
* int m, l, r;
|
||||
* l = 0;
|
||||
* r = ARRAYLEN(kPeople) - 1;
|
||||
* strncpy(k, name, 8);
|
||||
* while (l <= r) {
|
||||
* m = (l + r) >> 1;
|
||||
* if (READ64BE(kPeople[m].name) < READ64BE(k)) {
|
||||
* l = m + 1;
|
||||
* } else if (READ64BE(kPeople[m].name) > READ64BE(k)) {
|
||||
* r = m - 1;
|
||||
* } else {
|
||||
* return kPeople[m].age;
|
||||
* }
|
||||
* }
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* @return dest
|
||||
* @see stpncpy(), memccpy()
|
||||
* @asyncsignalsafe
|
||||
|
|
|
@ -201,7 +201,7 @@ wint_t towlower(wint_t c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kLower) / sizeof(kLower[0]);
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kLower[m].y < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
@ -218,7 +218,7 @@ wint_t towlower(wint_t c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kAstralLower) / sizeof(kAstralLower[0]);
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kAstralLower[m][1] < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -164,7 +164,7 @@ wint_t towupper(wint_t c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kUpper) / sizeof(kUpper[0]);
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kUpper[m].y < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
@ -181,7 +181,7 @@ wint_t towupper(wint_t c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kAstralUpper) / sizeof(kAstralUpper[0]);
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kAstralUpper[m][1] < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
|
@ -119,7 +119,7 @@ static const char *BisectContentType(uint64_t ext) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kContentTypeExtension) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
c = CompareInts(READ64BE(kContentTypeExtension[m].ext), ext);
|
||||
if (c < 0) {
|
||||
l = m + 1;
|
||||
|
|
|
@ -100,7 +100,7 @@ const char *GetHttpReason(int code) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kHttpReason) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kHttpReason[m].code < code) {
|
||||
l = m + 1;
|
||||
} else if (kHttpReason[m].code > code) {
|
||||
|
|
|
@ -43,7 +43,7 @@ static bool BisectNoCompressExts(uint64_t ext) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kNoCompressExts) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (READ64BE(kNoCompressExts[m]) < ext) {
|
||||
l = m + 1;
|
||||
} else if (READ64BE(kNoCompressExts[m]) > ext) {
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/midpoint.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/sortedints.internal.h"
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/midpoint.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
|
@ -67,7 +66,8 @@ TEST(sched_setscheduler, test) {
|
|||
|
||||
TEST(sched_setscheduler, testMidpoint) {
|
||||
if (!CanTuneRealtimeSchedulers()) return;
|
||||
struct sched_param p = {_midpoint(sched_get_priority_min(SCHED_FIFO),
|
||||
sched_get_priority_max(SCHED_FIFO))};
|
||||
struct sched_param p = {(sched_get_priority_min(SCHED_FIFO) +
|
||||
sched_get_priority_max(SCHED_FIFO)) /
|
||||
2};
|
||||
EXPECT_SYS(0, DEFAULT_POLICY, sched_setscheduler(0, SCHED_FIFO, &p));
|
||||
}
|
||||
|
|
8
third_party/chibicc/as.c
vendored
8
third_party/chibicc/as.c
vendored
|
@ -1894,7 +1894,7 @@ static bool Prefix(struct As *a, const char *p, int n) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kPrefix) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
y = READ64BE(kPrefix[m]);
|
||||
if (x < y) {
|
||||
r = m - 1;
|
||||
|
@ -1919,7 +1919,7 @@ static bool FindReg(const char *p, int n, struct Reg *out_reg) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kRegs) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
y = READ64BE(kRegs[m].s);
|
||||
if (x < y) {
|
||||
r = m - 1;
|
||||
|
@ -3740,7 +3740,7 @@ static bool OnDirective8(struct As *a, struct Slice s) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kDirective8) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
y = READ64BE(kDirective8[m].s);
|
||||
if (x < y) {
|
||||
r = m - 1;
|
||||
|
@ -3763,7 +3763,7 @@ static bool OnDirective16(struct As *a, struct Slice s) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kDirective16) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
y = READ128BE(kDirective16[m].s);
|
||||
if (x < y) {
|
||||
r = m - 1;
|
||||
|
|
2
third_party/linenoise/linenoise.c
vendored
2
third_party/linenoise/linenoise.c
vendored
|
@ -313,7 +313,7 @@ static unsigned GetMirror(const unsigned short A[][2], size_t n, unsigned c) {
|
|||
l = 0;
|
||||
r = n - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (A[m][0] < c) {
|
||||
l = m + 1;
|
||||
} else if (A[m][0] > c) {
|
||||
|
|
2
third_party/maxmind/getmetroname.c
vendored
2
third_party/maxmind/getmetroname.c
vendored
|
@ -244,7 +244,7 @@ const char *GetMetroName(int code) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kMetroNames) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kMetroNames[m].code < code) {
|
||||
l = m + 1;
|
||||
} else if (kMetroNames[m].code > code) {
|
||||
|
|
|
@ -3901,7 +3901,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 c)
|
|||
l = 0;
|
||||
r = sizeof(kNumericCodes) / sizeof(kNumericCodes[0]) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kNumericCodes[m] < c) {
|
||||
l = m + 1;
|
||||
} else if (kNumericCodes[m] > c) {
|
||||
|
@ -3914,7 +3914,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 c)
|
|||
l = 0;
|
||||
r = sizeof(kNumericAstralCodes) / sizeof(kNumericAstralCodes[0]) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kNumericAstralCodes[m] < c) {
|
||||
l = m + 1;
|
||||
} else if (kNumericAstralCodes[m] > c) {
|
||||
|
|
|
@ -456,7 +456,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 c)
|
|||
l = 0;
|
||||
r = sizeof(kNumericCodes) / sizeof(kNumericCodes[0]) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kNumericCodes[m] < c) {
|
||||
l = m + 1;
|
||||
} else if (kNumericCodes[m] > c) {
|
||||
|
@ -469,7 +469,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 c)
|
|||
l = 0;
|
||||
r = sizeof(kNumericAstralCodes) / sizeof(kNumericAstralCodes[0]) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kNumericAstralCodes[m] < c) {
|
||||
l = m + 1;
|
||||
} else if (kNumericAstralCodes[m] > c) {
|
||||
|
|
2
third_party/python/pyobj.c
vendored
2
third_party/python/pyobj.c
vendored
|
@ -414,7 +414,7 @@ IsIgnoredModule(const char *s)
|
|||
l = 0;
|
||||
r = ARRAYLEN(kIgnoredModules) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
x = strcmp(s, kIgnoredModules[m]);
|
||||
if (x < 0) {
|
||||
r = m - 1;
|
||||
|
|
12
third_party/stb/stb_truetype.c
vendored
12
third_party/stb/stb_truetype.c
vendored
|
@ -25,6 +25,7 @@
|
|||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/stb/stb_truetype.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/likely.h"
|
||||
|
@ -34,7 +35,6 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/stb/stb_rect_pack.h"
|
||||
#include "third_party/stb/stb_truetype.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
stb_truetype (MIT License)\\n\
|
||||
|
@ -1562,7 +1562,7 @@ static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1
|
|||
r = ttUSHORT(data+10) - 1;
|
||||
needle = glyph1 << 16 | glyph2;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
straw = ttULONG(data+18+(m*6)); // note: unaligned read
|
||||
if (needle < straw)
|
||||
r = m - 1;
|
||||
|
@ -1586,7 +1586,7 @@ static int32_t stbtt__GetCoverageIndex(uint8_t *coverageTable, int glyph)
|
|||
while (l <= r) {
|
||||
uint8_t *glyphArray = coverageTable + 4;
|
||||
uint16_t glyphID;
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
glyphID = ttUSHORT(glyphArray + 2 * m);
|
||||
straw = glyphID;
|
||||
if (needle < straw)
|
||||
|
@ -1607,7 +1607,7 @@ static int32_t stbtt__GetCoverageIndex(uint8_t *coverageTable, int glyph)
|
|||
int strawStart, strawEnd, needle=glyph;
|
||||
while (l <= r) {
|
||||
uint8_t *rangeRecord;
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
rangeRecord = rangeArray + 6 * m;
|
||||
strawStart = ttUSHORT(rangeRecord);
|
||||
strawEnd = ttUSHORT(rangeRecord + 2);
|
||||
|
@ -1648,7 +1648,7 @@ static int32_t stbtt__GetGlyphClass(uint8_t *classDefTable, int glyph)
|
|||
int strawStart, strawEnd, needle=glyph;
|
||||
while (l <= r) {
|
||||
uint8_t *classRangeRecord;
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
classRangeRecord = classRangeRecords + 6 * m;
|
||||
strawStart = ttUSHORT(classRangeRecord);
|
||||
strawEnd = ttUSHORT(classRangeRecord + 2);
|
||||
|
@ -1719,7 +1719,7 @@ static int32_t stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int gl
|
|||
while (l <= r) {
|
||||
uint16_t secondGlyph;
|
||||
uint8_t *pairValue;
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
|
||||
secondGlyph = ttUSHORT(pairValue);
|
||||
straw = secondGlyph;
|
||||
|
|
|
@ -228,6 +228,7 @@ const char *const kGccOnlyFlags[] = {
|
|||
"-fdelete-dead-exceptions",
|
||||
"-femit-struct-debug-baseonly",
|
||||
"-ffp-int-builtin-inexact",
|
||||
"-finline-functions-called-once",
|
||||
"-fipa-pta",
|
||||
"-fivopts",
|
||||
"-flimit-function-alignment",
|
||||
|
@ -241,6 +242,7 @@ const char *const kGccOnlyFlags[] = {
|
|||
"-fno-fp-int-builtin-inexact",
|
||||
"-fno-gnu-unique",
|
||||
"-fno-gnu-unique",
|
||||
"-fno-inline-functions-called-once",
|
||||
"-fno-instrument-functions",
|
||||
"-fno-schedule-insns2",
|
||||
"-fno-whole-program",
|
||||
|
@ -371,7 +373,7 @@ bool IsSafeEnv(const char *s) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kSafeEnv) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
x = strncmp(s, kSafeEnv[m], n);
|
||||
if (x < 0) {
|
||||
r = m - 1;
|
||||
|
@ -389,7 +391,7 @@ bool IsGccOnlyFlag(const char *s) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kGccOnlyFlags) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
x = strcmp(s, kGccOnlyFlags[m]);
|
||||
if (x < 0) {
|
||||
r = m - 1;
|
||||
|
@ -1034,7 +1036,6 @@ int main(int argc, char *argv[]) {
|
|||
#ifdef __x86_64__
|
||||
} else if (!strcmp(argv[i], "-march=native")) {
|
||||
struct X86ProcessorModel *model;
|
||||
if (X86_HAVE(ABM)) AddArg("-mabm");
|
||||
if (X86_HAVE(XOP)) AddArg("-mxop");
|
||||
if (X86_HAVE(SSE4A)) AddArg("-msse4a");
|
||||
if (X86_HAVE(SSE3)) AddArg("-msse3");
|
||||
|
|
|
@ -13,45 +13,24 @@
|
|||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
│ TORTIOUS ACTION, ARISING OUTPATH OF OR IN CONNECTION WITH THE USE OR │ │
|
||||
PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/mem/arraylist.internal.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/mem/bisectcarleft.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/stdio/append.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clone.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/thread/spawn.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/thread/wait0.internal.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "tool/build/lib/getargs.h"
|
||||
|
||||
|
@ -73,27 +52,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define VERSION \
|
||||
"cosmopolitan mkdeps v2.0\n" \
|
||||
"copyright 2023 justine tunney\n" \
|
||||
"https://github.com/jart/cosmopolitan\n"
|
||||
|
||||
#define kIncludePrefix "include \""
|
||||
|
||||
#define THREADS 1 // _getcpucount()
|
||||
#define LOCK (void) // if (__threaded) pthread_spin_lock
|
||||
#define UNLOCK (void) // pthread_spin_unlock
|
||||
|
||||
const char kSourceExts[][5] = {".s", ".S", ".c", ".cc", ".cpp"};
|
||||
|
||||
const char *const kIgnorePrefixes[] = {
|
||||
#if 0
|
||||
"libc/sysv/consts/", "libc/sysv/calls/", "libc/nt/kernel32/",
|
||||
"libc/nt/KernelBase/", "libc/nt/advapi32/", "libc/nt/gdi32/",
|
||||
"libc/nt/ntdll/", "libc/nt/user32/", "libc/nt/shell32/",
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Strings {
|
||||
size_t i, n;
|
||||
char *p;
|
||||
};
|
||||
|
||||
struct Source {
|
||||
unsigned hash;
|
||||
unsigned name;
|
||||
|
@ -120,31 +87,71 @@ struct Edges {
|
|||
struct Edge *p;
|
||||
};
|
||||
|
||||
char *out;
|
||||
char **bouts;
|
||||
pthread_t *th;
|
||||
unsigned counter;
|
||||
struct GetArgs ga;
|
||||
struct Edges edges;
|
||||
struct Sauce *sauces;
|
||||
struct Strings strings;
|
||||
struct Sources sources;
|
||||
const char *buildroot;
|
||||
pthread_spinlock_t galock;
|
||||
pthread_spinlock_t readlock;
|
||||
pthread_spinlock_t writelock;
|
||||
pthread_spinlock_t reportlock;
|
||||
static char *names;
|
||||
static unsigned counter;
|
||||
static const char *prog;
|
||||
static struct Edges edges;
|
||||
static struct Sauce *sauces;
|
||||
static struct Sources sources;
|
||||
static const char *buildroot;
|
||||
static const char *outpath;
|
||||
|
||||
unsigned Hash(const void *s, size_t l) {
|
||||
return max(1, crc32c(0, s, l));
|
||||
static wontreturn void Die(const char *reason) {
|
||||
tinyprint(2, prog, ": ", reason, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned FindFirstFromEdge(unsigned id) {
|
||||
static wontreturn void DieSys(const char *thing) {
|
||||
perror(thing);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static wontreturn void DieOom(void) {
|
||||
Die("out of memory");
|
||||
}
|
||||
|
||||
static unsigned Hash(const void *s, size_t l) {
|
||||
unsigned h;
|
||||
h = crc32c(0, s, l);
|
||||
if (!h) h = 1;
|
||||
return h;
|
||||
}
|
||||
|
||||
static void *Malloc(size_t n) {
|
||||
void *p;
|
||||
if (!(p = malloc(n))) DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Calloc(size_t n, size_t z) {
|
||||
void *p;
|
||||
if (!(p = calloc(n, z))) DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *Realloc(void *p, size_t n) {
|
||||
if (!(p = realloc(p, n))) DieOom();
|
||||
return p;
|
||||
}
|
||||
|
||||
static void Appendw(char **b, uint64_t w) {
|
||||
if (appendw(b, w) == -1) DieOom();
|
||||
}
|
||||
|
||||
static void Appends(char **b, const char *s) {
|
||||
if (appends(b, s) == -1) DieOom();
|
||||
}
|
||||
|
||||
static void Appendd(char **b, const void *p, size_t n) {
|
||||
if (appendd(b, p, n) == -1) DieOom();
|
||||
}
|
||||
|
||||
static unsigned FindFirstFromEdge(unsigned id) {
|
||||
unsigned m, l, r;
|
||||
l = 0;
|
||||
r = edges.i;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (edges.p[m].from < id) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
@ -154,9 +161,18 @@ unsigned FindFirstFromEdge(unsigned id) {
|
|||
return l;
|
||||
}
|
||||
|
||||
void Crunch(void) {
|
||||
static void AppendEdge(struct Edges *edges, unsigned to, unsigned from) {
|
||||
if (edges->i + 1 > edges->n) {
|
||||
edges->n += 1;
|
||||
edges->n += edges->n >> 1;
|
||||
edges->p = Realloc(edges->p, edges->n * sizeof(*edges->p));
|
||||
}
|
||||
edges->p[edges->i++] = (struct Edge){to, from};
|
||||
}
|
||||
|
||||
static void Crunch(void) {
|
||||
size_t i, j;
|
||||
sauces = malloc(sizeof(*sauces) * sources.n);
|
||||
sauces = Malloc(sizeof(*sauces) * sources.n);
|
||||
for (j = i = 0; i < sources.n; ++i) {
|
||||
if (sources.p[i].hash) {
|
||||
sauces[j].name = sources.p[i].name;
|
||||
|
@ -167,16 +183,18 @@ void Crunch(void) {
|
|||
free(sources.p);
|
||||
sources.p = 0;
|
||||
sources.i = j;
|
||||
_longsort((const long *)sauces, sources.i);
|
||||
_longsort((const long *)edges.p, edges.i);
|
||||
if (!radix_sort_int64((const long *)sauces, sources.i) ||
|
||||
!radix_sort_int64((const long *)edges.p, edges.i)) {
|
||||
DieOom();
|
||||
}
|
||||
}
|
||||
|
||||
void Rehash(void) {
|
||||
static void Rehash(void) {
|
||||
size_t i, j, step;
|
||||
struct Sources old;
|
||||
memcpy(&old, &sources, sizeof(sources));
|
||||
sources.n = sources.n ? sources.n << 1 : 16;
|
||||
sources.p = calloc(sources.n, sizeof(struct Source));
|
||||
sources.p = Calloc(sources.n, sizeof(struct Source));
|
||||
for (i = 0; i < old.n; ++i) {
|
||||
if (!old.p[i].hash) continue;
|
||||
step = 0;
|
||||
|
@ -189,9 +207,9 @@ void Rehash(void) {
|
|||
free(old.p);
|
||||
}
|
||||
|
||||
unsigned GetSourceId(const char *name, size_t len) {
|
||||
size_t i, step;
|
||||
static unsigned GetSourceId(const char *name, size_t len) {
|
||||
unsigned hash;
|
||||
size_t i, step;
|
||||
i = 0;
|
||||
hash = Hash(name, len);
|
||||
if (sources.n) {
|
||||
|
@ -199,7 +217,7 @@ unsigned GetSourceId(const char *name, size_t len) {
|
|||
do {
|
||||
i = (hash + step * (step + 1) / 2) & (sources.n - 1);
|
||||
if (sources.p[i].hash == hash &&
|
||||
!memcmp(name, &strings.p[sources.p[i].name], len)) {
|
||||
!memcmp(name, names + sources.p[i].name, len)) {
|
||||
return sources.p[i].id;
|
||||
}
|
||||
step++;
|
||||
|
@ -214,142 +232,128 @@ unsigned GetSourceId(const char *name, size_t len) {
|
|||
} while (sources.p[i].hash);
|
||||
}
|
||||
sources.p[i].hash = hash;
|
||||
sources.p[i].name = CONCAT(&strings.p, &strings.i, &strings.n, name, len);
|
||||
strings.p[strings.i++] = '\0';
|
||||
sources.p[i].name = appendz(names).i;
|
||||
Appendd(&names, name, len);
|
||||
Appendw(&names, 0);
|
||||
return (sources.p[i].id = counter++);
|
||||
}
|
||||
|
||||
bool ShouldSkipSource(const char *src) {
|
||||
unsigned j;
|
||||
for (j = 0; j < ARRAYLEN(kIgnorePrefixes); ++j) {
|
||||
if (_startswith(src, kIgnorePrefixes[j])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
wontreturn void OnMissingFile(const char *list, const char *src) {
|
||||
kprintf("%s is missing\n", src);
|
||||
DCHECK_EQ(ENOENT, errno, "%s", src);
|
||||
/*
|
||||
* This code helps GNU Make automatically fix itself when we
|
||||
* delete a source file. It removes o/.../srcs.txt or
|
||||
* o/.../hdrs.txt and exits nonzero. Since we use hyphen
|
||||
* notation on mkdeps related rules, the build will
|
||||
* automatically restart itself.
|
||||
*/
|
||||
if (list) {
|
||||
kprintf("%s %s...\n", "Refreshing", list);
|
||||
unlink(list);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *LoadRelationshipsWorker(void *arg) {
|
||||
static void LoadRelationships(int argc, char *argv[]) {
|
||||
int fd;
|
||||
char *map;
|
||||
ssize_t rc;
|
||||
bool skipme;
|
||||
struct stat st;
|
||||
struct Edge edge;
|
||||
struct GetArgs ga;
|
||||
size_t i, n, size, inclen;
|
||||
unsigned srcid, dependency;
|
||||
char *buf, srcbuf[PATH_MAX];
|
||||
const char *p, *pe, *src, *path, *pathend;
|
||||
getargs_init(&ga, argv + optind);
|
||||
inclen = strlen(kIncludePrefix);
|
||||
for (;;) {
|
||||
LOCK(&galock);
|
||||
if ((src = getargs_next(&ga))) strcpy(srcbuf, src);
|
||||
UNLOCK(&galock);
|
||||
if (!src) break;
|
||||
src = srcbuf;
|
||||
if (ShouldSkipSource(src)) continue;
|
||||
while ((src = getargs_next(&ga))) {
|
||||
n = strlen(src);
|
||||
LOCK(&readlock);
|
||||
srcid = GetSourceId(src, n);
|
||||
UNLOCK(&readlock);
|
||||
if ((fd = open(src, O_RDONLY)) == -1) {
|
||||
LOCK(&reportlock);
|
||||
OnMissingFile(ga.path, src);
|
||||
if (errno == ENOENT && ga.path) {
|
||||
// This code helps GNU Make automatically fix itself when we
|
||||
// delete a source file. It removes o/.../srcs.txt or
|
||||
// o/.../hdrs.txt and exits nonzero. Since we use hyphen
|
||||
// notation on mkdeps related rules, the build will
|
||||
// automatically restart itself.
|
||||
tinyprint(2, prog, ": deleting ", ga.path, " to refresh build...\n",
|
||||
NULL);
|
||||
}
|
||||
DieSys(src);
|
||||
}
|
||||
CHECK_NE(-1, fstat(fd, &st));
|
||||
if ((size = st.st_size)) {
|
||||
CHECK_NE(MAP_FAILED, (buf = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)));
|
||||
for (p = buf + 1, pe = buf + size; p < pe; ++p) {
|
||||
if ((rc = lseek(fd, 0, SEEK_END)) == -1) {
|
||||
DieSys(src);
|
||||
}
|
||||
if ((size = rc)) {
|
||||
map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (map == MAP_FAILED) {
|
||||
DieSys(src);
|
||||
}
|
||||
for (p = map + 1, pe = map + size; p < pe; ++p) {
|
||||
if (!(p = memmem(p, pe - p, kIncludePrefix, inclen))) break;
|
||||
path = p + inclen;
|
||||
pathend = memchr(path, '"', pe - path);
|
||||
if (pathend && //
|
||||
(p[-1] == '#' || p[-1] == '.') && //
|
||||
(p - buf == 1 || p[-2] == '\n')) { //
|
||||
LOCK(&readlock);
|
||||
(p - map == 1 || p[-2] == '\n')) { //
|
||||
dependency = GetSourceId(path, pathend - path);
|
||||
UNLOCK(&readlock);
|
||||
edge.from = srcid;
|
||||
edge.to = dependency;
|
||||
LOCK(&writelock);
|
||||
append(&edges, &edge);
|
||||
UNLOCK(&writelock);
|
||||
AppendEdge(&edges, dependency, srcid);
|
||||
p = pathend;
|
||||
}
|
||||
}
|
||||
munmap(buf, size);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LoadRelationships(int argc, char *argv[]) {
|
||||
int i;
|
||||
getargs_init(&ga, argv + optind);
|
||||
if (THREADS == 1) {
|
||||
LoadRelationshipsWorker((void *)(intptr_t)0);
|
||||
} else {
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
if (pthread_create(th + i, 0, LoadRelationshipsWorker,
|
||||
(void *)(intptr_t)i)) {
|
||||
LOCK(&reportlock);
|
||||
kprintf("error: _spawn(%d) failed %m\n", i);
|
||||
exit(1);
|
||||
if (munmap(map, size)) {
|
||||
DieSys(src);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
pthread_join(th[i], 0);
|
||||
if (close(fd)) {
|
||||
DieSys(src);
|
||||
}
|
||||
}
|
||||
getargs_destroy(&ga);
|
||||
}
|
||||
|
||||
void GetOpts(int argc, char *argv[]) {
|
||||
static wontreturn void ShowUsage(int rc, int fd) {
|
||||
tinyprint(fd, VERSION,
|
||||
"\n"
|
||||
"USAGE\n"
|
||||
"\n",
|
||||
" ", prog, " -r o// -o OUTPUT INPUT...\n",
|
||||
"\n"
|
||||
"FLAGS\n"
|
||||
"\n"
|
||||
" -h show usage\n"
|
||||
" -o OUTPUT set output path\n"
|
||||
" -r ROOT set build output prefix, e.g. o//\n"
|
||||
"\n"
|
||||
"ARGUMENTS\n"
|
||||
"\n"
|
||||
" OUTPUT shall be makefile code\n"
|
||||
" INPUT should be source or @args.txt\n"
|
||||
"\n",
|
||||
NULL);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
static void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "ho:r:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "hno:r:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
out = optarg;
|
||||
outpath = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
buildroot = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
exit(0);
|
||||
case 'h':
|
||||
ShowUsage(0, 1);
|
||||
default:
|
||||
kprintf("%s: %s [-r %s] [-o %s] [%s...]\n", "Usage", argv[0],
|
||||
"BUILDROOT", "OUTPUT", "PATHSFILE");
|
||||
exit(1);
|
||||
ShowUsage(1, 2);
|
||||
}
|
||||
}
|
||||
if (isempty(out)) kprintf("need -o FILE"), exit(1);
|
||||
if (isempty(buildroot)) kprintf("need -r o/$(MODE)"), exit(1);
|
||||
if (!outpath) {
|
||||
Die("need output path");
|
||||
}
|
||||
if (!buildroot) {
|
||||
Die("need build output prefix");
|
||||
}
|
||||
if (optind == argc) {
|
||||
Die("missing input argument");
|
||||
}
|
||||
}
|
||||
|
||||
const char *StripExt(char pathbuf[PATH_MAX], const char *s) {
|
||||
static const char *StripExt(char pathbuf[PATH_MAX + 1], const char *s) {
|
||||
static char *dot;
|
||||
strcpy(pathbuf, s);
|
||||
strlcpy(pathbuf, s, PATH_MAX + 1);
|
||||
dot = strrchr(pathbuf, '.');
|
||||
if (dot) *dot = '\0';
|
||||
return pathbuf;
|
||||
}
|
||||
|
||||
bool IsObjectSource(const char *name) {
|
||||
static bool IsObjectSource(const char *name) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(kSourceExts); ++i) {
|
||||
if (_endswith(name, kSourceExts[i])) return true;
|
||||
|
@ -357,7 +361,7 @@ bool IsObjectSource(const char *name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
forceinline bool Bts(uint32_t *p, size_t i) {
|
||||
__funline bool Bts(uint32_t *p, size_t i) {
|
||||
bool r;
|
||||
uint32_t k;
|
||||
k = 1u << (i & 31);
|
||||
|
@ -366,95 +370,74 @@ forceinline bool Bts(uint32_t *p, size_t i) {
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t GetFileSizeOrZero(const char *path) {
|
||||
struct stat st;
|
||||
st.st_size = 0;
|
||||
stat(path, &st);
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
void Dive(char **bout, uint32_t *visited, unsigned id) {
|
||||
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;
|
||||
appendw(bout, READ32LE(" \\\n\t"));
|
||||
appends(bout, strings.p + sauces[edges.p[i].to].name);
|
||||
Dive(bout, visited, edges.p[i].to);
|
||||
Appendw(makefile, READ32LE(" \\\n\t"));
|
||||
Appends(makefile, names + sauces[edges.p[i].to].name);
|
||||
Dive(makefile, visited, edges.p[i].to);
|
||||
}
|
||||
}
|
||||
|
||||
void *Diver(void *arg) {
|
||||
char *bout = 0;
|
||||
static char *Explore(void) {
|
||||
const char *path;
|
||||
uint32_t *visited;
|
||||
unsigned *visited;
|
||||
size_t i, visilen;
|
||||
char pathbuf[PATH_MAX];
|
||||
int x = (intptr_t)arg;
|
||||
char *makefile = 0;
|
||||
char buf[PATH_MAX + 1];
|
||||
visilen = (sources.i + sizeof(*visited) * CHAR_BIT - 1) /
|
||||
(sizeof(*visited) * CHAR_BIT);
|
||||
visited = malloc(visilen * sizeof(*visited));
|
||||
for (i = x; i < sources.i; i += THREADS) {
|
||||
path = strings.p + sauces[i].name;
|
||||
visited = Malloc(visilen * sizeof(*visited));
|
||||
for (i = 0; i < sources.i; ++i) {
|
||||
path = names + sauces[i].name;
|
||||
if (!IsObjectSource(path)) continue;
|
||||
appendw(&bout, '\n');
|
||||
Appendw(&makefile, '\n');
|
||||
if (!_startswith(path, "o/")) {
|
||||
appends(&bout, buildroot);
|
||||
Appends(&makefile, buildroot);
|
||||
}
|
||||
appends(&bout, StripExt(pathbuf, path));
|
||||
appendw(&bout, READ64LE(".o: \\\n\t"));
|
||||
appends(&bout, path);
|
||||
Appends(&makefile, StripExt(buf, path));
|
||||
Appendw(&makefile, READ64LE(".o: \\\n\t"));
|
||||
Appends(&makefile, path);
|
||||
bzero(visited, visilen * sizeof(*visited));
|
||||
Bts(visited, i);
|
||||
Dive(&bout, visited, i);
|
||||
appendw(&bout, '\n');
|
||||
Dive(&makefile, visited, i);
|
||||
Appendw(&makefile, '\n');
|
||||
}
|
||||
Appendw(&makefile, '\n');
|
||||
free(visited);
|
||||
appendw(&bout, '\n');
|
||||
bouts[x] = bout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Explore(void) {
|
||||
int i;
|
||||
if (THREADS == 1) {
|
||||
Diver((void *)(intptr_t)0);
|
||||
} else {
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
if (pthread_create(th + i, 0, Diver, (void *)(intptr_t)i)) {
|
||||
LOCK(&reportlock);
|
||||
kprintf("error: _spawn(%d) failed %m\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
pthread_join(th[i], 0);
|
||||
}
|
||||
}
|
||||
return makefile;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i, fd;
|
||||
int fd;
|
||||
ssize_t rc;
|
||||
size_t i, n;
|
||||
char *makefile;
|
||||
#ifndef NDEBUG
|
||||
ShowCrashReports();
|
||||
if (argc == 2 && !strcmp(argv[1], "-n")) exit(0);
|
||||
#endif
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "mkdeps";
|
||||
GetOpts(argc, argv);
|
||||
th = calloc(THREADS, sizeof(*th));
|
||||
bouts = calloc(THREADS, sizeof(*bouts));
|
||||
LoadRelationships(argc, argv);
|
||||
Crunch();
|
||||
Explore();
|
||||
CHECK_NE(-1, (fd = open(out, O_WRONLY | O_CREAT | O_TRUNC, 0644)),
|
||||
"open(%#s)", out);
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
CHECK_NE(-1, xwrite(fd, bouts[i], appendz(bouts[i]).i));
|
||||
makefile = Explore();
|
||||
if ((fd = open(outpath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
|
||||
DieSys(outpath);
|
||||
}
|
||||
CHECK_NE(-1, close(fd));
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
free(bouts[i]);
|
||||
n = appendz(makefile).i;
|
||||
for (i = 0; i < n; i += (size_t)rc) {
|
||||
if ((rc = write(fd, makefile + i, n - i)) == -1) {
|
||||
DieSys(outpath);
|
||||
}
|
||||
}
|
||||
free(strings.p);
|
||||
if (close(fd)) {
|
||||
DieSys(outpath);
|
||||
}
|
||||
free(makefile);
|
||||
free(edges.p);
|
||||
free(sauces);
|
||||
free(bouts);
|
||||
free(th);
|
||||
free(names);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -550,7 +550,7 @@ static struct Symbol *BisectSymbol(struct Package *pkg, const char *name) {
|
|||
l = 0;
|
||||
r = pkg->symbols.i - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
c = strcmp(pkg->strings.p + pkg->symbols.p[m].name, name);
|
||||
if (c < 0) {
|
||||
l = m + 1;
|
||||
|
|
|
@ -669,7 +669,7 @@ static long FindRedirect(const char *s, size_t n) {
|
|||
l = 0;
|
||||
r = redirects.n - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
c = CompareSlices(redirects.p[m].path.s, redirects.p[m].path.n, s, n);
|
||||
if (c < 0) {
|
||||
l = m + 1;
|
||||
|
@ -5381,7 +5381,7 @@ static bool ShouldAutocomplete(const char *s) {
|
|||
l = 0;
|
||||
r = ARRAYLEN(kDontAutoComplete) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
c = strcmp(kDontAutoComplete[m], s);
|
||||
if (c < 0) {
|
||||
l = m + 1;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/midpoint.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "tool/plinko/lib/char.h"
|
||||
|
||||
|
@ -315,7 +314,7 @@ pureconst bool IsWide(int c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kWides) / sizeof(kWides[0]);
|
||||
while (l < r) {
|
||||
m = _midpoint(l, r);
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kWides[m][1] < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
@ -327,7 +326,7 @@ pureconst bool IsWide(int c) {
|
|||
l = 0;
|
||||
r = n = sizeof(kAstralWides) / sizeof(kAstralWides[0]);
|
||||
while (l < r) {
|
||||
m = _midpoint(l, r);
|
||||
m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2)
|
||||
if (kAstralWides[m][1] < c) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue