From 977d07a3ae47ef204665d1eda2d642e5064724f3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 24 Jun 2019 12:01:19 +0200 Subject: Split build system into library and driver --- build2/diagnostics.hxx | 435 ------------------------------------------------- 1 file changed, 435 deletions(-) delete mode 100644 build2/diagnostics.hxx (limited to 'build2/diagnostics.hxx') diff --git a/build2/diagnostics.hxx b/build2/diagnostics.hxx deleted file mode 100644 index 992e741..0000000 --- a/build2/diagnostics.hxx +++ /dev/null @@ -1,435 +0,0 @@ -// file : build2/diagnostics.hxx -*- C++ -*- -// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD2_DIAGNOSTICS_HXX -#define BUILD2_DIAGNOSTICS_HXX - -#include - -#include -#include - -namespace build2 -{ - using butl::diag_record; - - // Throw this exception to terminate the build. The handler should - // assume that the diagnostics has already been issued. - // - class failed: public std::exception {}; - - // Print process commmand line. If the number of elements is specified - // (or the second version is used), then it will print the piped multi- - // process command line, if present. In this case, the expected format - // is as follows: - // - // name1 arg arg ... nullptr - // name2 arg arg ... nullptr - // ... - // nameN arg arg ... nullptr nullptr - // - void - print_process (diag_record&, const char* const* args, size_t n = 0); - - void - print_process (const char* const* args, size_t n = 0); - - inline void - print_process (diag_record& dr, const cstrings& args, size_t n = 0) - { - print_process (dr, args.data (), n != 0 ? n : args.size ()); - } - - inline void - print_process (const cstrings& args, size_t n = 0) - { - print_process (args.data (), n != 0 ? n : args.size ()); - } - - // Program verbosity level (-v/--verbose). - // - // 0 - disabled - // 1 - high-level information messages - // 2 - essential underlying commands that are being executed - // 3 - all underlying commands that are being executed - // 4 - information helpful to the user (e.g., why a rule did not match) - // 5 - information helpful to the developer - // 6 - even more detailed information - // - // While uint8 is more than enough, use uint16 for the ease of printing. - // - - // Forward-declarated in utility.hxx. - // - // extern uint16_t verb; - // const uint16_t verb_never = 7; - - template inline void l1 (const F& f) {if (verb >= 1) f ();} - template inline void l2 (const F& f) {if (verb >= 2) f ();} - template inline void l3 (const F& f) {if (verb >= 3) f ();} - template inline void l4 (const F& f) {if (verb >= 4) f ();} - template inline void l5 (const F& f) {if (verb >= 5) f ();} - template inline void l6 (const F& f) {if (verb >= 6) f ();} - - // Stream verbosity level. Determined by the diagnostic type (e.g., trace - // always has maximum verbosity) as well as the program verbosity. It is - // used to decide whether to print relative/absolute paths and default - // target extensions. - // - // Currently we have the following program to stream verbosity mapping: - // - // fail/error/warn/info <2:{0,0} 2:{0,1} >2:{1,2} - // trace *:{1,2} - // - // A stream that hasn't been (yet) assigned any verbosity explicitly (e.g., - // ostringstream) defaults to maximum. - // - struct stream_verbosity - { - union - { - struct - { - // 0 - print relative. - // 1 - print absolute. - // - uint16_t path: 1; - - // 0 - don't print. - // 1 - print if specified. - // 2 - print as 'foo.?' if unspecified and 'foo.' if specified as - // "no extension" (empty). - // - uint16_t extension: 2; - }; - uint16_t value_; - }; - - constexpr - stream_verbosity (uint16_t p, uint16_t e): path (p), extension (e) {} - - explicit - stream_verbosity (uint16_t v = 0): value_ (v) {} - }; - - constexpr stream_verbosity stream_verb_max = {1, 2}; - - // Default program to stream verbosity mapping, as outlined above. - // - inline stream_verbosity - stream_verb_map () - { - return - verb < 2 ? stream_verbosity (0, 0) : - verb > 2 ? stream_verbosity (1, 2) : - /* */ stream_verbosity (0, 1); - } - - extern const int stream_verb_index; - - inline stream_verbosity - stream_verb (ostream& os) - { - long v (os.iword (stream_verb_index)); - return v == 0 - ? stream_verb_max - : stream_verbosity (static_cast (v - 1)); - } - - inline void - stream_verb (ostream& os, stream_verbosity v) - { - os.iword (stream_verb_index) = static_cast (v.value_) + 1; - } - - // Progress reporting. - // - using butl::diag_progress; - using butl::diag_progress_lock; - - // Return true if progress is to be shown. The max_verb argument is the - // maximum verbosity level that this type of progress should be shown by - // default. - // - inline bool - show_progress (uint16_t max_verb) - { - return diag_progress_option - ? *diag_progress_option - : stderr_term && verb >= 1 && verb <= max_verb; - } - - // Diagnostic facility, base infrastructure. - // - using butl::diag_stream_lock; - using butl::diag_stream; - using butl::diag_epilogue; - - // Diagnostics stack. Each frame is "applied" to the fail/error/warn/info - // diag record. - // - // Unfortunately most of our use-cases don't fit into the 2-pointer small - // object optimization of std::function. So we have to complicate things - // a bit here. - // - struct diag_frame - { - explicit - diag_frame (void (*f) (const diag_frame&, const diag_record&)) - : func_ (f) - { - if (func_ != nullptr) - { - prev_ = stack; - stack = this; - } - } - - diag_frame (diag_frame&& x) - : func_ (x.func_) - { - if (func_ != nullptr) - { - prev_ = x.prev_; - stack = this; - - x.func_ = nullptr; - } - } - - diag_frame& operator= (diag_frame&&) = delete; - - diag_frame (const diag_frame&) = delete; - diag_frame& operator= (const diag_frame&) = delete; - - ~diag_frame () - { - if (func_ != nullptr ) - stack = prev_; - } - - static void - apply (const diag_record& r) - { - for (const diag_frame* f (stack); f != nullptr; f = f->prev_) - f->func_ (*f, r); - } - - static -#ifdef __cpp_thread_local - thread_local -#else - __thread -#endif - const diag_frame* stack; // Tip of the stack. - - struct stack_guard - { - explicit stack_guard (const diag_frame* s): s_ (stack) {stack = s;} - ~stack_guard () {stack = s_;} - const diag_frame* s_; - }; - - private: - void (*func_) (const diag_frame&, const diag_record&); - const diag_frame* prev_; - }; - - template - struct diag_frame_impl: diag_frame - { - explicit - diag_frame_impl (F f): diag_frame (&thunk), func_ (move (f)) {} - - private: - static void - thunk (const diag_frame& f, const diag_record& r) - { - static_cast (f).func_ (r); - } - - const F func_; - }; - - template - inline diag_frame_impl - make_diag_frame (F f) - { - return diag_frame_impl (move (f)); - } - - // Diagnostic facility, project specifics. - // - struct simple_prologue_base - { - explicit - simple_prologue_base (const char* type, - const char* mod, - const char* name, - stream_verbosity sverb) - : type_ (type), mod_ (mod), name_ (name), sverb_ (sverb) {} - - void - operator() (const diag_record& r) const; - - private: - const char* type_; - const char* mod_; - const char* name_; - const stream_verbosity sverb_; - }; - - struct location_prologue_base - { - location_prologue_base (const char* type, - const char* mod, - const char* name, - const location& l, - stream_verbosity sverb) - : type_ (type), mod_ (mod), name_ (name), - loc_ (l), - sverb_ (sverb) {} - - location_prologue_base (const char* type, - const char* mod, - const char* name, - path&& f, - stream_verbosity sverb) - : type_ (type), mod_ (mod), name_ (name), - file_ (move (f)), loc_ (&file_), - sverb_ (sverb) {} - - void - operator() (const diag_record& r) const; - - private: - const char* type_; - const char* mod_; - const char* name_; - const path file_; - const location loc_; - const stream_verbosity sverb_; - }; - - struct basic_mark_base - { - using simple_prologue = butl::diag_prologue; - using location_prologue = butl::diag_prologue; - - explicit - basic_mark_base (const char* type, - const void* data = nullptr, - diag_epilogue* epilogue = &diag_frame::apply, - stream_verbosity (*sverb) () = &stream_verb_map, - const char* mod = nullptr, - const char* name = nullptr) - : sverb_ (sverb), - type_ (type), mod_ (mod), name_ (name), data_ (data), - epilogue_ (epilogue) {} - - simple_prologue - operator() () const - { - return simple_prologue (epilogue_, type_, mod_, name_, sverb_ ()); - } - - location_prologue - operator() (const location& l) const - { - return location_prologue (epilogue_, type_, mod_, name_, l, sverb_ ()); - } - - // fail (relative (src)) << ... - // - location_prologue - operator() (path&& f) const - { - return location_prologue ( - epilogue_, type_, mod_, name_, move (f), sverb_ ()); - } - - template - location_prologue - operator() (const L& l) const - { - return location_prologue ( - epilogue_, type_, mod_, name_, get_location (l, data_), sverb_ ()); - } - - protected: - stream_verbosity (*sverb_) (); - const char* type_; - const char* mod_; - const char* name_; - const void* data_; - diag_epilogue* const epilogue_; - }; - using basic_mark = butl::diag_mark; - - extern const basic_mark error; - extern const basic_mark warn; - extern const basic_mark info; - extern const basic_mark text; - - // trace - // - struct trace_mark_base: basic_mark_base - { - explicit - trace_mark_base (const char* name, const void* data = nullptr) - : trace_mark_base (nullptr, name, data) {} - - trace_mark_base (const char* mod, - const char* name, - const void* data = nullptr) - : basic_mark_base ("trace", - data, - nullptr, // No diag stack. - []() {return stream_verb_max;}, - mod, - name) {} - }; - using trace_mark = butl::diag_mark; - using tracer = trace_mark; - - // fail - // - struct fail_mark_base: basic_mark_base - { - explicit - fail_mark_base (const char* type, - const void* data = nullptr) - : basic_mark_base (type, - data, - [](const diag_record& r) - { - diag_frame::apply (r); - r.flush (); - throw failed (); - }, - &stream_verb_map, - nullptr, - nullptr) {} - }; - using fail_mark = butl::diag_mark; - - struct fail_end_base - { - [[noreturn]] void - operator() (const diag_record& r) const - { - // If we just throw then the record's destructor will see an active - // exception and will not flush the record. - // - r.flush (); - throw failed (); - } - }; - using fail_end = butl::diag_noreturn_end; - - extern const fail_mark fail; - extern const fail_end endf; -} - -#endif // BUILD2_DIAGNOSTICS_HXX -- cgit v1.1