diff --git a/src/common.cpp b/src/common.cpp index 5de756383..bdc476ec2 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -541,9 +541,7 @@ bool should_suppress_stderr_for_tests() { static bool should_debug(int level) { if (level > debug_level) return false; - if (should_suppress_stderr_for_tests()) return false; - return true; } @@ -1534,9 +1532,8 @@ int create_directory(const wcstring &d) { } __attribute__((noinline)) void bugreport() { - debug(1, _(L"This is a bug. Break on bugreport to debug. " - L"If you can reproduce it, please send a bug report to %s."), - PACKAGE_BUGREPORT); + debug(0, _(L"This is a bug. Break on bugreport to debug.")); + debug(0, _(L"If you can reproduce it, please send a bug report to %s."), PACKAGE_BUGREPORT); } wcstring format_size(long long sz) { @@ -1722,28 +1719,24 @@ bool is_main_thread() { void assert_is_main_thread(const char *who) { if (!is_main_thread() && !thread_asserts_cfg_for_testing) { - fprintf(stderr, - "Warning: %s called off of main thread. Break on debug_thread_error to debug.\n", - who); + debug(0, "%s called off of main thread.", who); + debug(0, "Break on debug_thread_error to debug."); debug_thread_error(); } } void assert_is_not_forked_child(const char *who) { if (is_forked_child()) { - fprintf(stderr, - "Warning: %s called in a forked child. Break on debug_thread_error to debug.\n", - who); + debug(0, "%s called in a forked child.", who); + debug(0, "Break on debug_thread_error to debug."); debug_thread_error(); } } void assert_is_background_thread(const char *who) { if (is_main_thread() && !thread_asserts_cfg_for_testing) { - fprintf(stderr, - "Warning: %s called on the main thread (may block!). Break on debug_thread_error " - "to debug.\n", - who); + debug(0, "%s called on the main thread (may block!).", who); + debug(0, "Break on debug_thread_error to debug."); debug_thread_error(); } } @@ -1751,10 +1744,8 @@ void assert_is_background_thread(const char *who) { void assert_is_locked(void *vmutex, const char *who, const char *caller) { pthread_mutex_t *mutex = static_cast(vmutex); if (0 == pthread_mutex_trylock(mutex)) { - fprintf(stderr, - "Warning: %s is not locked when it should be in '%s'. Break on debug_thread_error " - "to debug.\n", - who, caller); + debug(0, "%s is not locked when it should be in '%s'", who, caller); + debug(0, "Break on debug_thread_error to debug."); debug_thread_error(); pthread_mutex_unlock(mutex); } diff --git a/src/common.h b/src/common.h index 09edff927..f0ec546df 100644 --- a/src/common.h +++ b/src/common.h @@ -143,6 +143,26 @@ inline bool selection_direction_is_cardinal(selection_direction_t dir) { } } +/// Issue a debug message with printf-style string formating and automatic line breaking. The string +/// will begin with the string \c program_name, followed by a colon and a whitespace. +/// +/// Because debug is often called to tell the user about an error, before using wperror to give a +/// specific error message, debug will never ever modify the value of errno. +/// +/// \param level the priority of the message. Lower number means higher priority. Messages with a +/// priority_number higher than \c debug_level will be ignored.. +/// \param msg the message format string. +/// +/// Example: +/// +/// debug( 1, L"Pi = %.3f", M_PI ); +/// +/// will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that +/// program_name is 'fish'. +void __attribute__((noinline)) debug(int level, const char *msg, ...) + __attribute__((format(printf, 2, 3))); +void __attribute__((noinline)) debug(int level, const wchar_t *msg, ...); + /// Helper macro for errors. #define VOMIT_ON_FAILURE(a) \ do { \ @@ -157,12 +177,12 @@ inline bool selection_direction_is_cardinal(selection_direction_t dir) { VOMIT_ABORT(err, #a); \ } \ } while (0) -#define VOMIT_ABORT(err, str) \ - do { \ - int code = (err); \ - fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", str, __LINE__, __FILE__, \ - code, strerror(code)); \ - abort(); \ +#define VOMIT_ABORT(err, str) \ + do { \ + int code = (err); \ + debug(0, "%s failed on line %d in file %s: %d (%s)", str, __LINE__, __FILE__, code, \ + strerror(code)); \ + abort(); \ } while (0) /// Exits without invoking destructors (via _exit), useful for code after fork. @@ -224,11 +244,10 @@ extern bool has_working_tty_timestamps; } /// Exit program at once after emitting an error message. -#define DIE(msg) \ - { \ - fprintf(stderr, "fish: %s on line %ld of file %s, shutting down fish\n", msg, \ - (long)__LINE__, __FILE__); \ - FATAL_EXIT(); \ +#define DIE(msg) \ + { \ + debug(0, "%s on line %ld of file %s, shutting down fish", msg, (long)__LINE__, __FILE__); \ + FATAL_EXIT(); \ } /// Exit program at once, leaving an error message about running out of memory. @@ -659,25 +678,6 @@ ssize_t write_loop(int fd, const char *buff, size_t count); /// error. ssize_t read_loop(int fd, void *buff, size_t count); -/// Issue a debug message with printf-style string formating and automatic line breaking. The string -/// will begin with the string \c program_name, followed by a colon and a whitespace. -/// -/// Because debug is often called to tell the user about an error, before using wperror to give a -/// specific error message, debug will never ever modify the value of errno. -/// -/// \param level the priority of the message. Lower number means higher priority. Messages with a -/// priority_number higher than \c debug_level will be ignored.. -/// \param msg the message format string. -/// -/// Example: -/// -/// debug( 1, L"Pi = %.3f", M_PI ); -/// -/// will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that -/// program_name is 'fish'. -void __attribute__((noinline)) debug(int level, const char *msg, ...) - __attribute__((format(printf, 2, 3))); -void __attribute__((noinline)) debug(int level, const wchar_t *msg, ...); /// Replace special characters with backslash escape sequences. Newline is replaced with \n, etc. /// diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index de47fe07b..d60bb705c 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -95,7 +95,8 @@ static const wcstring default_vars_path() { return vars_filename_in_directory(path); } -/// Check, and create if necessary, a secure runtime path Derived from tmux.c in tmux +#if !defined(__APPLE__) && !defined(__CYGWIN__) +/// Check, and create if necessary, a secure runtime path. Derived from tmux.c in tmux /// (http://tmux.sourceforge.net/). static int check_runtime_path(const char *path) { // Copyright (c) 2007 Nicholas Marriott @@ -143,9 +144,8 @@ static wcstring get_runtime_path() { std::string tmpdir = "/tmp/fish."; tmpdir.append(uname); if (check_runtime_path(tmpdir.c_str()) != 0) { - debug(0, - L"Runtime path not available. Try deleting the directory %s and restarting fish.", - tmpdir.c_str()); + debug(0, L"Runtime path not available."); + debug(0, L"Try deleting the directory %s and restarting fish.", tmpdir.c_str()); } else { result = str2wcstring(tmpdir); } @@ -159,6 +159,7 @@ static wcstring default_named_pipe_path() { // Note that vars_filename_in_directory returns empty string when passed the empty string. return vars_filename_in_directory(get_runtime_path()); } +#endif /// Test if the message msg contains the command cmd. static bool match(const wchar_t *msg, const wchar_t *cmd) { @@ -1121,10 +1122,8 @@ class universal_notifier_notifyd_t : public universal_notifier_t { uint32_t status = notify_register_file_descriptor(name.c_str(), &this->notify_fd, 0, &this->token); if (status != NOTIFY_STATUS_OK) { - fprintf(stderr, - "Warning: notify_register_file_descriptor() failed with status %u. Universal " - "variable notifications may not be received.", - status); + debug(1, "notify_register_file_descriptor() failed with status %u.", status); + debug(1, "Universal variable notifications may not be received."); } if (this->notify_fd >= 0) { // Mark us for non-blocking reads, and CLO_EXEC. @@ -1184,8 +1183,10 @@ class universal_notifier_notifyd_t : public universal_notifier_t { #endif }; -#define NAMED_PIPE_FLASH_DURATION_USEC (1000000 / 10) -#define SUSTAINED_READABILITY_CLEANUP_DURATION_USEC (1000000 * 5) +#if !defined(__APPLE__) && !defined(__CYGWIN__) +#define NAMED_PIPE_FLASH_DURATION_USEC (1e5) +#define SUSTAINED_READABILITY_CLEANUP_DURATION_USEC (5 * 1e6) +#endif // Named-pipe based notifier. All clients open the same named pipe for reading and writing. The // pipe's readability status is a trigger to enter polling mode. @@ -1347,7 +1348,7 @@ class universal_notifier_named_pipe_t : public universal_notifier_t { #else // this class isn't valid on this system public: universal_notifier_named_pipe_t(const wchar_t *test_path) { - auto x = test_path; // silence "unused parameter" warning + static_cast(test_path); DIE("universal_notifier_named_pipe_t cannot be used on this system"); } #endif diff --git a/src/exec.cpp b/src/exec.cpp index 0e26cfb14..26f5d9165 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -1131,16 +1131,12 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, const int prev_status = proc_get_last_status(); bool split_output = false; - // fprintf(stderr, "subcmd %ls\n", cmd.c_str()); - const env_var_t ifs = env_get_string(L"IFS"); - if (!ifs.missing_or_empty()) { split_output = true; } is_subshell = 1; - int subcommand_status = -1; // assume the worst // IO buffer creation may fail (e.g. if we have too many open files to make a pipe), so this may diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp index 8605e4ead..80235a2df 100644 --- a/src/fish_indent.cpp +++ b/src/fish_indent.cpp @@ -491,7 +491,7 @@ int main(int argc, char *argv[]) { case output_type_file: { FILE *fh = fopen(output_location, "w"); if (fh) { - fputs(wcs2str(output_wtext), fh); + fputws(output_wtext.c_str(), fh); fclose(fh); exit(0); } else { @@ -511,6 +511,6 @@ int main(int argc, char *argv[]) { } } - fputs(colored_output.c_str(), stdout); + fputws(str2wcstring(colored_output).c_str(), stdout); return 0; } diff --git a/src/fish_key_reader.cpp b/src/fish_key_reader.cpp index 04375c00a..b767bfa18 100644 --- a/src/fish_key_reader.cpp +++ b/src/fish_key_reader.cpp @@ -34,10 +34,10 @@ struct config_paths_t determine_config_directory_paths(const char *argv0); -static const char *ctrl_symbolic_names[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\a", - "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, "\\e", NULL, NULL, NULL, NULL}; +static const wchar_t *ctrl_symbolic_names[] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, L"\\a", L"\\b", L"\\t", L"\\n", + L"\\v", L"\\f", L"\\r", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, L"\\e", NULL, NULL, NULL, NULL}; static bool keep_running = true; /// Return true if the recent sequence of characters indicates the user wants to exit the program. @@ -51,12 +51,12 @@ static bool should_exit(wchar_t wc) { recent_chars[3] = c; if (c == shell_modes.c_cc[VINTR]) { if (recent_chars[2] == shell_modes.c_cc[VINTR]) return true; - fprintf(stderr, "Press [ctrl-%c] again to exit\n", shell_modes.c_cc[VINTR] + 0x40); + fwprintf(stderr, L"Press [ctrl-%c] again to exit\n", shell_modes.c_cc[VINTR] + 0x40); return false; } if (c == shell_modes.c_cc[VEOF]) { if (recent_chars[2] == shell_modes.c_cc[VEOF]) return true; - fprintf(stderr, "Press [ctrl-%c] again to exit\n", shell_modes.c_cc[VEOF] + 0x40); + fwprintf(stderr, L"Press [ctrl-%c] again to exit\n", shell_modes.c_cc[VEOF] + 0x40); return false; } return memcmp(recent_chars, "exit", 4) == 0 || memcmp(recent_chars, "quit", 4) == 0; @@ -116,46 +116,48 @@ static bool must_escape(wchar_t wc) { } } -static char *char_to_symbol(wchar_t wc, bool bind_friendly) { - static char buf[128]; +static wchar_t *char_to_symbol(wchar_t wc, bool bind_friendly) { +#define BUF_LEN 64 + static wchar_t buf[BUF_LEN]; - if (wc < ' ') { + if (wc < L' ') { // ASCII control character. if (ctrl_symbolic_names[wc]) { if (bind_friendly) { - snprintf(buf, sizeof(buf), "%s", ctrl_symbolic_names[wc]); + swprintf(buf, BUF_LEN, L"%ls", ctrl_symbolic_names[wc]); } else { - snprintf(buf, sizeof(buf), "\\c%c (or %s)", wc + 64, ctrl_symbolic_names[wc]); + swprintf(buf, BUF_LEN, L"\\c%c (or %ls)", wc + 0x40, ctrl_symbolic_names[wc]); } } else { - snprintf(buf, sizeof(buf), "\\c%c", wc + 64); + swprintf(buf, BUF_LEN, L"\\c%c", wc + 0x40); } - } else if (wc == ' ') { + } else if (wc == L' ') { // The "space" character. if (bind_friendly) { - snprintf(buf, sizeof(buf), "\\x%X", wc); + swprintf(buf, BUF_LEN, L"\\x%X", ' '); } else { - snprintf(buf, sizeof(buf), "\\x%X (aka \"space\")", wc); + swprintf(buf, BUF_LEN, L"\\x%X (aka \"space\")", ' '); } } else if (wc == 0x7F) { // The "del" character. if (bind_friendly) { - snprintf(buf, sizeof(buf), "\\x%X", wc); + swprintf(buf, BUF_LEN, L"\\x%X", 0x7F); } else { - snprintf(buf, sizeof(buf), "\\x%X (aka \"del\")", wc); + swprintf(buf, BUF_LEN, L"\\x%X (aka \"del\")", 0x7F); } } else if (wc < 0x80) { // ASCII characters that are not control characters. if (bind_friendly && must_escape(wc)) { - snprintf(buf, sizeof(buf), "\\%c", wc); + swprintf(buf, BUF_LEN, L"\\%c", wc); } else { - snprintf(buf, sizeof(buf), "%c", wc); + swprintf(buf, BUF_LEN, L"%c", wc); } } else if (wc <= 0xFFFF) { - snprintf(buf, sizeof(buf), "\\u%04X", wc); + swprintf(buf, BUF_LEN, L"\\u%04X", (int)wc); } else { - snprintf(buf, sizeof(buf), "\\U%06X", wc); + swprintf(buf, BUF_LEN, L"\\U%06X", (int)wc); } + return buf; } @@ -165,17 +167,17 @@ static void add_char_to_bind_command(wchar_t wc, std::vector &bind_char static void output_bind_command(std::vector &bind_chars) { if (bind_chars.size()) { - fputs("bind ", stdout); + fputws(L"bind ", stdout); for (size_t i = 0; i < bind_chars.size(); i++) { - fputs(char_to_symbol(bind_chars[i], true), stdout); + fputws(char_to_symbol(bind_chars[i], true), stdout); } - fputs(" 'do something'\n", stdout); + fputws(L" 'do something'\n", stdout); bind_chars.clear(); } } static void output_info_about_char(wchar_t wc) { - fprintf(stderr, "hex: %4X char: %s\n", wc, char_to_symbol(wc, false)); + fwprintf(stderr, L"hex: %4X char: %ls\n", wc, char_to_symbol(wc, false)); } static bool output_matching_key_name(wchar_t wc) { @@ -193,11 +195,11 @@ static double output_elapsed_time(double prev_tstamp, bool first_char_seen) { double now = timef(); long long int delta_tstamp_us = 1000000 * (now - prev_tstamp); - if (delta_tstamp_us >= 200000 && first_char_seen) putc('\n', stderr); + if (delta_tstamp_us >= 200000 && first_char_seen) fputwc(L'\n', stderr); if (delta_tstamp_us >= 1000000) { - fprintf(stderr, " "); + fwprintf(stderr, L" "); } else { - fprintf(stderr, "(%3lld.%03lld ms) ", delta_tstamp_us / 1000, delta_tstamp_us % 1000); + fwprintf(stderr, L"(%3lld.%03lld ms) ", delta_tstamp_us / 1000, delta_tstamp_us % 1000); } return now; } @@ -208,7 +210,7 @@ static void process_input(bool continuous_mode) { double prev_tstamp = 0.0; std::vector bind_chars; - fprintf(stderr, "Press a key\n\n"); + fwprintf(stderr, L"Press a key\n\n"); while (keep_running) { wchar_t wc; if (reader_interrupted()) { @@ -232,7 +234,7 @@ static void process_input(bool continuous_mode) { } if (should_exit(wc)) { - fprintf(stderr, "\nExiting at your request.\n"); + fwprintf(stderr, L"\nExiting at your request.\n"); break; } @@ -295,11 +297,11 @@ static void setup_and_process_keys(bool continuous_mode) { install_our_signal_handlers(); if (continuous_mode) { - fprintf(stderr, "\n"); - fprintf(stderr, "To terminate this program type \"exit\" or \"quit\" in this window,\n"); - fprintf(stderr, "or press [ctrl-%c] or [ctrl-%c] twice in a row.\n", - shell_modes.c_cc[VINTR] + 0x40, shell_modes.c_cc[VEOF] + 0x40); - fprintf(stderr, "\n"); + fwprintf(stderr, L"\n"); + fwprintf(stderr, L"To terminate this program type \"exit\" or \"quit\" in this window,\n"); + fwprintf(stderr, L"or press [ctrl-%c] or [ctrl-%c] twice in a row.\n", + shell_modes.c_cc[VINTR] + 0x40, shell_modes.c_cc[VEOF] + 0x40); + fwprintf(stderr, L"\n"); } process_input(continuous_mode); @@ -323,7 +325,7 @@ int main(int argc, char **argv) { while (!error && (opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { switch (opt) { case 0: { - fprintf(stderr, "getopt_long() unexpectedly returned zero\n"); + fwprintf(stderr, L"getopt_long() unexpectedly returned zero\n"); error = true; break; } @@ -378,12 +380,12 @@ int main(int argc, char **argv) { argc -= optind; if (argc != 0) { - fprintf(stderr, "Expected no arguments, got %d\n", argc); + fwprintf(stderr, L"Expected no arguments, got %d\n", argc); return 1; } if (!isatty(STDIN_FILENO)) { - fprintf(stderr, "Stdin must be attached to a tty.\n"); + fwprintf(stderr, L"Stdin must be attached to a tty.\n"); return 1; } diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 387cd73e3..714de42c1 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -766,19 +766,10 @@ static void test_cancellation() { // we cancel we expect no output. test_1_cancellation(L"echo (while true ; echo blah ; end)"); - fprintf(stderr, "."); - // Nasty infinite loop that doesn't actually execute anything. test_1_cancellation(L"echo (while true ; end) (while true ; end) (while true ; end)"); - fprintf(stderr, "."); - test_1_cancellation(L"while true ; end"); - fprintf(stderr, "."); - test_1_cancellation(L"for i in (while true ; end) ; end"); - fprintf(stderr, "."); - - fprintf(stderr, "\n"); // Restore signal handling. proc_pop_interactive(); @@ -1645,8 +1636,8 @@ struct pager_layout_testcase_t { wcstring text = sd.line(0).to_string(); if (text != expected) { - fprintf(stderr, "width %zu got <%ls>, expected <%ls>\n", this->width, text.c_str(), - expected.c_str()); + fwprintf(stderr, L"width %zu got <%ls>, expected <%ls>\n", this->width, + text.c_str(), expected.c_str()); } do_test(text == expected); } @@ -2175,8 +2166,8 @@ static void test_1_completion(wcstring line, const wcstring &completion, complet wcstring result = completion_apply_to_command_line(completion, flags, line, &cursor_pos, append_only); if (result != expected) { - fprintf(stderr, "line %ld: %ls + %ls -> [%ls], expected [%ls]\n", source_line, line.c_str(), - completion.c_str(), result.c_str(), expected.c_str()); + fwprintf(stderr, L"line %ld: %ls + %ls -> [%ls], expected [%ls]\n", source_line, + line.c_str(), completion.c_str(), result.c_str(), expected.c_str()); } do_test(result == expected); do_test(cursor_pos == out_cursor_pos); @@ -2501,7 +2492,7 @@ static void test_universal() { } if (system("rm -Rf /tmp/fish_uvars_test")) err(L"rm failed"); - putc('\n', stderr); + fputwc(L'\n', stderr); } static bool callback_data_less_than(const callback_data_t &a, const callback_data_t &b) { @@ -3225,7 +3216,7 @@ static void test_new_parser_fuzzing(void) { bool log_it = true; unsigned long max_len = 5; for (unsigned long len = 0; len < max_len; len++) { - if (log_it) fprintf(stderr, "%lu / %lu...", len, max_len); + if (log_it) fwprintf(stderr, L"%lu / %lu...", len, max_len); // We wish to look at all permutations of 4 elements of 'fuzzes' (with replacement). // Construct an int and keep incrementing it. @@ -3234,7 +3225,7 @@ static void test_new_parser_fuzzing(void) { &src)) { parse_tree_from_string(src, parse_flag_continue_after_error, &node_tree, &errors); } - if (log_it) fprintf(stderr, "done (%lu)\n", permutation); + if (log_it) fwprintf(stderr, L"done (%lu)\n", permutation); } double end = timef(); if (log_it) say(L"All fuzzed in %f seconds!", end - start); @@ -4121,8 +4112,8 @@ int main(int argc, char **argv) { exit(-1); } if (!strcmp(wd, "/")) { - fprintf(stderr, - "Unable to find 'tests' directory, which should contain file test.fish\n"); + fwprintf(stderr, + L"Unable to find 'tests' directory, which should contain file test.fish\n"); exit(EXIT_FAILURE); } if (chdir(dirname(wd)) < 0) { diff --git a/src/highlight.cpp b/src/highlight.cpp index a1cd1a646..3019db942 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -1031,7 +1031,7 @@ const highlighter_t::color_array_t &highlighter_t::highlight() { #if 0 // Disabled for the 2.2.0 release: https://github.com/fish-shell/fish-shell/issues/1809. const wcstring dump = parse_dump_tree(parse_tree, buff); - fprintf(stderr, "%ls\n", dump.c_str()); + fwprintf(stderr, L"%ls\n", dump.c_str()); #endif // Walk the node tree. diff --git a/src/input.cpp b/src/input.cpp index 537889214..cfd409cdc 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -374,7 +374,7 @@ int input_init() { } else { debug(0, _(L"Using fallback terminal type '%ls'"), DEFAULT_TERM); } - putc('\n', stderr); + fputwc(L'\n', stderr); } input_terminfo_init(); diff --git a/src/io.cpp b/src/io.cpp index be33bcb12..5cdc5c336 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "common.h" #include "exec.h" @@ -15,19 +16,20 @@ io_data_t::~io_data_t() {} -void io_close_t::print() const { fprintf(stderr, "close %d\n", fd); } +void io_close_t::print() const { fwprintf(stderr, L"close %d\n", fd); } -void io_fd_t::print() const { fprintf(stderr, "FD map %d -> %d\n", old_fd, fd); } +void io_fd_t::print() const { fwprintf(stderr, L"FD map %d -> %d\n", old_fd, fd); } -void io_file_t::print() const { fprintf(stderr, "file (%s)\n", filename_cstr); } +void io_file_t::print() const { fwprintf(stderr, L"file (%s)\n", filename_cstr); } void io_pipe_t::print() const { - fprintf(stderr, "pipe {%d, %d} (input: %s)\n", pipe_fd[0], pipe_fd[1], is_input ? "yes" : "no"); + fwprintf(stderr, L"pipe {%d, %d} (input: %s)\n", pipe_fd[0], pipe_fd[1], + is_input ? "yes" : "no"); } void io_buffer_t::print() const { - fprintf(stderr, "buffer %p (input: %s, size %lu)\n", out_buffer_ptr(), is_input ? "yes" : "no", - (unsigned long)out_buffer_size()); + fwprintf(stderr, L"buffer %p (input: %s, size %lu)\n", out_buffer_ptr(), + is_input ? "yes" : "no", (unsigned long)out_buffer_size()); } void io_buffer_t::read() { @@ -139,21 +141,21 @@ void io_print(const io_chain_t &chain) { if (chain.empty()) { - fprintf(stderr, "Empty chain %p\n", &chain); + fwprintf(stderr, L"Empty chain %p\n", &chain); return; } - fprintf(stderr, "Chain %p (%ld items):\n", &chain, (long)chain.size()); + fwprintf(stderr, L"Chain %p (%ld items):\n", &chain, (long)chain.size()); for (size_t i=0; i < chain.size(); i++) { const shared_ptr &io = chain.at(i); if (io.get() == NULL) { - fprintf(stderr, "\t(null)\n"); + fwprintf(stderr, L"\t(null)\n"); } else { - fprintf(stderr, "\t%lu: fd:%d, ", (unsigned long)i, io->fd); + fwprintf(stderr, L"\t%lu: fd:%d, ", (unsigned long)i, io->fd); io->print(); } } diff --git a/src/iothread.cpp b/src/iothread.cpp index e9279dae9..d80496bfc 100644 --- a/src/iothread.cpp +++ b/src/iothread.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -228,7 +227,7 @@ void iothread_service_completion(void) { } else if (wakeup_byte == IO_SERVICE_RESULT_QUEUE) { iothread_service_result_queue(); } else { - fprintf(stderr, "Unknown wakeup byte %02x in %s\n", wakeup_byte, __FUNCTION__); + debug(0, "Unknown wakeup byte %02x in %s", wakeup_byte, __FUNCTION__); } } diff --git a/src/parse_constants.h b/src/parse_constants.h index 642a569ee..72b1a0089 100644 --- a/src/parse_constants.h +++ b/src/parse_constants.h @@ -6,10 +6,10 @@ #include "config.h" #define PARSE_ASSERT(a) assert(a) -#define PARSER_DIE() \ - do { \ - fprintf(stderr, "Parser dying!\n"); \ - exit_without_destructors(-1); \ +#define PARSER_DIE() \ + do { \ + debug(0, "Parser dying!"); \ + exit_without_destructors(-1); \ } while (0) // IMPORTANT: If the following enum table is modified you must also update token_enum_map below. diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 712626fab..3b10d2e08 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -441,7 +441,7 @@ parse_execution_result_t parse_execution_context_t::run_block_statement( break; } default: { - fprintf(stderr, "Unexpected block header: %ls\n", header.describe().c_str()); + debug(0, L"Unexpected block header: %ls\n", header.describe().c_str()); PARSER_DIE(); break; } @@ -700,7 +700,7 @@ parse_execution_result_t parse_execution_context_t::report_errors( const parse_error_list_t &error_list) const { if (!parser->cancellation_requested) { if (error_list.empty()) { - fprintf(stderr, "Bug: Error reported but no error text found."); + debug(0, "Error reported but no error text found."); } // Get a backtrace. @@ -708,7 +708,9 @@ parse_execution_result_t parse_execution_context_t::report_errors( parser->get_backtrace(src, error_list, &backtrace_and_desc); // Print it. - if (!should_suppress_stderr_for_tests()) fprintf(stderr, "%ls", backtrace_and_desc.c_str()); + if (!should_suppress_stderr_for_tests()) { + fwprintf(stderr, L"%ls", backtrace_and_desc.c_str()); + } } return parse_execution_errored; } @@ -1034,8 +1036,7 @@ bool parse_execution_context_t::determine_io_chain(const parse_node_t &statement } default: { // Should be unreachable. - fprintf(stderr, "Unexpected redirection type %ld. aborting.\n", - (long)redirect_type); + debug(0, "Unexpected redirection type %ld.", (long)redirect_type); PARSER_DIE(); break; } @@ -1133,8 +1134,8 @@ parse_execution_result_t parse_execution_context_t::populate_job_process( break; } default: { - fprintf(stderr, "'%ls' not handled by new parser yet\n", - specific_statement.describe().c_str()); + debug(0, L"'%ls' not handled by new parser yet.", + specific_statement.describe().c_str()); PARSER_DIE(); break; } @@ -1426,8 +1427,7 @@ parse_execution_result_t parse_execution_context_t::eval_node_at_offset( default: { // In principle, we could support other node types. However we never expect to be passed // them - see above. - fprintf(stderr, "Unexpected node %ls found in %s\n", node.describe().c_str(), - __FUNCTION__); + debug(0, "Unexpected node %ls found in %s", node.describe().c_str(), __FUNCTION__); PARSER_DIE(); break; } diff --git a/src/parse_productions.cpp b/src/parse_productions.cpp index dbbd84610..ffd998e11 100644 --- a/src/parse_productions.cpp +++ b/src/parse_productions.cpp @@ -481,21 +481,21 @@ const production_element_t *parse_productions::production_for_token(parse_token_ case parse_token_type_background: case parse_token_type_end: case parse_token_type_terminate: { - fprintf(stderr, "Terminal token type %ls passed to %s\n", - token_type_description(node_type), __FUNCTION__); + debug(0, "Terminal token type %ls passed to %s", token_type_description(node_type), + __FUNCTION__); PARSER_DIE(); break; } case parse_special_type_parse_error: case parse_special_type_tokenizer_error: case parse_special_type_comment: { - fprintf(stderr, "Special type %ls passed to %s\n", token_type_description(node_type), - __FUNCTION__); + debug(0, "Special type %ls passed to %s\n", token_type_description(node_type), + __FUNCTION__); PARSER_DIE(); break; } case token_type_invalid: { - fprintf(stderr, "token_type_invalid passed to %s\n", __FUNCTION__); + debug(0, "token_type_invalid passed to %s", __FUNCTION__); PARSER_DIE(); break; } diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 7b8f065ef..f95ea1aa3 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -127,6 +127,7 @@ const wchar_t *token_type_description(parse_token_type_t type) { // This leaks memory but it should never be run unless we have a bug elsewhere in the code. const wcstring d = format_string(L"unknown_token_type_%ld", static_cast(type)); wchar_t *d2 = new wchar_t[d.size() + 1]; + // cppcheck-suppress memleak return std::wcscpy(d2, d.c_str()); } @@ -137,6 +138,7 @@ const wchar_t *keyword_description(parse_keyword_t type) { // This leaks memory but it should never be run unless we have a bug elsewhere in the code. const wcstring d = format_string(L"unknown_keyword_%ld", static_cast(type)); wchar_t *d2 = new wchar_t[d.size() + 1]; + // cppcheck-suppress memleak return std::wcscpy(d2, d.c_str()); } @@ -258,8 +260,7 @@ static inline parse_token_type_t parse_token_type_from_tokenizer_token( break; } default: { - fprintf(stderr, "Bad token type %d passed to %s\n", (int)tokenizer_token_type, - __FUNCTION__); + debug(0, "Bad token type %d passed to %s", (int)tokenizer_token_type, __FUNCTION__); DIE("bad token type"); break; } @@ -420,17 +421,17 @@ class parse_ll_t { bool logit = false; if (logit) { int count = 0; - fprintf(stderr, "Applying production:\n"); + fwprintf(stderr, L"Applying production:\n"); for (int i = 0;; i++) { production_element_t elem = production[i]; if (!production_element_is_valid(elem)) break; // all done, bail out parse_token_type_t type = production_element_type(elem); parse_keyword_t keyword = production_element_keyword(elem); - fprintf(stderr, "\t%ls <%ls>\n", token_type_description(type), - keyword_description(keyword)); + fwprintf(stderr, L"\t%ls <%ls>\n", token_type_description(type), + keyword_description(keyword)); count++; } - if (!count) fprintf(stderr, "\t\n"); + if (!count) fwprintf(stderr, L"\t\n"); } // Get the parent index. But we can't get the parent parse node yet, since it may be made @@ -537,9 +538,9 @@ void parse_ll_t::dump_stack(void) const { } } - fprintf(stderr, "Stack dump (%zu elements):\n", symbol_stack.size()); + fwprintf(stderr, L"Stack dump (%zu elements):\n", symbol_stack.size()); for (size_t idx = 0; idx < stack_lines.size(); idx++) { - fprintf(stderr, " %ls\n", stack_lines.at(idx).c_str()); + fwprintf(stderr, L" %ls\n", stack_lines.at(idx).c_str()); } } #endif @@ -927,7 +928,7 @@ bool parse_ll_t::top_node_handle_terminal_types(parse_token_t token) { void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) { bool logit = false; if (logit) { - fprintf(stderr, "Accept token %ls\n", token1.describe().c_str()); + fwprintf(stderr, L"Accept token %ls\n", token1.describe().c_str()); } PARSE_ASSERT(token1.type >= FIRST_PARSE_TOKEN_TYPE); @@ -964,7 +965,7 @@ void parse_ll_t::accept_tokens(parse_token_t token1, parse_token_t token2) { if (top_node_handle_terminal_types(token1)) { if (logit) { - fprintf(stderr, "Consumed token %ls\n", token1.describe().c_str()); + fwprintf(stderr, L"Consumed token %ls\n", token1.describe().c_str()); } // consumed = true; break; @@ -1184,8 +1185,8 @@ bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t parse_flags, #if 0 //wcstring result = dump_tree(this->parser->nodes, str); - //fprintf(stderr, "Tree (%ld nodes):\n%ls", this->parser->nodes.size(), result.c_str()); - fprintf(stderr, "%lu nodes, node size %lu, %lu bytes\n", output->size(), sizeof(parse_node_t), + //fwprintf(stderr, L"Tree (%ld nodes):\n%ls", this->parser->nodes.size(), result.c_str()); + fwprintf(stderr, L"%lu nodes, node size %lu, %lu bytes\n", output->size(), sizeof(parse_node_t), output->size() * sizeof(parse_node_t)); #endif diff --git a/src/parser.cpp b/src/parser.cpp index 7ec47285c..21bd8777e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -615,8 +615,7 @@ int parser_t::eval(const wcstring &cmd, const io_chain_t &io, enum block_type_t this->get_backtrace(cmd, error_list, &backtrace_and_desc); // Print it. - fprintf(stderr, "%ls", backtrace_and_desc.c_str()); - + fwprintf(stderr, L"%ls\n", backtrace_and_desc.c_str()); return 1; } return this->eval_acquiring_tree(cmd, io, block_type, moved_ref(tree)); diff --git a/src/path.cpp b/src/path.cpp index 1cfda620a..6465822ed 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -242,7 +242,7 @@ static void maybe_issue_path_warning(const wcstring &which_dir, const wcstring & debug(0, _(L"The error was '%s'."), strerror(saved_errno)); debug(0, _(L"Please set $%ls to a directory where you have write access."), env_var); } - putc('\n', stderr); + fputwc(L'\n', stderr); } static void path_create(wcstring &path, const wcstring &xdg_var, const wcstring &which_dir, diff --git a/src/postfork.cpp b/src/postfork.cpp index 366c5ced8..41fe0e30b 100644 --- a/src/postfork.cpp +++ b/src/postfork.cpp @@ -11,6 +11,7 @@ #if FISH_USE_POSIX_SPAWN #include #endif +#include #include "common.h" #include "exec.h" @@ -141,7 +142,7 @@ static int handle_child_io(const io_chain_t &io_chain) { switch (io->io_mode) { case IO_CLOSE: { - if (log_redirections) fprintf(stderr, "%d: close %d\n", getpid(), io->fd); + if (log_redirections) fwprintf(stderr, L"%d: close %d\n", getpid(), io->fd); if (close(io->fd)) { debug_safe_int(0, "Failed to close file descriptor %s", io->fd); safe_perror("close"); @@ -180,7 +181,7 @@ static int handle_child_io(const io_chain_t &io_chain) { case IO_FD: { int old_fd = static_cast(io)->old_fd; if (log_redirections) - fprintf(stderr, "%d: fd dup %d to %d\n", getpid(), old_fd, io->fd); + fwprintf(stderr, L"%d: fd dup %d to %d\n", getpid(), old_fd, io->fd); // This call will sometimes fail, but that is ok, this is just a precausion. close(io->fd); @@ -200,14 +201,14 @@ static int handle_child_io(const io_chain_t &io_chain) { // fd). If it's 1, we're connecting to the write end (second pipe fd). unsigned int write_pipe_idx = (io_pipe->is_input ? 0 : 1); #if 0 - debug( 0, L"%ls %ls on fd %d (%d %d)", write_pipe?L"write":L"read", - (io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, io->pipe_fd[0], - io->pipe_fd[1]); + debug(0, L"%ls %ls on fd %d (%d %d)", write_pipe?L"write":L"read", + (io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, io->pipe_fd[0], + io->pipe_fd[1]); #endif if (log_redirections) - fprintf(stderr, "%d: %s dup %d to %d\n", getpid(), - io->io_mode == IO_BUFFER ? "buffer" : "pipe", - io_pipe->pipe_fd[write_pipe_idx], io->fd); + fwprintf(stderr, L"%d: %s dup %d to %d\n", getpid(), + io->io_mode == IO_BUFFER ? "buffer" : "pipe", + io_pipe->pipe_fd[write_pipe_idx], io->fd); if (dup2(io_pipe->pipe_fd[write_pipe_idx], io->fd) != io->fd) { debug_safe(1, LOCAL_PIPE_ERROR); safe_perror("dup2"); diff --git a/src/proc.cpp b/src/proc.cpp index 815a53084..3a392d56c 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -280,7 +280,7 @@ static void mark_process_status(process_t *p, int status) { } else { // This should never be reached. p->completed = 1; - fprintf(stderr, "Process %ld exited abnormally\n", (long)p->pid); + debug(1, "Process %ld exited abnormally", (long)p->pid); } } diff --git a/src/reader.cpp b/src/reader.cpp index 5121f7544..3e3c96aaf 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2424,7 +2424,7 @@ const wchar_t *reader_readline(int nchars) { is_interactive_read = 1; c = input_readch(); is_interactive_read = was_interactive_read; - // fprintf(stderr, "C: %lx\n", (long)c); + // fwprintf(stderr, L"C: %lx\n", (long)c); if (((!fish_reserved_codepoint(c))) && (c > 31) && (c != 127) && can_read(0)) { wchar_t arr[READAHEAD_MAX + 1]; @@ -2486,7 +2486,7 @@ const wchar_t *reader_readline(int nchars) { if (command_ends_paging(c, focused_on_search_field)) { clear_pager(); } - // fprintf(stderr, "\n\nchar: %ls\n\n", describe_char(c).c_str()); + // fwprintf(stderr, L"\n\nchar: %ls\n\n", describe_char(c).c_str()); switch (c) { // Go to beginning of line. @@ -2607,7 +2607,7 @@ const wchar_t *reader_readline(int nchars) { // up to the end of the token we're completing. const wcstring buffcpy = wcstring(cmdsub_begin, token_end); - // fprintf(stderr, "Complete (%ls)\n", buffcpy.c_str()); + // fwprintf(stderr, L"Complete (%ls)\n", buffcpy.c_str()); complete_flags_t complete_flags = COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_DESCRIPTIONS | COMPLETION_REQUEST_FUZZY_MATCH; diff --git a/src/screen.cpp b/src/screen.cpp index 4336de082..ebbb74739 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -416,7 +416,7 @@ static void s_desired_append_char(screen_t *s, wchar_t b, int c, int indent, siz if ((s->desired.cursor.x + cw) > screen_width) { // Current line is soft wrapped (assuming we support it). s->desired.line(s->desired.cursor.y).is_soft_wrapped = true; - // fprintf(stderr, "\n\n1 Soft wrapping %d\n\n", s->desired.cursor.y); + // fwprintf(stderr, L"\n\n1 Soft wrapping %d\n\n", s->desired.cursor.y); line_no = (int)s->desired.line_count(); s->desired.add_line();