X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcommon%2Fcommon.c;h=b0d048772ef5ad8c56e471a91c3c5f8e22f6e2d0;hb=ecd7492f21a492b70569d5ecc1d3a808241b63f0;hp=dacb5054fa04280e04a0f44b0bc7af2a1bb7eb20;hpb=5ab3582ba148e9e5c7c86bd277b6bdbd56465bbd;p=babeltrace.git diff --git a/src/common/common.c b/src/common/common.c index dacb5054..b0d04877 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -1,25 +1,9 @@ /* - * Babeltrace common functions + * SPDX-License-Identifier: MIT * * Copyright 2016 Philippe Proulx * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Babeltrace common functions */ #define BT_LOG_OUTPUT_LEVEL log_level @@ -43,6 +27,7 @@ #include "common/macros.h" #include "common/common.h" #include "compat/unistd.h" +#include "compat/limits.h" #ifndef __MINGW32__ #include @@ -63,6 +48,13 @@ static const char *bt_common_color_code_fg_blue = ""; static const char *bt_common_color_code_fg_magenta = ""; static const char *bt_common_color_code_fg_cyan = ""; static const char *bt_common_color_code_fg_light_gray = ""; +static const char *bt_common_color_code_fg_bright_red = ""; +static const char *bt_common_color_code_fg_bright_green = ""; +static const char *bt_common_color_code_fg_bright_yellow = ""; +static const char *bt_common_color_code_fg_bright_blue = ""; +static const char *bt_common_color_code_fg_bright_magenta = ""; +static const char *bt_common_color_code_fg_bright_cyan = ""; +static const char *bt_common_color_code_fg_bright_light_gray = ""; static const char *bt_common_color_code_bg_default = ""; static const char *bt_common_color_code_bg_red = ""; static const char *bt_common_color_code_bg_green = ""; @@ -72,9 +64,106 @@ static const char *bt_common_color_code_bg_magenta = ""; static const char *bt_common_color_code_bg_cyan = ""; static const char *bt_common_color_code_bg_light_gray = ""; +/* + * A color codes structure always filled with the proper color codes for the + * terminal. + */ +static struct bt_common_color_codes color_codes; + +/* + * A color codes structure always filled with empty strings, for when we want no + * colors. + */ +static struct bt_common_color_codes no_color_codes = { + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", +}; + static void __attribute__((constructor)) bt_common_color_ctor(void) { + const char *term_env_var; + const char *bright_means_bold_env_var; + bool bright_means_bold = true; + const char *code_fg_bright_red; + const char *code_fg_bright_green; + const char *code_fg_bright_yellow; + const char *code_fg_bright_blue; + const char *code_fg_bright_magenta; + const char *code_fg_bright_cyan; + const char *code_fg_bright_light_gray; + + /* + * Check whether or not the terminal supports having + * bold foreground colors which do _not_ become bright + * colors, that is, the lines + * + * $ echo -e "\033[31mTHIS\n\033[1mTHAT\033[0m" + * + * have the _same_ color, but `THAT` uses a bold font. + * + * This is the case of the kitty terminal emulator. + * + * It's also possible with GNOME Terminal since 3.27.2 + * and xfce4-terminal since 0.8.7 (and GNOME VTE since + * 0.51.2), but it's user-configurable. Since we don't + * have this configuration value here, assume it's not + * the case to support old versions of GNOME Terminal. + * + * Any user can set the + * `BABELTRACE_TERM_COLOR_BRIGHT_MEANS_BOLD` environment + * variable to `0` to use the bright foreground color + * codes instead of making the normal foreground color + * codes bold. + * + * Summary: + * + * With kitty or when + * `BABELTRACE_TERM_COLOR_BRIGHT_MEANS_BOLD` is `0`: + * Output bright colors using dedicated SGR codes + * 90 to 97. + * + * Otherwise: + * Output bright colors with bold + SGR codes 30 to + * 37. + */ + term_env_var = getenv("TERM"); + + if (term_env_var && strcmp(term_env_var, "xterm-kitty") == 0) { + /* + * The kitty terminal emulator supports + * non-bright bold foreground colors. + */ + bright_means_bold = false; + } + + bright_means_bold_env_var = + getenv("BABELTRACE_TERM_COLOR_BRIGHT_MEANS_BOLD"); + + if (bright_means_bold_env_var) { + bright_means_bold = + !(strcmp(bright_means_bold_env_var, "0") == 0); + } + + if (bright_means_bold) { + code_fg_bright_red = BT_COMMON_COLOR_FG_BOLD_RED; + code_fg_bright_green = BT_COMMON_COLOR_FG_BOLD_GREEN; + code_fg_bright_yellow = BT_COMMON_COLOR_FG_BOLD_YELLOW; + code_fg_bright_blue = BT_COMMON_COLOR_FG_BOLD_BLUE; + code_fg_bright_magenta = BT_COMMON_COLOR_FG_BOLD_MAGENTA; + code_fg_bright_cyan = BT_COMMON_COLOR_FG_BOLD_CYAN; + code_fg_bright_light_gray = BT_COMMON_COLOR_FG_BOLD_LIGHT_GRAY; + } else { + code_fg_bright_red = BT_COMMON_COLOR_FG_BRIGHT_RED; + code_fg_bright_green = BT_COMMON_COLOR_FG_BRIGHT_GREEN; + code_fg_bright_yellow = BT_COMMON_COLOR_FG_BRIGHT_YELLOW; + code_fg_bright_blue = BT_COMMON_COLOR_FG_BRIGHT_BLUE; + code_fg_bright_magenta = BT_COMMON_COLOR_FG_BRIGHT_MAGENTA; + code_fg_bright_cyan = BT_COMMON_COLOR_FG_BRIGHT_CYAN; + code_fg_bright_light_gray = BT_COMMON_COLOR_FG_BRIGHT_LIGHT_GRAY; + } + if (bt_common_colors_supported()) { bt_common_color_code_reset = BT_COMMON_COLOR_RESET; bt_common_color_code_bold = BT_COMMON_COLOR_BOLD; @@ -86,6 +175,15 @@ void __attribute__((constructor)) bt_common_color_ctor(void) bt_common_color_code_fg_magenta = BT_COMMON_COLOR_FG_MAGENTA; bt_common_color_code_fg_cyan = BT_COMMON_COLOR_FG_CYAN; bt_common_color_code_fg_light_gray = BT_COMMON_COLOR_FG_LIGHT_GRAY; + + bt_common_color_code_fg_bright_red = code_fg_bright_red; + bt_common_color_code_fg_bright_green = code_fg_bright_green; + bt_common_color_code_fg_bright_yellow = code_fg_bright_yellow; + bt_common_color_code_fg_bright_blue = code_fg_bright_blue; + bt_common_color_code_fg_bright_magenta = code_fg_bright_magenta; + bt_common_color_code_fg_bright_cyan = code_fg_bright_cyan; + bt_common_color_code_fg_bright_light_gray = code_fg_bright_light_gray; + bt_common_color_code_bg_default = BT_COMMON_COLOR_BG_DEFAULT; bt_common_color_code_bg_red = BT_COMMON_COLOR_BG_RED; bt_common_color_code_bg_green = BT_COMMON_COLOR_BG_GREEN; @@ -95,22 +193,45 @@ void __attribute__((constructor)) bt_common_color_ctor(void) bt_common_color_code_bg_cyan = BT_COMMON_COLOR_BG_CYAN; bt_common_color_code_bg_light_gray = BT_COMMON_COLOR_BG_LIGHT_GRAY; } + + color_codes.reset = BT_COMMON_COLOR_RESET; + color_codes.bold = BT_COMMON_COLOR_BOLD; + color_codes.fg_default = BT_COMMON_COLOR_FG_DEFAULT; + color_codes.fg_red = BT_COMMON_COLOR_FG_RED; + color_codes.fg_green = BT_COMMON_COLOR_FG_GREEN; + color_codes.fg_yellow = BT_COMMON_COLOR_FG_YELLOW; + color_codes.fg_blue = BT_COMMON_COLOR_FG_BLUE; + color_codes.fg_magenta = BT_COMMON_COLOR_FG_MAGENTA; + color_codes.fg_cyan = BT_COMMON_COLOR_FG_CYAN; + color_codes.fg_light_gray = BT_COMMON_COLOR_FG_LIGHT_GRAY; + color_codes.fg_bright_red = code_fg_bright_red; + color_codes.fg_bright_green = code_fg_bright_green; + color_codes.fg_bright_yellow = code_fg_bright_yellow; + color_codes.fg_bright_blue = code_fg_bright_blue; + color_codes.fg_bright_magenta = code_fg_bright_magenta; + color_codes.fg_bright_cyan = code_fg_bright_cyan; + color_codes.fg_bright_light_gray = code_fg_bright_light_gray; + color_codes.bg_default = BT_COMMON_COLOR_BG_DEFAULT; + color_codes.bg_red = BT_COMMON_COLOR_BG_RED; + color_codes.bg_green = BT_COMMON_COLOR_BG_GREEN; + color_codes.bg_yellow = BT_COMMON_COLOR_BG_YELLOW; + color_codes.bg_blue = BT_COMMON_COLOR_BG_BLUE; + color_codes.bg_magenta = BT_COMMON_COLOR_BG_MAGENTA; + color_codes.bg_cyan = BT_COMMON_COLOR_BG_CYAN; + color_codes.bg_light_gray = BT_COMMON_COLOR_BG_LIGHT_GRAY; } -BT_HIDDEN const char *bt_common_get_system_plugin_path(void) { return SYSTEM_PLUGIN_PATH; } #ifdef __MINGW32__ -BT_HIDDEN bool bt_common_is_setuid_setgid(void) { return false; } #else /* __MINGW32__ */ -BT_HIDDEN bool bt_common_is_setuid_setgid(void) { return (geteuid() != getuid() || getegid() != getgid()); @@ -119,7 +240,7 @@ bool bt_common_is_setuid_setgid(void) #ifdef __MINGW32__ static -const char *bt_get_home_dir(int log_level) +const char *bt_get_home_dir(int log_level __attribute__((unused))) { return g_get_home_dir(); } @@ -156,7 +277,6 @@ end: } #endif /* __MINGW32__ */ -BT_HIDDEN char *bt_common_get_home_plugin_path(int log_level) { char *path = NULL; @@ -188,7 +308,6 @@ end: return path; } -BT_HIDDEN int bt_common_append_plugin_path_dirs(const char *paths, GPtrArray *dirs) { int ret = 0; @@ -272,7 +391,6 @@ end: return istty; } -BT_HIDDEN bool bt_common_colors_supported(void) { static bool supports_colors = false; @@ -328,115 +446,149 @@ end: return supports_colors; } -BT_HIDDEN const char *bt_common_color_reset(void) { return bt_common_color_code_reset; } -BT_HIDDEN const char *bt_common_color_bold(void) { return bt_common_color_code_bold; } -BT_HIDDEN const char *bt_common_color_fg_default(void) { return bt_common_color_code_fg_default; } -BT_HIDDEN const char *bt_common_color_fg_red(void) { return bt_common_color_code_fg_red; } -BT_HIDDEN const char *bt_common_color_fg_green(void) { return bt_common_color_code_fg_green; } -BT_HIDDEN const char *bt_common_color_fg_yellow(void) { return bt_common_color_code_fg_yellow; } -BT_HIDDEN const char *bt_common_color_fg_blue(void) { return bt_common_color_code_fg_blue; } -BT_HIDDEN const char *bt_common_color_fg_magenta(void) { return bt_common_color_code_fg_magenta; } -BT_HIDDEN const char *bt_common_color_fg_cyan(void) { return bt_common_color_code_fg_cyan; } -BT_HIDDEN const char *bt_common_color_fg_light_gray(void) { return bt_common_color_code_fg_light_gray; } -BT_HIDDEN +const char *bt_common_color_fg_bright_red(void) +{ + return bt_common_color_code_fg_bright_red; +} + +const char *bt_common_color_fg_bright_green(void) +{ + return bt_common_color_code_fg_bright_green; +} + +const char *bt_common_color_fg_bright_yellow(void) +{ + return bt_common_color_code_fg_bright_yellow; +} + +const char *bt_common_color_fg_bright_blue(void) +{ + return bt_common_color_code_fg_bright_blue; +} + +const char *bt_common_color_fg_bright_magenta(void) +{ + return bt_common_color_code_fg_bright_magenta; +} + +const char *bt_common_color_fg_bright_cyan(void) +{ + return bt_common_color_code_fg_bright_cyan; +} + +const char *bt_common_color_fg_bright_light_gray(void) +{ + return bt_common_color_code_fg_bright_light_gray; +} + const char *bt_common_color_bg_default(void) { return bt_common_color_code_bg_default; } -BT_HIDDEN const char *bt_common_color_bg_red(void) { return bt_common_color_code_bg_red; } -BT_HIDDEN const char *bt_common_color_bg_green(void) { return bt_common_color_code_bg_green; } -BT_HIDDEN const char *bt_common_color_bg_yellow(void) { return bt_common_color_code_bg_yellow; } -BT_HIDDEN const char *bt_common_color_bg_blue(void) { return bt_common_color_code_bg_blue; } -BT_HIDDEN const char *bt_common_color_bg_magenta(void) { return bt_common_color_code_bg_magenta; } -BT_HIDDEN const char *bt_common_color_bg_cyan(void) { return bt_common_color_code_bg_cyan; } -BT_HIDDEN const char *bt_common_color_bg_light_gray(void) { return bt_common_color_code_bg_light_gray; } -BT_HIDDEN +void bt_common_color_get_codes(struct bt_common_color_codes *codes, + enum bt_common_color_when use_colors) +{ + if (use_colors == BT_COMMON_COLOR_WHEN_ALWAYS) { + *codes = color_codes; + } else if (use_colors == BT_COMMON_COLOR_WHEN_NEVER) { + *codes = no_color_codes; + } else { + BT_ASSERT(use_colors == BT_COMMON_COLOR_WHEN_AUTO); + + if (bt_common_colors_supported()) { + *codes = color_codes; + } else { + *codes = no_color_codes; + } + } +} + GString *bt_common_string_until(const char *input, const char *escapable_chars, const char *end_chars, size_t *end_pos) { @@ -512,13 +664,13 @@ set_end_pos: error: if (output) { g_string_free(output, TRUE); + output = NULL; } end: return output; } -BT_HIDDEN GString *bt_common_shell_quote(const char *input, bool with_single_quotes) { GString *output = g_string_new(NULL); @@ -574,15 +726,14 @@ end: return output; } -BT_HIDDEN bool bt_common_string_is_printable(const char *input) { const char *ch; bool printable = true; - BT_ASSERT(input); + BT_ASSERT_DBG(input); for (ch = input; *ch != '\0'; ch++) { - if (!isprint(*ch) && *ch != '\n' && *ch != '\r' && + if (!isprint((unsigned char) *ch) && *ch != '\n' && *ch != '\r' && *ch != '\t' && *ch != '\v') { printable = false; goto end; @@ -593,7 +744,6 @@ end: return printable; } -BT_HIDDEN void bt_common_destroy_lttng_live_url_parts( struct bt_common_lttng_live_url_parts *parts) { @@ -625,7 +775,6 @@ end: return; } -BT_HIDDEN struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( const char *url, char *error_buf, size_t error_buf_size) { @@ -672,7 +821,7 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( at += end_pos; - /* :// */ + /* `://` */ if (strncmp(at, "://", 3) != 0) { if (error_buf) { snprintf(error_buf, error_buf_size, @@ -682,6 +831,7 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( goto error; } + /* Skip `://` */ at += 3; /* Hostname */ @@ -731,12 +881,13 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( } if (at[end_pos] == '\0') { + /* Relay daemon hostname and ports provided only */ goto end; } at += end_pos; - /* /host/ */ + /* `/host/` */ if (strncmp(at, "/host/", 6) != 0) { if (error_buf) { snprintf(error_buf, error_buf_size, @@ -760,9 +911,16 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( } if (at[end_pos] == '\0') { - goto end; + if (error_buf) { + snprintf(error_buf, error_buf_size, + "Missing `/` after target hostname (`%s`)", + parts.target_hostname->str); + } + + goto error; } + /* Skip `/` */ at += end_pos + 1; /* Session name */ @@ -795,7 +953,6 @@ end: return parts; } -BT_HIDDEN void bt_common_normalize_star_glob_pattern(char *pattern) { const char *p; @@ -855,7 +1012,6 @@ bool at_end_of_pattern(const char *p, const char *pattern, size_t pattern_len) * string length of `pattern` or `candidate` if the string is * null-terminated. */ -BT_HIDDEN bool bt_common_star_glob_match(const char *pattern, size_t pattern_len, const char *candidate, size_t candidate_len) { const char *retry_c = candidate, *retry_p = pattern, *c, *p; @@ -1090,8 +1246,8 @@ end_of_pattern: } #ifdef __MINGW32__ -BT_HIDDEN -GString *bt_common_normalize_path(const char *path, const char *wd) +GString *bt_common_normalize_path(const char *path, + const char *wd __attribute__((unused))) { char *tmp; GString *norm_path = NULL; @@ -1152,7 +1308,6 @@ void destroy_gstring(void *gstring) (void) g_string_free(gstring, TRUE); } -BT_HIDDEN GString *bt_common_normalize_path(const char *path, const char *wd) { size_t i; @@ -1237,7 +1392,6 @@ end: } #endif -BT_HIDDEN size_t bt_common_get_page_size(int log_level) { int page_size; @@ -1246,7 +1400,7 @@ size_t bt_common_get_page_size(int log_level) if (page_size < 0) { BT_LOGF("Cannot get system's page size: ret=%d", page_size); - abort(); + bt_common_abort(); } return page_size; @@ -1260,8 +1414,11 @@ size_t bt_common_get_page_size(int log_level) size_t _tmp_fmt_size = (size_t) (fmt_ch - *out_fmt_ch); \ strncpy(_tmp_fmt, *out_fmt_ch, _tmp_fmt_size); \ _tmp_fmt[_tmp_fmt_size] = '\0'; \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") \ _count = snprintf(*buf_ch, _size, _tmp_fmt, __VA_ARGS__); \ - BT_ASSERT(_count >= 0); \ + _Pragma("GCC diagnostic pop") \ + BT_ASSERT_DBG(_count >= 0); \ *buf_ch += MIN(_count, _size); \ } while (0) @@ -1403,13 +1560,11 @@ static inline void handle_conversion_specifier_std(char *buf, char **buf_ch, switch (length_mod) { case LENGTH_MOD_NONE: - BUF_STD_APPEND_SINGLE_ARG(int); - break; case LENGTH_MOD_LOW_L: - BUF_STD_APPEND_SINGLE_ARG(wint_t); + BUF_STD_APPEND_SINGLE_ARG(int); break; default: - abort(); + bt_common_abort(); } break; } @@ -1424,7 +1579,7 @@ static inline void handle_conversion_specifier_std(char *buf, char **buf_ch, BUF_STD_APPEND_SINGLE_ARG(wchar_t *); break; default: - abort(); + bt_common_abort(); } break; case 'd': @@ -1447,7 +1602,7 @@ static inline void handle_conversion_specifier_std(char *buf, char **buf_ch, BUF_STD_APPEND_SINGLE_ARG(size_t); break; default: - abort(); + bt_common_abort(); } break; case 'o': @@ -1472,7 +1627,7 @@ static inline void handle_conversion_specifier_std(char *buf, char **buf_ch, BUF_STD_APPEND_SINGLE_ARG(size_t); break; default: - abort(); + bt_common_abort(); } break; case 'f': @@ -1491,7 +1646,7 @@ static inline void handle_conversion_specifier_std(char *buf, char **buf_ch, BUF_STD_APPEND_SINGLE_ARG(long double); break; default: - abort(); + bt_common_abort(); } break; case 'p': @@ -1500,18 +1655,17 @@ static inline void handle_conversion_specifier_std(char *buf, char **buf_ch, if (length_mod == LENGTH_MOD_NONE) { BUF_STD_APPEND_SINGLE_ARG(void *); } else { - abort(); + bt_common_abort(); } break; default: - abort(); + bt_common_abort(); } update_rw_fmt: *out_fmt_ch = fmt_ch; } -BT_HIDDEN void bt_common_custom_vsnprintf(char *buf, size_t buf_size, char intro, bt_common_handle_custom_specifier_func handle_specifier, @@ -1520,13 +1674,13 @@ void bt_common_custom_vsnprintf(char *buf, size_t buf_size, const char *fmt_ch = fmt; char *buf_ch = buf; - BT_ASSERT(buf); - BT_ASSERT(fmt); + BT_ASSERT_DBG(buf); + BT_ASSERT_DBG(fmt); while (*fmt_ch != '\0') { switch (*fmt_ch) { case '%': - BT_ASSERT(fmt_ch[1] != '\0'); + BT_ASSERT_DBG(fmt_ch[1] != '\0'); if (fmt_ch[1] == intro) { handle_specifier(priv_data, &buf_ch, @@ -1555,7 +1709,6 @@ void bt_common_custom_vsnprintf(char *buf, size_t buf_size, *buf_ch = '\0'; } -BT_HIDDEN void bt_common_custom_snprintf(char *buf, size_t buf_size, char intro, bt_common_handle_custom_specifier_func handle_specifier, @@ -1568,7 +1721,6 @@ void bt_common_custom_snprintf(char *buf, size_t buf_size, va_end(args); } -BT_HIDDEN void bt_common_sep_digits(char *str, unsigned int digits_per_group, char sep) { const char *rd; @@ -1578,12 +1730,12 @@ void bt_common_sep_digits(char *str, unsigned int digits_per_group, char sep) uint64_t sep_count; uint64_t new_len; - BT_ASSERT(digits_per_group > 0); - BT_ASSERT(sep != '\0'); + BT_ASSERT_DBG(digits_per_group > 0); + BT_ASSERT_DBG(sep != '\0'); /* Compute new length of `str` */ orig_len = strlen(str); - BT_ASSERT(orig_len > 0); + BT_ASSERT_DBG(orig_len > 0); sep_count = (orig_len - 1) / digits_per_group; new_len = strlen(str) + sep_count; @@ -1671,7 +1823,6 @@ void bt_common_sep_digits(char *str, unsigned int digits_per_group, char sep) } } -BT_HIDDEN GString *bt_common_fold(const char *str, unsigned int total_length, unsigned int indent) { @@ -1683,10 +1834,10 @@ GString *bt_common_fold(const char *str, unsigned int total_length, gchar * const *line; unsigned int i; - BT_ASSERT(str); - BT_ASSERT(indent < total_length); - BT_ASSERT(tmp_line); - BT_ASSERT(folded); + BT_ASSERT_DBG(str); + BT_ASSERT_DBG(indent < total_length); + BT_ASSERT_DBG(tmp_line); + BT_ASSERT_DBG(folded); if (strlen(str) == 0) { /* Empty input string: empty output string */ @@ -1695,7 +1846,7 @@ GString *bt_common_fold(const char *str, unsigned int total_length, /* Split lines */ lines = g_strsplit(str, "\n", 0); - BT_ASSERT(lines); + BT_ASSERT_DBG(lines); /* For each source line */ for (line = lines; *line; line++) { @@ -1712,7 +1863,7 @@ GString *bt_common_fold(const char *str, unsigned int total_length, /* Split words */ line_words = g_strsplit(*line, " ", 0); - BT_ASSERT(line_words); + BT_ASSERT_DBG(line_words); /* * Indent for first line (we know there's at least one @@ -1780,9 +1931,7 @@ end: g_strfreev(lines); } - if (line_words) { - g_strfreev(line_words); - } + BT_ASSERT_DBG(!line_words); if (tmp_line) { g_string_free(tmp_line, TRUE); @@ -1792,14 +1941,13 @@ end: } #ifdef __MINGW32__ -BT_HIDDEN -int bt_common_get_term_size(unsigned int *width, unsigned int *height) +int bt_common_get_term_size(unsigned int *width __attribute__((unused)), + unsigned int *height __attribute__((unused))) { /* Not supported on Windows yet */ return -1; } #else /* __MINGW32__ */ -BT_HIDDEN int bt_common_get_term_size(unsigned int *width, unsigned int *height) { int ret = 0; @@ -1823,7 +1971,6 @@ end: } #endif /* __MINGW32__ */ -BT_HIDDEN int bt_common_g_string_append_printf(GString *str, const char *fmt, ...) { va_list ap; @@ -1847,10 +1994,70 @@ int bt_common_g_string_append_printf(GString *str, const char *fmt, ...) /* Resize. */ g_string_set_size(str, len + print_len); va_start(ap, fmt); - print_len = vsprintf(str->str + len, fmt, ap); + print_len = vsnprintf(str->str + len, print_len + 1, fmt, ap); va_end(ap); } else { str->len = len + print_len; } return print_len; } + +int bt_common_append_file_content_to_g_string(GString *str, FILE *fp) +{ + const size_t chunk_size = 4096; + int ret = 0; + char *buf; + size_t read_len; + gsize orig_len = str->len; + + BT_ASSERT(str); + BT_ASSERT(fp); + buf = g_malloc(chunk_size); + if (!buf) { + ret = -1; + goto end; + } + + while (true) { + if (ferror(fp)) { + ret = -1; + goto end; + } + + if (feof(fp)) { + break; + } + + read_len = fread(buf, 1, chunk_size, fp); + g_string_append_len(str, buf, read_len); + } + +end: + if (ret) { + /* Remove what was appended */ + g_string_truncate(str, orig_len); + } + + g_free(buf); + return ret; +} + +void bt_common_abort(void) +{ + static const char * const exec_on_abort_env_name = + "BABELTRACE_EXEC_ON_ABORT"; + const char *env_exec_on_abort; + + env_exec_on_abort = getenv(exec_on_abort_env_name); + if (env_exec_on_abort) { + if (bt_common_is_setuid_setgid()) { + goto do_abort; + } + + (void) g_spawn_command_line_sync(env_exec_on_abort, + NULL, NULL, NULL, NULL); + } + +do_abort: + abort(); +}