From 891c1cfc9a355171215821fc91b694273503f139 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Mar 2018 20:38:32 +0200 Subject: C Logging: use instead of printf for messages - See `--log` help message for usage. - Supports enabling categories. - Color severity. - Optionally logs to a file. - Currently use to replace printf calls in wm module. See D3120 for details. --- source/creator/CMakeLists.txt | 1 + source/creator/creator.c | 12 ++++++ source/creator/creator_args.c | 93 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) (limited to 'source/creator') diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a155f060335..a71c1bb1984 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -26,6 +26,7 @@ setup_libdirs() blender_include_dirs( + ../../intern/clog ../../intern/guardedalloc ../../intern/glew-mx ../blender/blenlib diff --git a/source/creator/creator.c b/source/creator/creator.c index a59a45f885c..962d6720760 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -42,6 +42,8 @@ #include "MEM_guardedalloc.h" +#include "CLG_log.h" + #include "DNA_genfile.h" #include "BLI_args.h" @@ -49,6 +51,7 @@ #include "BLI_utildefines.h" #include "BLI_callbacks.h" #include "BLI_string.h" +#include "BLI_system.h" /* mostly init functions */ #include "BKE_appdir.h" @@ -180,6 +183,11 @@ static void callback_main_atexit(void *user_data) #endif } +static void callback_clg_fatal(void *fp) +{ + BLI_system_backtrace(fp); +} + /** \} */ @@ -304,6 +312,10 @@ int main( sdlewInit(); #endif + /* Initialize logging */ + CLG_init(); + CLG_fatal_fn_set(callback_clg_fatal); + C = CTX_create(); #ifdef WITH_PYTHON_MODULE diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 25f8d732c58..17fa18916fd 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -30,6 +30,8 @@ #include "MEM_guardedalloc.h" +#include "CLG_log.h" + #ifdef WIN32 # include "BLI_winstuff.h" #endif @@ -529,6 +531,11 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo BLI_argsPrintArgDoc(ba, "--python-exit-code"); BLI_argsPrintArgDoc(ba, "--addons"); + printf("\n"); + printf("Logging Options:\n"); + BLI_argsPrintArgDoc(ba, "--log"); + BLI_argsPrintArgDoc(ba, "--log-level"); + BLI_argsPrintArgDoc(ba, "--log-file"); printf("\n"); printf("Debug Options:\n"); @@ -704,6 +711,88 @@ static int arg_handle_background_mode_set(int UNUSED(argc), const char **UNUSED( return 0; } +static const char arg_handle_log_level_set_doc[] = +"\n\tSet the logging verbosity level (higher for more details) defaults to 1." +; +static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(data)) +{ + const char *arg_id = "--log-level"; + if (argc > 1) { + const char *err_msg = NULL; + if (!parse_int_clamp(argv[1], NULL, 0, INT_MAX, &G.log.level, &err_msg)) { + printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + } + return 1; + } + else { + printf("\nError: '%s' no args given.\n", arg_id); + return 0; + } +} + +static const char arg_handle_log_file_set_doc[] = +"\n\tSet a file to output the log to." +; +static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(data)) +{ + const char *arg_id = "--log-file"; + if (argc > 1) { + errno = 0; + FILE *fp = BLI_fopen(argv[1], "w"); + if (fp == NULL) { + const char *err_msg = errno ? strerror(errno) : "unknown"; + printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + } + else { + if (UNLIKELY(G.log.file != NULL)) { + fclose(G.log.file); + } + G.log.file = fp; + CLG_output_set(G.log.file); + } + return 1; + } + else { + printf("\nError: '%s' no args given.\n", arg_id); + return 0; + } +} + +static const char arg_handle_log_set_doc[] = +"\n\tEnable logging categories, taking a single comma separated argument.\n" +"\tMultiple categories can be matched using a '.*' suffix, so '--log \"wm.*\"' logs every kind of window-manager message.\n" +"\tUse \"*\" to log everything." +; +static int arg_handle_log_set(int argc, const char **argv, void *UNUSED(data)) +{ + const char *arg_id = "--log"; + if (argc > 1) { + const char *str_step = argv[1]; + while (*str_step) { + const char *str_step_end = strchr(str_step, ','); + int str_step_len = str_step_end ? (str_step_end - str_step) : strlen(str_step); + + CLG_type_filter(str_step, str_step_len); + + if (str_step_end) { + /* typically only be one, but don't fail on multiple.*/ + while (*str_step_end == ',') { + str_step_end++; + } + str_step = str_step_end; + } + else { + break; + } + } + return 1; + } + else { + printf("\nError: '%s' no args given.\n", arg_id); + return 0; + } +} + static const char arg_handle_debug_mode_set_doc[] = "\n" "\tTurn debugging on.\n" @@ -1827,6 +1916,10 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 1, "-a", NULL, CB(arg_handle_playback_mode), NULL); + BLI_argsAdd(ba, 1, NULL, "--log-level", CB(arg_handle_log_level_set), ba); + BLI_argsAdd(ba, 1, NULL, "--log-file", CB(arg_handle_log_file_set), ba); + BLI_argsAdd(ba, 1, NULL, "--log", CB(arg_handle_log_set), ba); + BLI_argsAdd(ba, 1, "-d", "--debug", CB(arg_handle_debug_mode_set), ba); #ifdef WITH_FFMPEG -- cgit v1.2.3 From ac4513a5b84017e5e95fc4b84e3e8444fd2c8494 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 Mar 2018 12:52:47 +0200 Subject: Logging: add ability to exclude categories. --- source/creator/creator_args.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source/creator') diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 17fa18916fd..3be16ba650b 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -761,6 +761,7 @@ static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(dat static const char arg_handle_log_set_doc[] = "\n\tEnable logging categories, taking a single comma separated argument.\n" "\tMultiple categories can be matched using a '.*' suffix, so '--log \"wm.*\"' logs every kind of window-manager message.\n" +"\tUse \"^\" prefix to ignore, so '--log \"*,^wm.operator.*\"' logs all except for 'wm.operators.*'\n" "\tUse \"*\" to log everything." ; static int arg_handle_log_set(int argc, const char **argv, void *UNUSED(data)) @@ -772,7 +773,12 @@ static int arg_handle_log_set(int argc, const char **argv, void *UNUSED(data)) const char *str_step_end = strchr(str_step, ','); int str_step_len = str_step_end ? (str_step_end - str_step) : strlen(str_step); - CLG_type_filter(str_step, str_step_len); + if (str_step[0] == '^') { + CLG_type_filter_exclude(str_step + 1, str_step_len - 1); + } + else { + CLG_type_filter_include(str_step, str_step_len); + } if (str_step_end) { /* typically only be one, but don't fail on multiple.*/ -- cgit v1.2.3 From 5cb440492e2fb588765449e7a125720a2961a3f6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 Mar 2018 14:53:15 +0200 Subject: Cleanup: --help text output Some arguments missed their . --- source/creator/creator_args.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'source/creator') diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 3be16ba650b..b7150bca47f 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -712,7 +712,9 @@ static int arg_handle_background_mode_set(int UNUSED(argc), const char **UNUSED( } static const char arg_handle_log_level_set_doc[] = -"\n\tSet the logging verbosity level (higher for more details) defaults to 1." +"\n" +"\n" +"\tSet the logging verbosity level (higher for more details) defaults to 1." ; static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(data)) { @@ -731,7 +733,9 @@ static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(da } static const char arg_handle_log_file_set_doc[] = -"\n\tSet a file to output the log to." +"\n" +"\n" +"\tSet a file to output the log to." ; static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(data)) { @@ -759,8 +763,10 @@ static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(dat } static const char arg_handle_log_set_doc[] = -"\n\tEnable logging categories, taking a single comma separated argument.\n" -"\tMultiple categories can be matched using a '.*' suffix, so '--log \"wm.*\"' logs every kind of window-manager message.\n" +"\n" +"\tEnable logging categories, taking a single comma separated argument.\n" +"\tMultiple categories can be matched using a '.*' suffix,\n" +"\tso '--log \"wm.*\"' logs every kind of window-manager message.\n" "\tUse \"^\" prefix to ignore, so '--log \"*,^wm.operator.*\"' logs all except for 'wm.operators.*'\n" "\tUse \"*\" to log everything." ; @@ -1776,7 +1782,7 @@ static int arg_handle_python_console_run(int UNUSED(argc), const char **argv, vo } static const char arg_handle_python_exit_code_set_doc[] = -"\n" +"\n" "\tSet the exit-code in [0..255] to exit if a Python exception is raised\n" "\t(only for scripts executed from the command line), zero disables." ; @@ -1802,7 +1808,8 @@ static int arg_handle_python_exit_code_set(int argc, const char **argv, void *UN } static const char arg_handle_addons_set_doc[] = -"\n\tComma separated list of add-ons (no spaces)." +"\n" +"\tComma separated list of add-ons (no spaces)." ; static int arg_handle_addons_set(int argc, const char **argv, void *data) { @@ -1922,9 +1929,9 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 1, "-a", NULL, CB(arg_handle_playback_mode), NULL); + BLI_argsAdd(ba, 1, NULL, "--log", CB(arg_handle_log_set), ba); BLI_argsAdd(ba, 1, NULL, "--log-level", CB(arg_handle_log_level_set), ba); BLI_argsAdd(ba, 1, NULL, "--log-file", CB(arg_handle_log_file_set), ba); - BLI_argsAdd(ba, 1, NULL, "--log", CB(arg_handle_log_set), ba); BLI_argsAdd(ba, 1, "-d", "--debug", CB(arg_handle_debug_mode_set), ba); -- cgit v1.2.3 From db8e7f9780f9148704a986290b9493e27b350fe4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 Mar 2018 15:27:06 +0200 Subject: Logging: add argument --log-show-basename Optionally strips leading path from filenames when logging. --- source/creator/creator_args.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source/creator') diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index b7150bca47f..d4af3cd6b09 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -535,6 +535,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo printf("Logging Options:\n"); BLI_argsPrintArgDoc(ba, "--log"); BLI_argsPrintArgDoc(ba, "--log-level"); + BLI_argsPrintArgDoc(ba, "--log-show-basename"); BLI_argsPrintArgDoc(ba, "--log-file"); printf("\n"); @@ -732,6 +733,15 @@ static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(da } } +static const char arg_handle_log_show_basename_set_doc[] = +"\n\tOnly show file name in output (not the leading path)." +; +static int arg_handle_log_show_basename_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) +{ + CLG_output_use_basename_set(true); + return 0; +} + static const char arg_handle_log_file_set_doc[] = "\n" "\n" @@ -1931,6 +1941,7 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 1, NULL, "--log", CB(arg_handle_log_set), ba); BLI_argsAdd(ba, 1, NULL, "--log-level", CB(arg_handle_log_level_set), ba); + BLI_argsAdd(ba, 1, NULL, "--log-show-basename", CB(arg_handle_log_show_basename_set), ba); BLI_argsAdd(ba, 1, NULL, "--log-file", CB(arg_handle_log_file_set), ba); BLI_argsAdd(ba, 1, "-d", "--debug", CB(arg_handle_debug_mode_set), ba); -- cgit v1.2.3 From 651b8fb14eb6ee5cbfa98bffe80a966a0753b14e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Mar 2018 14:17:59 +0100 Subject: Undo: unified undo system w/ linear history - Use a single undo history for all operations. - UndoType's are registered and poll the context to check if they should be used when performing an undo push. - Mode switching is used to ensure the state is correct before undo data is restored. - Some undo types accumulate changes (image & text editing) others store the state multiple times (with de-duplication). This is supported by checking UndoStack.mode `ACCUMULATE` / `STORE`. - Each undo step stores ID datablocks they use with utilities to help manage restoring correct ID's. Needed since global undo is now mixed with other modes undo. - Currently performs each undo step when going up/down history Previously this wasn't done, making history fail in some cases. This can be optimized to skip some combinations of undo steps. grease-pencil is an exception which has not been updated since it integrates undo into the draw-session. See D3113 --- source/creator/creator_signals.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'source/creator') diff --git a/source/creator/creator_signals.c b/source/creator/creator_signals.c index 81e6178c502..feb108da289 100644 --- a/source/creator/creator_signals.c +++ b/source/creator/creator_signals.c @@ -64,6 +64,7 @@ #include "BKE_main.h" #include "BKE_report.h" + /* for passing information between creator and gameengine */ #ifdef WITH_GAMEENGINE # include "BL_System.h" @@ -75,6 +76,12 @@ #include "creator_intern.h" /* own include */ +// #define USE_WRITE_CRASH_BLEND +#ifdef USE_WRITE_CRASH_BLEND +# include "BKE_undo_system.h" +# include "BLO_undofile.h" +#endif + /* set breakpoints here when running in debug mode, useful to catch floating point errors */ #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE) static void sig_handle_fpe(int UNUSED(sig)) @@ -110,29 +117,32 @@ static void sig_handle_crash_backtrace(FILE *fp) static void sig_handle_crash(int signum) { + wmWindowManager *wm = G.main->wm.first; -#if 0 - { - char fname[FILE_MAX]; +#ifdef USE_WRITE_CRASH_BLEND + if (wm->undo_stack) { + struct MemFile *memfile = BKE_undosys_stack_memfile_get_active(wm->undo_stack); + if (memfile) { + char fname[FILE_MAX]; - if (!G.main->name[0]) { - BLI_make_file_string("/", fname, BKE_tempdir_base(), "crash.blend"); - } - else { - BLI_strncpy(fname, G.main->name, sizeof(fname)); - BLI_replace_extension(fname, sizeof(fname), ".crash.blend"); - } + if (!G.main->name[0]) { + BLI_make_file_string("/", fname, BKE_tempdir_base(), "crash.blend"); + } + else { + BLI_strncpy(fname, G.main->name, sizeof(fname)); + BLI_replace_extension(fname, sizeof(fname), ".crash.blend"); + } - printf("Writing: %s\n", fname); - fflush(stdout); + printf("Writing: %s\n", fname); + fflush(stdout); - BKE_undo_save_file(fname); + BLO_memfile_write_file(memfile, fname); + } } #endif FILE *fp; char header[512]; - wmWindowManager *wm = G.main->wm.first; char fname[FILE_MAX]; @@ -338,4 +348,4 @@ void main_signal_setup_fpe(void) #endif } -#endif /* WITH_PYTHON_MODULE */ \ No newline at end of file +#endif /* WITH_PYTHON_MODULE */ -- cgit v1.2.3