kstr *kdclient_format_error(const char *file, int line, const char *msg, va_list va) { char *p; kstr *err_msg, *err; kstr err_fmt; /* Search for @ */ p = strstr(msg, "@"); if (p) { kstr_init_buf(&err_fmt, msg, p - msg); err_msg = kerror_str_n(0); kstr_append_kstr(&err_fmt, err_msg); kstr_destroy(err_msg); kstr_append_cstr(&err_fmt, p + 1); } else kstr_init_cstr(&err_fmt, msg); err = kmalloc(sizeof(kstr)); kstr_init_sfv(err, err_fmt.data, va); /* Add [file:line] before error message. */ kstr_sf(&err_fmt, "[%s:%d] %s", file, line, err->data); kstr_assign_kstr(err, &err_fmt); kstr_clean(&err_fmt); return err; }
static void kdclient_log_very_internal(int is_err, const char *file, int line, const char *log_channel, const char *msg, va_list va) { struct kerror *error_instance = kerror_get_current(); int i, level = (is_err ? LOG_ERR : LOG_WARNING); kstr err; kstr_init_sfv(&err, msg, va); log_write_line(level, log_channel, file, line, "%s", err.data); if (error_instance->stack.size <= 0) { kstr_clean(&err); return; } if (is_err) log_write(level, log_channel, "*** Error stack ***"); else log_write(level, log_channel, "*** Warning stack ***"); for (i = 0; i < error_instance->stack.size; i++) { struct kerror_node *en = (struct kerror_node *)karray_get(&error_instance->stack, i); log_write(level, log_channel, "[%s:%d] %s", en->file, en->line, en->text.data); } log_write(level, log_channel, "*** End ***"); kstr_clean(&err); }
void kstr_init_sf(kstr *self, const char *format, ...) { va_list args; va_start(args, format); kstr_init_sfv(self, format, args); va_end(args); }