diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ddbfd90b776db..506fb39cf7e04 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -215,9 +215,10 @@ jobs: uchardet \ v4l_compat \ vulkan-headers \ - wayland-protocols + wayland-protocols \ + gdb ./ci/build-freebsd.sh - meson test -C build + meson test -v -C build msys2: runs-on: windows-latest diff --git a/common/msg.c b/common/msg.c index f630d1ecc7620..4e96660710d08 100644 --- a/common/msg.c +++ b/common/msg.c @@ -293,41 +293,41 @@ bool mp_msg_has_status_line(struct mpv_global *global) return r; } -static void set_term_color(void *talloc_ctx, bstr *text, int c) -{ - return c == -1 ? bstr_xappend(talloc_ctx, text, bstr0("\033[0m")) - : bstr_xappend_asprintf(talloc_ctx, text, - "\033[%d;3%dm", c >> 3, c & 7); -} - -static void set_msg_color(void *talloc_ctx, bstr *text, int lev) -{ - static const int v_colors[] = {9, 1, 3, -1, -1, 2, 8, 8, 8, -1}; - return set_term_color(talloc_ctx, text, v_colors[lev]); -} - -static void pretty_print_module(struct mp_log_root *root, bstr *text, - const char *prefix, int lev) -{ - size_t prefix_len = strlen(prefix); - root->module_indent = MPMAX(10, MPMAX(root->module_indent, prefix_len)); - bool color = root->color[term_msg_fileno(root, lev)]; - - // Use random color based on the name of the module - if (color) { - unsigned int mod = 0; - for (int i = 0; i < prefix_len; ++i) - mod = mod * 33 + prefix[i]; - set_term_color(root, text, (mod + 1) % 15 + 1); - } - - bstr_xappend_asprintf(root, text, "%*s", root->module_indent, prefix); - if (color) - set_term_color(root, text, -1); - bstr_xappend(root, text, bstr0(": ")); - if (color) - set_msg_color(root, text, lev); -} +// static void set_term_color(void *talloc_ctx, bstr *text, int c) +// { +// return c == -1 ? bstr_xappend(talloc_ctx, text, bstr0("\033[0m")) +// : bstr_xappend_asprintf(talloc_ctx, text, +// "\033[%d;3%dm", c >> 3, c & 7); +// } + +// static void set_msg_color(void *talloc_ctx, bstr *text, int lev) +// { +// static const int v_colors[] = {9, 1, 3, -1, -1, 2, 8, 8, 8, -1}; +// return set_term_color(talloc_ctx, text, v_colors[lev]); +// } + +// static void pretty_print_module(struct mp_log_root *root, bstr *text, +// const char *prefix, int lev) +// { +// size_t prefix_len = strlen(prefix); +// root->module_indent = MPMAX(10, MPMAX(root->module_indent, prefix_len)); +// bool color = root->color[term_msg_fileno(root, lev)]; + +// // Use random color based on the name of the module +// if (color) { +// unsigned int mod = 0; +// for (int i = 0; i < prefix_len; ++i) +// mod = mod * 33 + prefix[i]; +// set_term_color(root, text, (mod + 1) % 15 + 1); +// } + +// bstr_xappend_asprintf(root, text, "%*s", root->module_indent, prefix); +// if (color) +// set_term_color(root, text, -1); +// bstr_xappend(root, text, bstr0(": ")); +// if (color) +// set_msg_color(root, text, lev); +// } static bool test_terminal_level(struct mp_log *log, int lev) { @@ -335,62 +335,62 @@ static bool test_terminal_level(struct mp_log *log, int lev) !(lev == MSGL_STATUS && terminal_in_background()); } -// This is very basic way to infer needed width for a string. -static int term_disp_width(bstr str, size_t start, size_t end) -{ - int width = 0; - bool escape = false; - - const char *line = str.start; - for (size_t i = start; i < end && i < str.len; ++i) { - if (escape) { - escape = !(line[i] >= '@' && line[i] <= '~'); - continue; - } - - if (line[i] == '\033' && line[i + 1] == '[') { - escape = true; - ++i; - continue; - } - - if (line[i] == '\n') - continue; - - width++; - - // Assume that everything before \r should be discarded for simplicity - if (line[i] == '\r') - width = 0; - } - - return width; -} - -static void append_terminal_line(struct mp_log *log, int lev, - bstr text, bstr *term_msg, int *line_w) -{ - struct mp_log_root *root = log->root; - - size_t start = term_msg->len; - - if (root->show_time) - bstr_xappend_asprintf(root, term_msg, "[%10.6f] ", mp_time_sec()); - - const char *log_prefix = (lev >= MSGL_V) || root->verbose || root->module - ? log->verbose_prefix : log->prefix; - if (log_prefix) { - if (root->module) { - pretty_print_module(root, term_msg, log_prefix, lev); - } else { - bstr_xappend_asprintf(root, term_msg, "[%s] ", log_prefix); - } - } - - bstr_xappend(root, term_msg, text); - *line_w = root->isatty[term_msg_fileno(root, lev)] - ? term_disp_width(*term_msg, start, term_msg->len) : 0; -} +// // This is very basic way to infer needed width for a string. +// static int term_disp_width(bstr str, size_t start, size_t end) +// { +// int width = 0; +// bool escape = false; + +// const char *line = str.start; +// for (size_t i = start; i < end && i < str.len; ++i) { +// if (escape) { +// escape = !(line[i] >= '@' && line[i] <= '~'); +// continue; +// } + +// if (line[i] == '\033' && line[i + 1] == '[') { +// escape = true; +// ++i; +// continue; +// } + +// if (line[i] == '\n') +// continue; + +// width++; + +// // Assume that everything before \r should be discarded for simplicity +// if (line[i] == '\r') +// width = 0; +// } + +// return width; +// } + +// static void append_terminal_line(struct mp_log *log, int lev, +// bstr text, bstr *term_msg, int *line_w) +// { +// struct mp_log_root *root = log->root; + +// size_t start = term_msg->len; + +// if (root->show_time) +// bstr_xappend_asprintf(root, term_msg, "[%10.6f] ", mp_time_sec()); + +// const char *log_prefix = (lev >= MSGL_V) || root->verbose || root->module +// ? log->verbose_prefix : log->prefix; +// if (log_prefix) { +// if (root->module) { +// pretty_print_module(root, term_msg, log_prefix, lev); +// } else { +// bstr_xappend_asprintf(root, term_msg, "[%s] ", log_prefix); +// } +// } + +// bstr_xappend(root, term_msg, text); +// *line_w = root->isatty[term_msg_fileno(root, lev)] +// ? term_disp_width(*term_msg, start, term_msg->len) : 0; +// } static struct mp_log_buffer_entry *log_buffer_read(struct mp_log_buffer *buffer) { @@ -401,60 +401,60 @@ static struct mp_log_buffer_entry *log_buffer_read(struct mp_log_buffer *buffer) return res; } -static void write_msg_to_buffers(struct mp_log *log, int lev, bstr text) -{ - struct mp_log_root *root = log->root; - for (int n = 0; n < root->num_buffers; n++) { - struct mp_log_buffer *buffer = root->buffers[n]; - bool wakeup = false; - mp_mutex_lock(&buffer->lock); - int buffer_level = buffer->level; - if (buffer_level == MP_LOG_BUFFER_MSGL_TERM) - buffer_level = log->terminal_level; - if (buffer_level == MP_LOG_BUFFER_MSGL_LOGFILE) - buffer_level = MPMAX(log->terminal_level, MSGL_DEBUG); - if (lev <= buffer_level && lev != MSGL_STATUS) { - if (buffer->level == MP_LOG_BUFFER_MSGL_LOGFILE) { - // If the buffer is full, block until we can write again, - // unless there's no write thread (died, or early filebuffer) - bool dead = false; - while (buffer->num_entries == buffer->capacity && !dead) { - // Temporary unlock is OK; buffer->level is immutable, and - // buffer can't go away because the global log lock is held. - mp_mutex_unlock(&buffer->lock); - mp_mutex_lock(&root->log_file_lock); - if (root->log_file_thread_active) { - mp_cond_wait(&root->log_file_wakeup, - &root->log_file_lock); - } else { - dead = true; - } - mp_mutex_unlock(&root->log_file_lock); - mp_mutex_lock(&buffer->lock); - } - } - if (buffer->num_entries == buffer->capacity) { - struct mp_log_buffer_entry *skip = log_buffer_read(buffer); - talloc_free(skip); - buffer->dropped += 1; - } - struct mp_log_buffer_entry *entry = talloc_ptrtype(NULL, entry); - *entry = (struct mp_log_buffer_entry) { - .prefix = talloc_strdup(entry, log->verbose_prefix), - .level = lev, - .text = bstrdup0(entry, text), - }; - int pos = (buffer->entry0 + buffer->num_entries) % buffer->capacity; - buffer->entries[pos] = entry; - buffer->num_entries += 1; - if (buffer->wakeup_cb && !buffer->silent) - wakeup = true; - } - mp_mutex_unlock(&buffer->lock); - if (wakeup) - buffer->wakeup_cb(buffer->wakeup_cb_ctx); - } -} +// static void write_msg_to_buffers(struct mp_log *log, int lev, bstr text) +// { +// struct mp_log_root *root = log->root; +// for (int n = 0; n < root->num_buffers; n++) { +// struct mp_log_buffer *buffer = root->buffers[n]; +// bool wakeup = false; +// mp_mutex_lock(&buffer->lock); +// int buffer_level = buffer->level; +// if (buffer_level == MP_LOG_BUFFER_MSGL_TERM) +// buffer_level = log->terminal_level; +// if (buffer_level == MP_LOG_BUFFER_MSGL_LOGFILE) +// buffer_level = MPMAX(log->terminal_level, MSGL_DEBUG); +// if (lev <= buffer_level && lev != MSGL_STATUS) { +// if (buffer->level == MP_LOG_BUFFER_MSGL_LOGFILE) { +// // If the buffer is full, block until we can write again, +// // unless there's no write thread (died, or early filebuffer) +// bool dead = false; +// while (buffer->num_entries == buffer->capacity && !dead) { +// // Temporary unlock is OK; buffer->level is immutable, and +// // buffer can't go away because the global log lock is held. +// mp_mutex_unlock(&buffer->lock); +// mp_mutex_lock(&root->log_file_lock); +// if (root->log_file_thread_active) { +// mp_cond_wait(&root->log_file_wakeup, +// &root->log_file_lock); +// } else { +// dead = true; +// } +// mp_mutex_unlock(&root->log_file_lock); +// mp_mutex_lock(&buffer->lock); +// } +// } +// if (buffer->num_entries == buffer->capacity) { +// struct mp_log_buffer_entry *skip = log_buffer_read(buffer); +// talloc_free(skip); +// buffer->dropped += 1; +// } +// struct mp_log_buffer_entry *entry = talloc_ptrtype(NULL, entry); +// *entry = (struct mp_log_buffer_entry) { +// .prefix = talloc_strdup(entry, log->verbose_prefix), +// .level = lev, +// .text = bstrdup0(entry, text), +// }; +// int pos = (buffer->entry0 + buffer->num_entries) % buffer->capacity; +// buffer->entries[pos] = entry; +// buffer->num_entries += 1; +// if (buffer->wakeup_cb && !buffer->silent) +// wakeup = true; +// } +// mp_mutex_unlock(&buffer->lock); +// if (wakeup) +// buffer->wakeup_cb(buffer->wakeup_cb_ctx); +// } +// } static void dump_stats(struct mp_log *log, int lev, bstr text) { @@ -463,59 +463,60 @@ static void dump_stats(struct mp_log *log, int lev, bstr text) fprintf(root->stats_file, "%"PRId64" %.*s\n", mp_time_ns(), BSTR_P(text)); } -static void write_term_msg(struct mp_log *log, int lev, bstr text, bstr *out) -{ - struct mp_log_root *root = log->root; - bool print_term = test_terminal_level(log, lev); - int fileno = term_msg_fileno(root, lev); - int term_w = 0, term_h = 0; - if (print_term && root->isatty[fileno]) - terminal_get_size(&term_w, &term_h); - - out->len = 0; - - // Split away each line. Normally we require full lines; buffer partial - // lines if they happen. - root->term_msg_tmp.len = 0; - int term_msg_lines = 0; - - bstr str = text; - while (str.len) { - bstr line = bstr_getline(str, &str); - if (line.start[line.len - 1] != '\n') { - assert(str.len == 0); - str = line; - break; - } - - if (print_term) { - int line_w; - append_terminal_line(log, lev, line, &root->term_msg_tmp, &line_w); - term_msg_lines += (!line_w || !term_w) - ? 1 : (line_w + term_w - 1) / term_w; - } - write_msg_to_buffers(log, lev, line); - } - - if (lev == MSGL_STATUS && print_term) { - int line_w = 0; - if (str.len) - append_terminal_line(log, lev, str, &root->term_msg_tmp, &line_w); - term_msg_lines += !term_w ? (str.len ? 1 : 0) - : (line_w + term_w - 1) / term_w; - } else if (str.len) { - bstr_xappend(NULL, &log->partial[lev], str); - } - - if (print_term && (root->term_msg_tmp.len || lev == MSGL_STATUS)) { - prepare_prefix(root, out, lev, term_msg_lines); - if (root->color[fileno] && root->term_msg_tmp.len) { - set_msg_color(root, out, lev); - set_term_color(root, &root->term_msg_tmp, -1); - } - bstr_xappend(root, out, root->term_msg_tmp); - } -} +// static void write_term_msg(struct mp_log *log, int lev, bstr text, bstr *out) +// { +// struct mp_log_root *root = log->root; +// // bool print_term = test_terminal_level(log, lev); +// bool print_term = false; +// int fileno = term_msg_fileno(root, lev); +// int term_w = 0, term_h = 0; +// if (print_term && root->isatty[fileno]) +// terminal_get_size(&term_w, &term_h); + +// out->len = 0; + +// // Split away each line. Normally we require full lines; buffer partial +// // lines if they happen. +// root->term_msg_tmp.len = 0; +// int term_msg_lines = 0; + +// bstr str = text; +// while (str.len) { +// bstr line = bstr_getline(str, &str); +// if (line.start[line.len - 1] != '\n') { +// assert(str.len == 0); +// str = line; +// break; +// } + +// if (print_term) { +// int line_w; +// append_terminal_line(log, lev, line, &root->term_msg_tmp, &line_w); +// term_msg_lines += (!line_w || !term_w) +// ? 1 : (line_w + term_w - 1) / term_w; +// } +// write_msg_to_buffers(log, lev, line); +// } + +// if (lev == MSGL_STATUS && print_term) { +// int line_w = 0; +// if (str.len) +// append_terminal_line(log, lev, str, &root->term_msg_tmp, &line_w); +// term_msg_lines += !term_w ? (str.len ? 1 : 0) +// : (line_w + term_w - 1) / term_w; +// } else if (str.len) { +// bstr_xappend(NULL, &log->partial[lev], str); +// } + +// if (print_term && (root->term_msg_tmp.len || lev == MSGL_STATUS)) { +// prepare_prefix(root, out, lev, term_msg_lines); +// if (root->color[fileno] && root->term_msg_tmp.len) { +// set_msg_color(root, out, lev); +// set_term_color(root, &root->term_msg_tmp, -1); +// } +// bstr_xappend(root, out, root->term_msg_tmp); +// } +// } void mp_msg_va(struct mp_log *log, int lev, const char *format, va_list va) { @@ -549,27 +550,27 @@ void mp_msg_va(struct mp_log *log, int lev, const char *format, va_list va) } else if (lev == MSGL_STATUS && !test_terminal_level(log, lev)) { /* discard */ } else { - write_term_msg(log, lev, root->buffer, &root->term_msg); - - root->term_status_msg.len = 0; - if (lev != MSGL_STATUS && root->status_line.len && root->status_log && - test_terminal_level(root->status_log, MSGL_STATUS)) - { - write_term_msg(root->status_log, MSGL_STATUS, root->status_line, - &root->term_status_msg); - } - - int fileno = term_msg_fileno(root, lev); - FILE *stream = fileno == STDERR_FILENO ? stderr : stdout; - if (root->term_msg.len) { - if (root->term_status_msg.len) { - fprintf(stream, "%.*s%.*s", BSTR_P(root->term_msg), - BSTR_P(root->term_status_msg)); - } else { - fprintf(stream, "%.*s", BSTR_P(root->term_msg)); - } - fflush(stream); - } + // write_term_msg(log, lev, root->buffer, &root->term_msg); + + // root->term_status_msg.len = 0; + // if (lev != MSGL_STATUS && root->status_line.len && root->status_log && + // test_terminal_level(root->status_log, MSGL_STATUS)) + // { + // write_term_msg(root->status_log, MSGL_STATUS, root->status_line, + // &root->term_status_msg); + // } + + // int fileno = term_msg_fileno(root, lev); + // FILE *stream = fileno == STDERR_FILENO ? stderr : stdout; + // if (root->term_msg.len) { + // if (root->term_status_msg.len) { + // fprintf(stream, "%.*s%.*s", BSTR_P(root->term_msg), + // BSTR_P(root->term_status_msg)); + // } else { + // fprintf(stream, "%.*s", BSTR_P(root->term_msg)); + // } + // fflush(stream); + // } } mp_mutex_unlock(&root->lock);