mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 23:13:34 +00:00
This change integrates e58abc1110b335a3341e8ad5821ad8e3880d9bb2 from https://github.com/ahgamut/musl-cross-make/ which fixes the issues we were having with our C language extension for symbolic constants. This change also performs some code cleanup and bug fixes to getaddrinfo(). It's now possible to compile projects like ncurses, readline and python without needing to patch anything upstream, except maybe a line or two. Pretty soon it should be possible to build a Linux distro on Cosmo.
233 lines
9.8 KiB
C
233 lines
9.8 KiB
C
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
|
|
#define COSMOPOLITAN_LIBC_LOG_LOG_H_
|
|
#include "libc/stdio/stdio.h"
|
|
|
|
#define kLogFatal 0
|
|
#define kLogError 1
|
|
#define kLogWarn 2
|
|
#define kLogInfo 3
|
|
#define kLogVerbose 4
|
|
#define kLogDebug 5
|
|
#define kLogNoise 6
|
|
|
|
/**
|
|
* Log level for compile-time DCE.
|
|
*/
|
|
#ifndef LOGGABLELEVEL
|
|
#ifndef TINY
|
|
#define LOGGABLELEVEL kLogNoise
|
|
/* #elif IsTiny() */
|
|
/* #define LOGGABLELEVEL kLogInfo */
|
|
#else
|
|
#define LOGGABLELEVEL kLogVerbose
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef TINY
|
|
#define _LOG_TINY 1
|
|
#else
|
|
#define _LOG_TINY 0
|
|
#endif
|
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
extern FILE *__log_file;
|
|
|
|
int __watch(void *, size_t);
|
|
void __die(void) relegated wontreturn; /* print backtrace and abort() */
|
|
void _meminfo(int); /* shows malloc statistics &c. */
|
|
void _memsummary(int); /* light version of same thing */
|
|
bool IsTerminalInarticulate(void) nosideeffect;
|
|
const char *commandvenv(const char *, const char *);
|
|
int LogKprintfToFile(const char *);
|
|
const char *GetAddr2linePath(void);
|
|
const char *GetGdbPath(void);
|
|
void ShowCrashReports(void);
|
|
int MakeProcessNice(void);
|
|
bool32 IsDebuggerPresent(bool);
|
|
bool IsRunningUnderMake(void);
|
|
const char *GetSiCodeName(int, int);
|
|
char *GetSymbolByAddr(int64_t);
|
|
void PrintGarbage(void);
|
|
void PrintGarbageNumeric(FILE *);
|
|
void CheckForMemoryLeaks(void);
|
|
|
|
#ifndef __STRICT_ANSI__
|
|
|
|
#define _LOG_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
|
|
extern unsigned __log_level; /* log level for runtime check */
|
|
|
|
#define LOGGABLE(LEVEL) \
|
|
((!__builtin_constant_p(LEVEL) || (LEVEL) <= LOGGABLELEVEL) && \
|
|
(LEVEL) <= __log_level)
|
|
|
|
// log a message with the specified log level (not checking if LOGGABLE)
|
|
#define LOGF(LEVEL, FMT, ...) \
|
|
do { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
flogf(LEVEL, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} while (0)
|
|
|
|
// report an error without backtrace and debugger invocation
|
|
#define FATALF(FMT, ...) \
|
|
do { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
_log_exit(1); \
|
|
} while (0)
|
|
|
|
#define DIEF(FMT, ...) \
|
|
do { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
ffatalf(kLogFatal, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
__builtin_unreachable(); \
|
|
} while (0)
|
|
|
|
#define ERRORF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogError)) { \
|
|
LOGF(kLogError, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define WARNF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogWarn)) { \
|
|
LOGF(kLogWarn, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define INFOF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogInfo)) { \
|
|
LOGF(kLogInfo, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VERBOSEF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogVerbose)) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define DEBUGF(FMT, ...) \
|
|
do { \
|
|
if (_LOG_UNLIKELY(LOGGABLE(kLogDebug))) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define NOISEF(FMT, ...) \
|
|
do { \
|
|
if (_LOG_UNLIKELY(LOGGABLE(kLogNoise))) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
fnoisef(kLogNoise, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FLOGF(F, FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogInfo)) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FWARNF(F, FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogWarn)) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FFATALF(F, FMT, ...) \
|
|
do { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
flogf(kLogError, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
_log_exit(1); \
|
|
} while (0)
|
|
|
|
#define FDEBUGF(F, FMT, ...) \
|
|
do { \
|
|
if (_LOG_UNLIKELY(LOGGABLE(kLogDebug))) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FNOISEF(F, FMT, ...) \
|
|
do { \
|
|
if (_LOG_UNLIKELY(LOGGABLE(kLogNoise))) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
fnoisef(kLogNoise, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define LOGIFNEG1(FORM) \
|
|
({ \
|
|
int e = _log_get_errno(); \
|
|
autotype(FORM) Ax = (FORM); \
|
|
if (_LOG_UNLIKELY(Ax == (typeof(Ax))(-1)) && LOGGABLE(kLogWarn)) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
_log_errno(__FILE__, __LINE__, #FORM); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
_log_set_errno(e); \
|
|
} \
|
|
Ax; \
|
|
})
|
|
|
|
#define LOGIFNULL(FORM) \
|
|
({ \
|
|
int e = _log_get_errno(); \
|
|
autotype(FORM) Ax = (FORM); \
|
|
if (Ax == NULL && LOGGABLE(kLogWarn)) { \
|
|
if (!_LOG_TINY) _log_untrace(); \
|
|
_log_errno(__FILE__, __LINE__, #FORM); \
|
|
if (!_LOG_TINY) _log_retrace(); \
|
|
_log_set_errno(e); \
|
|
} \
|
|
Ax; \
|
|
})
|
|
|
|
void _log_errno(const char *, int, const char *) relegated;
|
|
int _log_get_errno(void);
|
|
void _log_set_errno(int);
|
|
void _log_untrace(void);
|
|
void _log_retrace(void);
|
|
void _log_exit(int) wontreturn;
|
|
|
|
#define ARGS unsigned, const char *, int, FILE *, const char *
|
|
#define ATTR paramsnonnull((5)) printfesque(5)
|
|
#define ATTRV paramsnonnull((5))
|
|
void flogf(ARGS, ...) ATTR libcesque;
|
|
void vflogf(ARGS, va_list) ATTRV libcesque;
|
|
void fverbosef(ARGS, ...) asm("flogf") ATTR relegated libcesque;
|
|
void vfverbosef(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
|
|
void fdebugf(ARGS, ...) asm("flogf") ATTR relegated libcesque;
|
|
void vfdebugf(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
|
|
void fnoisef(ARGS, ...) asm("flogf") ATTR relegated libcesque;
|
|
void vfnoisef(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
|
|
void ffatalf(ARGS, ...) asm("flogf") ATTR relegated wontreturn libcesque;
|
|
void vffatalf(ARGS, va_list) asm("vflogf") ATTRV relegated wontreturn libcesque;
|
|
#undef ARGS
|
|
#undef ATTR
|
|
#undef ATTRV
|
|
|
|
#endif /* __STRICT_ANSI__ */
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_LOG_LOG_H_ */
|