diff --git a/examples/breakpoint.c b/examples/breakpoint.c index c9a7a58e5..c4de23644 100644 --- a/examples/breakpoint.c +++ b/examples/breakpoint.c @@ -14,7 +14,7 @@ #include "libc/runtime/symbols.internal.h" int main(int argc, char *argv[]) { - // ShowCrashReports(); + ShowCrashReports(); if (IsDebuggerPresent(false)) { kprintf("debugger found!%n"); diff --git a/examples/datauri.c b/examples/datauri.c index 4c49d4c73..c07f569ff 100644 --- a/examples/datauri.c +++ b/examples/datauri.c @@ -43,7 +43,6 @@ void PrintUri(const char *path) { } int main(int argc, char *argv[]) { - ShowCrashReports(); int i; while ((i = getopt(argc, argv, "?h")) != -1) { switch (i) { diff --git a/examples/img.c b/examples/img.c index e456e3a85..37af07737 100644 --- a/examples/img.c +++ b/examples/img.c @@ -7,6 +7,7 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/dce.h" #include "libc/log/log.h" #include "libc/runtime/gc.internal.h" #include "libc/stdio/stdio.h" @@ -67,7 +68,7 @@ void PrintImg(const char *path) { } int main(int argc, char *argv[]) { - ShowCrashReports(); + if (!NoDebug()) ShowCrashReports(); int i; while ((i = getopt(argc, argv, "?huas01234")) != -1) { switch (i) { diff --git a/examples/ispell.c b/examples/ispell.c index 0a90fef64..8ce96e96d 100644 --- a/examples/ispell.c +++ b/examples/ispell.c @@ -153,7 +153,7 @@ void LoadWords(void) { } int main(int argc, char *argv[]) { - ShowCrashReports(); + if (!NoDebug()) ShowCrashReports(); LoadWords(); SpellChecker(); return 0; diff --git a/examples/panels.c b/examples/panels.c index 53d6d1ba9..4e3361126 100644 --- a/examples/panels.c +++ b/examples/panels.c @@ -12,6 +12,7 @@ #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/termios.h" #include "libc/calls/struct/winsize.h" +#include "libc/dce.h" #include "libc/log/check.h" #include "libc/log/gdb.h" #include "libc/log/log.h" @@ -152,7 +153,7 @@ void Draw(void) { int main(int argc, char *argv[]) { struct sigaction sa[2] = {{.sa_handler = OnShutdown}, {.sa_handler = OnInvalidate}}; - ShowCrashReports(); + if (!NoDebug()) ShowCrashReports(); Setup(); Enter(); GetTtySize(); diff --git a/examples/rlimit.c b/examples/rlimit.c index c98aa4113..47325062c 100644 --- a/examples/rlimit.c +++ b/examples/rlimit.c @@ -36,12 +36,12 @@ static void SetLimit(int resource, uint64_t soft, uint64_t hard) { lim.rlim_max = MIN(hard, old.rlim_max); lim.rlim_cur = MIN(soft, lim.rlim_max); if (!setrlimit(resource, &lim)) { - fprintf(stderr, "%snote: setrlimit(%s) downgraded to {%,ld, %,ld}\n", + fprintf(stderr, "%sNOTE: SETRLIMIT(%s) DOWNGRADED TO {%,ld, %,ld}\n", __strace_rlimit_name(resource), lim.rlim_cur, lim.rlim_max); return; } } - fprintf(stderr, "error: setrlimit(%s, %,ld, %,ld) failed %m%n", + fprintf(stderr, "ERROR: SETRLIMIT(%s, %,ld, %,ld) FAILED %m%n", __strace_rlimit_name(resource), soft, hard); exit(1); } @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) { for (i = 0; i < RLIM_NLIMITS; ++i) { rc = getrlimit(i, &rlim); - printf("setrlimit(%-20s, %,16ld, %,16ld) → %d %s\n", + printf("SETRLIMIT(%-20s, %,16ld, %,16ld) → %d %s\n", __strace_rlimit_name(i), rlim.rlim_cur, rlim.rlim_max, rc, !rc ? "" : strerror(errno)); } diff --git a/examples/seq.c b/examples/seq.c index 7e2782cc1..dc7e2295a 100644 --- a/examples/seq.c +++ b/examples/seq.c @@ -7,8 +7,9 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/calls/calls.h" #include "libc/fmt/conv.h" -#include "libc/stdio/stdio.h" +#include "libc/fmt/itoa.h" /** * @fileoverview Prints sequence of numbers. @@ -16,6 +17,7 @@ int main(int argc, char *argv[]) { long a, b, i; + char buf[21], *p; switch (argc) { case 2: a = 1; @@ -29,6 +31,9 @@ int main(int argc, char *argv[]) { return 1; } for (i = a; i <= b; ++i) { - printf("%ld\n", i); + p = buf; + p = FormatInt64(p, i); + *p++ = '\n'; + write(1, buf, p - buf); } } diff --git a/libc/log/backtrace2.greg.c b/libc/log/backtrace2.greg.c index 61f0f8666..376a2a580 100644 --- a/libc/log/backtrace2.greg.c +++ b/libc/log/backtrace2.greg.c @@ -184,8 +184,8 @@ void ShowBacktrace(int fd, const struct StackFrame *bp) { __strace = st; g_ftrace = ft; #else - kprintf("ShowBacktrace() needs these flags to show C backtrace:\n" - "\t-D__FNO_OMIT_FRAME_POINTER__\n" - "\t-fno-omit-frame-pointer\n"); + (fprintf)(stderr, "ShowBacktrace() needs these flags to show C backtrace:\n" + "\t-D__FNO_OMIT_FRAME_POINTER__\n" + "\t-fno-omit-frame-pointer\n"); #endif } diff --git a/libc/log/checkfail_ndebug.c b/libc/log/checkfail_ndebug.c index a5a09318d..410364304 100644 --- a/libc/log/checkfail_ndebug.c +++ b/libc/log/checkfail_ndebug.c @@ -17,10 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/errno.h" -#include "libc/intrin/kprintf.h" #include "libc/log/internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" #include "libc/str/str.h" /** @@ -36,9 +36,9 @@ relegated void ___check_fail_ndebug(uint64_t want, uint64_t got, const char *opchar) { __restore_tty(); - kprintf("\n%serror: %s: check failed: 0x%x %s 0x%x (%s)\n", - !__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, got, - strerror(errno)); + (fprintf)(stderr, "\n%serror: %s: check failed: 0x%x %s 0x%x (%s)\n", + !__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, + got, strerror(errno)); __restorewintty(); _Exit(68); } diff --git a/libc/time/localtime.c b/libc/time/localtime.c index 5e50d32de..4fcca25b2 100644 --- a/libc/time/localtime.c +++ b/libc/time/localtime.c @@ -17,6 +17,7 @@ STATIC_YOINK("usr/share/zoneinfo/Beijing"); STATIC_YOINK("usr/share/zoneinfo/Berlin"); STATIC_YOINK("usr/share/zoneinfo/Boulder"); STATIC_YOINK("usr/share/zoneinfo/Chicago"); +STATIC_YOINK("usr/share/zoneinfo/GMT"); STATIC_YOINK("usr/share/zoneinfo/GST"); STATIC_YOINK("usr/share/zoneinfo/Honolulu"); STATIC_YOINK("usr/share/zoneinfo/Israel"); @@ -172,10 +173,10 @@ static bool increment_overflow(int *, int); static bool increment_overflow_time(time_t *, int_fast32_t); static int_fast32_t leapcorr(struct state const *, time_t); static bool normalize_overflow32(int_fast32_t *, int *, int); -static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, - struct tm *); -static bool typesequiv(struct state const *, int, int); -static bool tzparse(char const *, struct state *, struct state *); +static struct tm *localtime_timesub(time_t const *, int_fast32_t, + struct state const *, struct tm *); +static bool localtime_typesequiv(struct state const *, int, int); +static bool localtime_tzparse(char const *, struct state *, struct state *); #ifdef ALL_STATE static struct state * lclptr; @@ -390,8 +391,8 @@ union local_storage { format if DOEXTEND. Use *LSP for temporary storage. Return 0 on success, an errno value on failure. */ static int -tzloadbody(char const *name, struct state *sp, bool doextend, - union local_storage *lsp) +localtime_tzloadbody(char const *name, struct state *sp, bool doextend, + union local_storage *lsp) { register int i; register int fid; @@ -628,7 +629,7 @@ tzloadbody(char const *name, struct state *sp, bool doextend, struct state *ts = &lsp->u.st; up->buf[nread - 1] = '\0'; - if (tzparse(&up->buf[1], ts, sp)) { + if (localtime_tzparse(&up->buf[1], ts, sp)) { /* Attempt to reuse existing abbreviations. Without this, America/Anchorage would be right on @@ -695,9 +696,9 @@ tzloadbody(char const *name, struct state *sp, bool doextend, int repeattype = sp->types[0]; for (i = 1; i < sp->timecnt; ++i) if (sp->ats[i] == repeatat - && typesequiv(sp, sp->types[i], repeattype)) { - sp->goback = true; - break; + && localtime_typesequiv(sp, sp->types[i], repeattype)) { + sp->goback = true; + break; } } if (TIME_T_MIN + SECSPERREPEAT <= sp->ats[sp->timecnt - 1]) { @@ -705,9 +706,9 @@ tzloadbody(char const *name, struct state *sp, bool doextend, int repeattype = sp->types[sp->timecnt - 1]; for (i = sp->timecnt - 2; i >= 0; --i) if (sp->ats[i] == repeatat - && typesequiv(sp, sp->types[i], repeattype)) { - sp->goahead = true; - break; + && localtime_typesequiv(sp, sp->types[i], repeattype)) { + sp->goahead = true; + break; } } } @@ -770,14 +771,14 @@ tzloadbody(char const *name, struct state *sp, bool doextend, /* Load tz data from the file named NAME into *SP. Read extended format if DOEXTEND. Return 0 on success, an errno value on failure. */ static int -tzload(char const *name, struct state *sp, bool doextend) +localtime_tzload(char const *name, struct state *sp, bool doextend) { #ifdef ALL_STATE union local_storage *lsp = malloc(sizeof *lsp); if (!lsp) { return HAVE_MALLOC_ERRNO ? errno : ENOMEM; } else { - int err = tzloadbody(name, sp, doextend, lsp); + int err = localtime_tzloadbody(name, sp, doextend, lsp); free(lsp); return err; } @@ -790,12 +791,12 @@ tzload(char const *name, struct state *sp, bool doextend) for (x = i = 0; i < sizeof(ls); i += 4096) { x += p[i]; /* make sure tzdata doesn't smash the stack */ } - return tzloadbody(name, sp, doextend, &ls); + return localtime_tzloadbody(name, sp, doextend, &ls); #endif } static bool -typesequiv(const struct state *sp, int a, int b) +localtime_typesequiv(const struct state *sp, int a, int b) { register bool result; @@ -1116,7 +1117,7 @@ transtime(const int year, register const struct rule *const rulep, */ static bool -tzparse(const char *name, struct state *sp, struct state *basep) +localtime_tzparse(const char *name, struct state *sp, struct state *basep) { const char * stdname; const char * dstname; @@ -1157,7 +1158,7 @@ tzparse(const char *name, struct state *sp, struct state *basep) sp->leapcnt = basep->leapcnt; memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis); } else { - load_ok = tzload(TZDEFRULES, sp, false) == 0; + load_ok = localtime_tzload(TZDEFRULES, sp, false) == 0; if (!load_ok) sp->leapcnt = 0; /* So, we're off a little. */ } @@ -1396,8 +1397,8 @@ tzparse(const char *name, struct state *sp, struct state *basep) static void gmtload(struct state *const sp) { - if (tzload(gmt, sp, true) != 0) - tzparse("GMT0", sp, NULL); + if (localtime_tzload(gmt, sp, true) != 0) + localtime_tzparse("GMT0", sp, NULL); } /* Initialize *SP to a value appropriate for the TZ setting NAME. @@ -1419,8 +1420,9 @@ zoneinit(struct state *sp, char const *name) sp->defaulttype = 0; return 0; } else { - int err = tzload(name, sp, true); - if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL)) + int err = localtime_tzload(name, sp, true); + if (err != 0 && name && name[0] != ':' && + localtime_tzparse(name, sp, NULL)) err = 0; if (err == 0) scrub_abbrs(sp); @@ -1429,7 +1431,7 @@ zoneinit(struct state *sp, char const *name) } static void -tzset_unlocked(void) +localtime_tzset_unlocked(void) { char const *name = getenv("TZ"); struct state *sp = lclptr; @@ -1457,12 +1459,12 @@ tzset(void) { if (lock() != 0) return; - tzset_unlocked(); + localtime_tzset_unlocked(); unlock(); } static void -gmtcheck(void) +localtime_gmtcheck(void) { static bool gmt_is_set; if (lock() != 0) @@ -1566,7 +1568,7 @@ localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, ** t += ttisp->tt_utoff; ** timesub(&t, 0L, sp, tmp); */ - result = timesub(&t, ttisp->tt_utoff, sp, tmp); + result = localtime_timesub(&t, ttisp->tt_utoff, sp, tmp); if (result) { result->tm_isdst = ttisp->tt_isdst; result->tm_zone = (char *) &sp->chars[ttisp->tt_desigidx]; @@ -1585,7 +1587,7 @@ localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) return NULL; } if (setname || !lcl_is_set) - tzset_unlocked(); + localtime_tzset_unlocked(); tmp = localsub(lclptr, timep, setname, tmp); unlock(); return tmp; @@ -1613,7 +1615,7 @@ gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset, { register struct tm * result; - result = timesub(timep, offset, gmtptr, tmp); + result = localtime_timesub(timep, offset, gmtptr, tmp); /* ** Could get fancy here and deliver something such as ** "+xx" or "-xx" if offset is non-zero, @@ -1631,7 +1633,7 @@ gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset, struct tm * gmtime_r(const time_t *timep, struct tm *tmp) { - gmtcheck(); + localtime_gmtcheck(); return gmtsub(gmtptr, timep, 0, tmp); } @@ -1661,8 +1663,8 @@ leaps_thru_end_of(time_t y) } static struct tm * -timesub(const time_t *timep, int_fast32_t offset, - const struct state *sp, struct tm *tmp) +localtime_timesub(const time_t *timep, int_fast32_t offset, + const struct state *sp, struct tm *tmp) { register const struct lsinfo * lp; register time_t tdays; @@ -1783,11 +1785,16 @@ timesub(const time_t *timep, int_fast32_t offset, ** Normalize logic courtesy Paul Eggert. */ -static bool +static inline bool increment_overflow(int *ip, int j) { +#if defined(__GNUC__) && __GNUC__ >= 6 + int i = *ip; + if (__builtin_add_overflow(i, j, &i)) return true; + *ip = i; + return false; +#else register int const i = *ip; - /* ** If i >= 0 there can only be overflow if i + j > INT_MAX ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. @@ -1798,22 +1805,35 @@ increment_overflow(int *ip, int j) return true; *ip += j; return false; +#endif } -static bool +static inline bool increment_overflow32(int_fast32_t *const lp, int const m) { +#if defined(__GNUC__) && __GNUC__ >= 6 + int_fast32_t i = *lp; + if (__builtin_add_overflow(i, m, &i)) return true; + *lp = i; + return false; +#else register int_fast32_t const l = *lp; - if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) return true; *lp += m; return false; +#endif } -static bool +static inline bool increment_overflow_time(time_t *tp, int_fast32_t j) { +#if defined(__GNUC__) && __GNUC__ >= 6 + time_t i = *tp; + if (__builtin_add_overflow(i, j, &i)) return true; + *tp = i; + return false; +#else /* ** This is like ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', @@ -1825,6 +1845,7 @@ increment_overflow_time(time_t *tp, int_fast32_t j) return true; *tp += j; return false; +#endif } static bool @@ -1868,13 +1889,14 @@ tmcomp(register const struct tm *const atmp, } static time_t -time2sub(struct tm *const tmp, - struct tm *(*funcp)(struct state const *, time_t const *, - int_fast32_t, struct tm *), - struct state const *sp, - const int_fast32_t offset, - bool *okayp, - bool do_norm_secs) +localtime_time2sub( + struct tm *const tmp, + struct tm *(*funcp)(struct state const *, time_t const *, + int_fast32_t, struct tm *), + struct state const *sp, + const int_fast32_t offset, + bool *okayp, + bool do_norm_secs) { register int dir; register int i, j; @@ -2067,12 +2089,13 @@ label: } static time_t -time2(struct tm * const tmp, - struct tm *(*funcp)(struct state const *, time_t const *, - int_fast32_t, struct tm *), - struct state const *sp, - const int_fast32_t offset, - bool *okayp) +localtime_time2( + struct tm * const tmp, + struct tm *(*funcp)(struct state const *, time_t const *, + int_fast32_t, struct tm *), + struct state const *sp, + const int_fast32_t offset, + bool *okayp) { time_t t; @@ -2081,16 +2104,17 @@ time2(struct tm * const tmp, ** (in case tm_sec contains a value associated with a leap second). ** If that fails, try with normalization of seconds. */ - t = time2sub(tmp, funcp, sp, offset, okayp, false); - return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); + t = localtime_time2sub(tmp, funcp, sp, offset, okayp, false); + return *okayp ? t : localtime_time2sub(tmp,funcp,sp,offset,okayp,true); } static time_t -time1(struct tm *const tmp, - struct tm *(*funcp)(struct state const *, time_t const *, - int_fast32_t, struct tm *), - struct state const *sp, - const int_fast32_t offset) +localtime_time1( + struct tm *const tmp, + struct tm *(*funcp)(struct state const *, time_t const *, + int_fast32_t, struct tm *), + struct state const *sp, + const int_fast32_t offset) { register time_t t; register int samei, otheri; @@ -2107,7 +2131,7 @@ time1(struct tm *const tmp, } if (tmp->tm_isdst > 1) tmp->tm_isdst = 1; - t = time2(tmp, funcp, sp, offset, &okay); + t = localtime_time2(tmp, funcp, sp, offset, &okay); if (okay) return t; if (tmp->tm_isdst < 0) @@ -2146,7 +2170,7 @@ time1(struct tm *const tmp, tmp->tm_sec += (sp->ttis[otheri].tt_utoff - sp->ttis[samei].tt_utoff); tmp->tm_isdst = !tmp->tm_isdst; - t = time2(tmp, funcp, sp, offset, &okay); + t = localtime_time2(tmp, funcp, sp, offset, &okay); if (okay) return t; tmp->tm_sec -= (sp->ttis[otheri].tt_utoff @@ -2161,10 +2185,10 @@ static time_t mktime_tzname(struct state *sp, struct tm *tmp, bool setname) { if (sp) - return time1(tmp, localsub, sp, setname); + return localtime_time1(tmp, localsub, sp, setname); else { - gmtcheck(); - return time1(tmp, gmtsub, gmtptr, 0); + localtime_gmtcheck(); + return localtime_time1(tmp, gmtsub, gmtptr, 0); } } @@ -2177,7 +2201,7 @@ mktime(struct tm *tmp) errno = err; return -1; } - tzset_unlocked(); + localtime_tzset_unlocked(); t = mktime_tzname(lclptr, tmp, true); unlock(); return t; diff --git a/libc/time/strftime.c b/libc/time/strftime.c index 41d16607f..8ab0ae2d1 100644 --- a/libc/time/strftime.c +++ b/libc/time/strftime.c @@ -106,7 +106,7 @@ enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL }; #endif /* !defined YEAR_2000_NAME */ static char * -_add(const char *str, char *pt, const char *ptlim) +strftime_add(const char *str, char *pt, const char *ptlim) { while (pt < ptlim && (*pt = *str++) != '\0') ++pt; @@ -114,11 +114,11 @@ _add(const char *str, char *pt, const char *ptlim) } static char * -_conv(int n, const char *format, char *pt, const char *ptlim) +strftime_conv(int n, const char *format, char *pt, const char *ptlim) { char buf[INT_STRLEN_MAXIMUM(int) + 1]; (sprintf)(buf, format, n); - return _add(buf, pt, ptlim); + return strftime_add(buf, pt, ptlim); } /* @@ -130,8 +130,13 @@ _conv(int n, const char *format, char *pt, const char *ptlim) */ static char * -_yconv(int a, int b, bool convert_top, bool convert_yy, - char *pt, const char *ptlim) +strftime_yconv( + int a, + int b, + bool convert_top, + bool convert_yy, + char *pt, + const char *ptlim) { register int lead; register int trail; @@ -148,17 +153,17 @@ _yconv(int a, int b, bool convert_top, bool convert_yy, } if (convert_top) { if (lead == 0 && trail < 0) - pt = _add("-0", pt, ptlim); - else pt = _conv(lead, "%02d", pt, ptlim); + pt = strftime_add("-0", pt, ptlim); + else pt = strftime_conv(lead, "%02d", pt, ptlim); } if (convert_yy) - pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); + pt = strftime_conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); return pt; } static char * -_fmt(const char *format, const struct tm *t, char *pt, - const char *ptlim, enum warn *warnp) +strftime_fmt(const char *format, const struct tm *t, char *pt, + const char *ptlim, enum warn *warnp) { for ( ; *format; ++format) { if (*format == '%') { @@ -168,27 +173,31 @@ label: --format; break; case 'A': - pt = _add((t->tm_wday < 0 || + pt = strftime_add( + (t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : Locale->weekday[t->tm_wday], pt, ptlim); continue; case 'a': - pt = _add((t->tm_wday < 0 || - t->tm_wday >= DAYSPERWEEK) ? + pt = strftime_add( + (t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? "?" : Locale->wday[t->tm_wday], pt, ptlim); continue; case 'B': - pt = _add((t->tm_mon < 0 || - t->tm_mon >= MONSPERYEAR) ? + pt = strftime_add( + (t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? "?" : Locale->month[t->tm_mon], pt, ptlim); continue; case 'b': case 'h': - pt = _add((t->tm_mon < 0 || - t->tm_mon >= MONSPERYEAR) ? + pt = strftime_add( + (t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? "?" : Locale->mon[t->tm_mon], pt, ptlim); continue; @@ -200,14 +209,14 @@ label: ** something completely different. ** (ado, 1993-05-24) */ - pt = _yconv(t->tm_year, TM_YEAR_BASE, - true, false, pt, ptlim); + pt = strftime_yconv(t->tm_year, TM_YEAR_BASE, + true, false, pt, ptlim); continue; case 'c': { enum warn warn2 = IN_SOME; - pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2); + pt = strftime_fmt(Locale->c_fmt, t, pt, ptlim, &warn2); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -215,10 +224,10 @@ label: } continue; case 'D': - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); + pt = strftime_fmt("%m/%d/%y", t, pt, ptlim, warnp); continue; case 'd': - pt = _conv(t->tm_mday, "%02d", pt, ptlim); + pt = strftime_conv(t->tm_mday, "%02d", pt, ptlim); continue; case 'E': case 'O': @@ -233,21 +242,21 @@ label: */ goto label; case 'e': - pt = _conv(t->tm_mday, "%2d", pt, ptlim); + pt = strftime_conv(t->tm_mday, "%2d", pt, ptlim); continue; case 'F': - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); + pt = strftime_fmt("%Y-%m-%d", t, pt, ptlim, warnp); continue; case 'H': - pt = _conv(t->tm_hour, "%02d", pt, ptlim); + pt = strftime_conv(t->tm_hour, "%02d", pt, ptlim); continue; case 'I': - pt = _conv((t->tm_hour % 12) ? - (t->tm_hour % 12) : 12, - "%02d", pt, ptlim); + pt = strftime_conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + "%02d", pt, ptlim); continue; case 'j': - pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); + pt = strftime_conv(t->tm_yday + 1, "%03d", pt, ptlim); continue; case 'k': /* @@ -260,14 +269,15 @@ label: ** "%l" have been swapped. ** (ado, 1993-05-24) */ - pt = _conv(t->tm_hour, "%2d", pt, ptlim); + pt = strftime_conv(t->tm_hour, "%2d", + pt, ptlim); continue; #ifdef KITCHEN_SINK case 'K': /* ** After all this time, still unclaimed! */ - pt = _add("kitchen sink", pt, ptlim); + pt = strftime_add("kitchen sink", pt, ptlim); continue; #endif /* defined KITCHEN_SINK */ case 'l': @@ -280,33 +290,38 @@ label: ** "%l" have been swapped. ** (ado, 1993-05-24) */ - pt = _conv((t->tm_hour % 12) ? - (t->tm_hour % 12) : 12, - "%2d", pt, ptlim); + pt = strftime_conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + "%2d", pt, ptlim); continue; case 'M': - pt = _conv(t->tm_min, "%02d", pt, ptlim); + pt = strftime_conv(t->tm_min, "%02d", + pt, ptlim); continue; case 'm': - pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); + pt = strftime_conv(t->tm_mon + 1, "%02d", + pt, ptlim); continue; case 'n': - pt = _add("\n", pt, ptlim); + pt = strftime_add("\n", pt, ptlim); continue; case 'p': - pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? + pt = strftime_add( + (t->tm_hour >= (HOURSPERDAY / 2)) ? Locale->pm : Locale->am, pt, ptlim); continue; case 'R': - pt = _fmt("%H:%M", t, pt, ptlim, warnp); + pt = strftime_fmt("%H:%M", t, pt, ptlim, warnp); continue; case 'r': - pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp); + pt = strftime_fmt("%I:%M:%S %p", t, pt, + ptlim, warnp); continue; case 'S': - pt = _conv(t->tm_sec, "%02d", pt, ptlim); + pt = strftime_conv(t->tm_sec, "%02d", pt, + ptlim); continue; case 's': { @@ -338,19 +353,19 @@ label: uintmax_t n = mkt; (sprintf)(buf, "%"PRIuMAX, n); } - pt = _add(buf, pt, ptlim); + pt = strftime_add(buf, pt, ptlim); } continue; case 'T': - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); + pt = strftime_fmt("%H:%M:%S", t, pt, ptlim, warnp); continue; case 't': - pt = _add("\t", pt, ptlim); + pt = strftime_add("\t", pt, ptlim); continue; case 'U': - pt = _conv((t->tm_yday + DAYSPERWEEK - - t->tm_wday) / DAYSPERWEEK, - "%02d", pt, ptlim); + pt = strftime_conv((t->tm_yday + DAYSPERWEEK - + t->tm_wday) / DAYSPERWEEK, + "%02d", pt, ptlim); continue; case 'u': /* @@ -359,9 +374,9 @@ label: ** [1 (Monday) - 7]" ** (ado, 1993-05-24) */ - pt = _conv((t->tm_wday == 0) ? - DAYSPERWEEK : t->tm_wday, - "%d", pt, ptlim); + pt = strftime_conv((t->tm_wday == 0) ? + DAYSPERWEEK : t->tm_wday, + "%d", pt, ptlim); continue; case 'V': /* ISO 8601 week number */ case 'G': /* ISO 8601 year (four digits) */ @@ -434,16 +449,16 @@ label: DAYSPERNYEAR; } if (*format == 'V') - pt = _conv(w, "%02d", - pt, ptlim); + pt = strftime_conv(w, "%02d", + pt, ptlim); else if (*format == 'g') { *warnp = IN_ALL; - pt = _yconv(year, base, - false, true, - pt, ptlim); - } else pt = _yconv(year, base, - true, true, - pt, ptlim); + pt = strftime_yconv(year, base, + false, true, + pt, ptlim); + } else pt = strftime_yconv(year, base, + true, true, + pt, ptlim); } continue; case 'v': @@ -452,26 +467,27 @@ label: ** "date as dd-bbb-YYYY" ** (ado, 1993-05-24) */ - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); + pt = strftime_fmt("%e-%b-%Y", t, pt, ptlim, warnp); continue; case 'W': - pt = _conv((t->tm_yday + DAYSPERWEEK - - (t->tm_wday ? - (t->tm_wday - 1) : - (DAYSPERWEEK - 1))) / DAYSPERWEEK, + pt = strftime_conv( + (t->tm_yday + DAYSPERWEEK - + (t->tm_wday ? + (t->tm_wday - 1) : + (DAYSPERWEEK - 1))) / DAYSPERWEEK, "%02d", pt, ptlim); continue; case 'w': - pt = _conv(t->tm_wday, "%d", pt, ptlim); + pt = strftime_conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': - pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp); + pt = strftime_fmt(Locale->X_fmt, t, pt, ptlim, warnp); continue; case 'x': { enum warn warn2 = IN_SOME; - pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2); + pt = strftime_fmt(Locale->x_fmt, t, pt, ptlim, &warn2); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -480,17 +496,17 @@ label: continue; case 'y': *warnp = IN_ALL; - pt = _yconv(t->tm_year, TM_YEAR_BASE, - false, true, - pt, ptlim); + pt = strftime_yconv(t->tm_year, TM_YEAR_BASE, + false, true, + pt, ptlim); continue; case 'Y': - pt = _yconv(t->tm_year, TM_YEAR_BASE, - true, true, - pt, ptlim); + pt = strftime_yconv(t->tm_year, TM_YEAR_BASE, + true, true, + pt, ptlim); continue; case 'Z': - pt = _add(t->tm_zone, pt, ptlim); + pt = strftime_add(t->tm_zone, pt, ptlim); /* ** C99 and later say that %Z must be ** replaced by the empty string if the @@ -513,16 +529,16 @@ label: sign = "-"; diff = -diff; } else sign = "+"; - pt = _add(sign, pt, ptlim); + pt = strftime_add(sign, pt, ptlim); diff /= SECSPERMIN; diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); - pt = _conv(diff, "%04d", pt, ptlim); + pt = strftime_conv(diff, "%04d", pt, ptlim); } continue; case '+': - pt = _fmt(Locale->date_fmt, t, pt, ptlim, - warnp); + pt = strftime_fmt(Locale->date_fmt, t, pt, + ptlim, warnp); continue; case '%': /* @@ -562,7 +578,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *t) enum warn warn = IN_NONE; tzset(); - p = _fmt(format, t, s, s + maxsize, &warn); + p = strftime_fmt(format, t, s, s + maxsize, &warn); if (!p) { errno = EOVERFLOW; return 0; diff --git a/libc/time/time.mk b/libc/time/time.mk index 0690eaa7c..da673d944 100644 --- a/libc/time/time.mk +++ b/libc/time/time.mk @@ -61,8 +61,7 @@ o/$(MODE)/libc/time/strftime.o: \ OVERRIDE_CFLAGS += \ -fno-jump-tables -o/$(MODE)/libc/time/localtime.o \ -o/$(MODE)/libc/time/strftime.o: \ +o/$(MODE)/libc/time/localtime.o: \ OVERRIDE_CFLAGS += \ -fdata-sections \ -ffunction-sections diff --git a/third_party/dlmalloc/dlmalloc_abort.greg.c b/third_party/dlmalloc/dlmalloc_abort.greg.c index 12ea05742..d2b2fd17a 100644 --- a/third_party/dlmalloc/dlmalloc_abort.greg.c +++ b/third_party/dlmalloc/dlmalloc_abort.greg.c @@ -17,13 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/weaken.h" -#include "libc/intrin/kprintf.h" +#include "libc/calls/calls.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" -#include "third_party/dlmalloc/dlmalloc.h" +#include "libc/str/str.h" + +#define MESSAGE "dlmalloc_abort()\n" void dlmalloc_abort(void) { - kprintf("dlmalloc_abort()%n"); + write(2, MESSAGE, strlen(MESSAGE)); if (weaken(__die)) weaken(__die)(); _Exit(44); } diff --git a/tool/net/help.txt b/tool/net/help.txt index 0fe55737f..e516a0e48 100644 --- a/tool/net/help.txt +++ b/tool/net/help.txt @@ -434,6 +434,11 @@ SPECIAL PATHS If it exists, it'll be used as the / listing page icon, embedded as a base64 URI. + /usr/share/zoneinfo + This directory contains a subset of the timezone database. + Your `TZ` environment variable controls which one of these + files is used by functions such as unix.localtime(). + /usr/share/ssl/root This directory contains your root certificate authorities. It is needed so the Fetch() HTTPS client API can verify that a remote @@ -1914,7 +1919,7 @@ UNIX MODULE ├─→ true └─→ nil, unix.Errno - Changes user and gorup on file. + Changes user and group on file. Returns `ENOSYS` on Windows NT. @@ -2817,19 +2822,21 @@ UNIX MODULE Your redbean ships with a subset of the time zone database. - - `/zip/usr/share/zoneinfo/Honolulu` - - `/zip/usr/share/zoneinfo/Anchorage` - - `/zip/usr/share/zoneinfo/GST` - - `/zip/usr/share/zoneinfo/Boulder` - - `/zip/usr/share/zoneinfo/Chicago` - - `/zip/usr/share/zoneinfo/New_York` - - `/zip/usr/share/zoneinfo/UTC` - - `/zip/usr/share/zoneinfo/London` - - `/zip/usr/share/zoneinfo/Berlin` - - `/zip/usr/share/zoneinfo/Israel` - - `/zip/usr/share/zoneinfo/Beijing` - - `/zip/usr/share/zoneinfo/Japan` - - `/zip/usr/share/zoneinfo/Sydney` + - `/zip/usr/share/zoneinfo/Honolulu` Z-10 + - `/zip/usr/share/zoneinfo/Anchorage` Z -9 + - `/zip/usr/share/zoneinfo/GST` Z -8 + - `/zip/usr/share/zoneinfo/Boulder` Z -6 + - `/zip/usr/share/zoneinfo/Chicago` Z -5 + - `/zip/usr/share/zoneinfo/New_York` Z -4 + - `/zip/usr/share/zoneinfo/UTC` Z +0 + - `/zip/usr/share/zoneinfo/GMT` Z +0 + - `/zip/usr/share/zoneinfo/London` Z +1 + - `/zip/usr/share/zoneinfo/Berlin` Z +2 + - `/zip/usr/share/zoneinfo/Israel` Z +3 + - `/zip/usr/share/zoneinfo/India` Z +5 + - `/zip/usr/share/zoneinfo/Beijing` Z +8 + - `/zip/usr/share/zoneinfo/Japan` Z +9 + - `/zip/usr/share/zoneinfo/Sydney` Z+10 You can control which timezone is used using the `TZ` environment variable. If your time zone isn't included in the above list, you @@ -3988,5 +3995,5 @@ UNIX MODULE SEE ALSO - https://justine.lol/redbean/index.html + https://redbean.dev/ https://news.ycombinator.com/item?id=26271117 diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 0aee7cdbf..c5a3b2444 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -179,7 +179,7 @@ STATIC_YOINK("zip_uri_support"); #define REDBEAN "redbean" #endif -#define VERSION 0x010500 +#define VERSION 0x020000 #define HEARTBEAT 5000 /*ms*/ #define HASH_LOAD_FACTOR /* 1. / */ 4 #define READ(F, P, N) readv(F, &(struct iovec){P, N}, 1) diff --git a/usr/share/zoneinfo/GMT b/usr/share/zoneinfo/GMT new file mode 100644 index 000000000..c63474664 Binary files /dev/null and b/usr/share/zoneinfo/GMT differ diff --git a/usr/share/zoneinfo/India b/usr/share/zoneinfo/India new file mode 100644 index 000000000..0014046d2 Binary files /dev/null and b/usr/share/zoneinfo/India differ