//---------------------------------------------------------------------------// // 1100101 |_ mov #0, r4 __ // // 11 |_ <0xb380 %5c4> / _|_ _____ ___ // // 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< // // |_ base# + offset |_| /_\_\___/__/ // //---------------------------------------------------------------------------// #include #include #include namespace FxOS { /* Currently configured log level */ static int loglevel = LOG_LEVEL_WRN; /* Level of the last message */ static int lastlevel = -1; /* Initialize log level depending on environment variable at startup */ __attribute__((constructor)) static void init_log_level(void) { char const *FXOS_LOG = std::getenv("FXOS_LOG"); if(!FXOS_LOG) return; if(!strcmp(FXOS_LOG, "LOG")) loglevel = LOG_LEVEL_LOG; else if(!strcmp(FXOS_LOG, "WRN")) loglevel = LOG_LEVEL_WRN; else if(!strcmp(FXOS_LOG, "ERR")) loglevel = LOG_LEVEL_ERR; else FxOS_log(WRN, "invalid FXOS_LOG value: %s", FXOS_LOG); } void log_setminlevel(int level) { loglevel = level; } int log_getminlevel() { return loglevel; } void logmsg(int level, char const *file, int line, char const *func, std::string message) { if(level < loglevel) return; bool endline = true; bool prefix = true; /* Add a newline if last line was unfinished, but level changed */ if(lastlevel >= 0 && lastlevel != level) std::cerr << '\n'; else if(lastlevel >= 0) prefix = false; if(message.size() > 0 && message.back() == '\\') { endline = false; message.pop_back(); } printf("\x1b[K"); if(prefix) { if(level == LOG_LEVEL_LOG) fprintf(stderr, "\e[30;1m[%s:%d@%s]\e[0m ", file, line, func); if(level == LOG_LEVEL_WRN) fprintf(stderr, "warning: "); if(level == LOG_LEVEL_ERR) fprintf(stderr, "\x1b[31;1merror:\x1b[0m "); } else fprintf(stderr, " "); fputs(message.c_str(), stderr); if(endline) { fputc('\n', stderr); lastlevel = -1; } else { lastlevel = level; } } } /* namespace FxOS */