233 lines
11 KiB
C
233 lines
11 KiB
C
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
|
|
#define COSMOPOLITAN_LIBC_LOG_LOG_H_
|
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
|
│ cosmopolitan § liblog ─╬─│┼
|
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
|
|
|
#define kLogFatal 0u
|
|
#define kLogError 1u
|
|
#define kLogWarn 2u
|
|
#define kLogInfo 3u
|
|
#define kLogVerbose 4u
|
|
#define kLogDebug 5u
|
|
|
|
/**
|
|
* Log level for compile-time DCE.
|
|
*/
|
|
#ifndef LOGGABLELEVEL
|
|
#ifndef NDEBUG
|
|
#define LOGGABLELEVEL kLogDebug
|
|
/* #elif IsTiny() */
|
|
/* #define LOGGABLELEVEL kLogInfo */
|
|
#else
|
|
#define LOGGABLELEVEL kLogVerbose
|
|
#endif
|
|
#endif
|
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
struct sigset;
|
|
struct winsize;
|
|
struct StackFrame;
|
|
typedef struct FILE FILE;
|
|
|
|
extern FILE *g_logfile;
|
|
|
|
void backtrace(FILE *) relegated; /* shows fn backtrace and args */
|
|
void perror(const char *) relegated; /* print the last system error */
|
|
void die(void) relegated noreturn; /* print backtrace and abort() */
|
|
void meminfo(int); /* shows malloc statistics &c. */
|
|
void memsummary(int); /* light version of same thing */
|
|
uint16_t getttycols(uint16_t);
|
|
int getttysize(int, struct winsize *) paramsnonnull();
|
|
bool cancolor(void) nothrow nocallback;
|
|
bool isterminalinarticulate(void) nosideeffect;
|
|
char *commandvenv(const char *, const char *) nodiscard;
|
|
const char *GetAddr2linePath(void);
|
|
const char *GetGdbPath(void);
|
|
|
|
void showcrashreports(void);
|
|
void callexitontermination(struct sigset *);
|
|
bool32 IsDebuggerPresent(bool);
|
|
bool isrunningundermake(void);
|
|
void showbacktrace(FILE *, const struct StackFrame *);
|
|
|
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
|
│ cosmopolitan § liblog » logging ─╬─│┼
|
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
|
|
|
extern unsigned g_loglevel; /* log level for runtime check */
|
|
|
|
#define LOGGABLE(LEVEL) \
|
|
((!isconstant(LEVEL) || (LEVEL) <= LOGGABLELEVEL) && (LEVEL) <= g_loglevel)
|
|
|
|
#define LOGF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogInfo)) { \
|
|
flogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VFLOG(FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogInfo)) { \
|
|
vflogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FLOGF(F, FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogInfo)) { \
|
|
flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VFLOGF(F, FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogInfo)) { \
|
|
vflogf(kLogInfo, __FILE__, __LINE__, F, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define WARNF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogWarn)) { \
|
|
flogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VWARNF(FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogWarn)) { \
|
|
vflogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FWARNF(F, FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogWarn)) { \
|
|
flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VFWARNF(F, FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogWarn)) { \
|
|
vflogf(kLogWarn, __FILE__, __LINE__, F, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FATALF(FMT, ...) \
|
|
do { \
|
|
ffatalf(kLogFatal, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
unreachable; \
|
|
} while (0)
|
|
|
|
#define VFATALF(FMT, VA) \
|
|
do { \
|
|
vffatalf(kLogFatal, __FILE__, __LINE__, NULL, FMT, VA); \
|
|
unreachable; \
|
|
} while (0)
|
|
|
|
#define FFATALF(F, FMT, ...) \
|
|
do { \
|
|
ffatalf(kLogFatal, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
unreachable; \
|
|
} while (0)
|
|
|
|
#define VFFATALF(F, FMT, VA) \
|
|
do { \
|
|
vffatalf(kLogFatal, __FILE__, __LINE__, F, FMT, VA); \
|
|
unreachable; \
|
|
} while (0)
|
|
|
|
#define DEBUGF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogDebug)) { \
|
|
fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VERBOSEF(FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogVerbose)) { \
|
|
fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VDEBUGF(FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogDebug)) { \
|
|
vfdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FDEBUGF(F, FMT, ...) \
|
|
do { \
|
|
if (LOGGABLE(kLogDebug)) { \
|
|
fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VFVERBOSEF(F, FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogVerbose)) { \
|
|
vfverbosef(kLogVerbose, __FILE__, __LINE__, F, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define VFDEBUGF(F, FMT, VA) \
|
|
do { \
|
|
if (LOGGABLE(kLogDebug)) { \
|
|
vfdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, VA); \
|
|
} \
|
|
} while (0)
|
|
|
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
|
│ cosmopolitan § liblog » on error resume next ─╬─│┼
|
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
|
|
|
#define LOGIFNEG1(FORM) \
|
|
({ \
|
|
autotype(FORM) Ax = (FORM); \
|
|
if (Ax == (typeof(Ax))(-1) && LOGGABLE(kLogWarn)) { \
|
|
__logerrno(__FILE__, __LINE__, #FORM); \
|
|
} \
|
|
Ax; \
|
|
})
|
|
|
|
#define LOGIFNULL(FORM) \
|
|
({ \
|
|
autotype(FORM) Ax = (FORM); \
|
|
if (Ax == NULL && LOGGABLE(kLogWarn)) { \
|
|
__logerrno(__FILE__, __LINE__, #FORM); \
|
|
} \
|
|
Ax; \
|
|
})
|
|
|
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
|
│ cosmopolitan § liblog » implementation details ─╬─│┼
|
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
|
|
|
void __logerrno(const char *, int, const char *) relegated;
|
|
|
|
#define ARGS unsigned, const char *, int, FILE *, const char *
|
|
#define ATTR paramsnonnull((5)) printfesque(5)
|
|
#define ATTRV paramsnonnull((5, 6))
|
|
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 ffatalf(ARGS, ...) asm("flogf") ATTR relegated noreturn libcesque;
|
|
void vffatalf(ARGS, va_list) asm("vflogf") ATTRV relegated noreturn libcesque;
|
|
#undef ARGS
|
|
#undef ATTR
|
|
#undef ATTRV
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_LOG_LOG_H_ */
|