1 // Copyright (c) 2019 nyorain 2 // Distributed under the Boost Software License, Version 1.0. 3 // See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt 4 5 #ifndef INC_DLG_OUTPUT_H_ 6 #define INC_DLG_OUTPUT_H_ 7 8 #include <dlg/dlg.h> 9 #include <stdio.h> 10 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 14 15 // Text style 16 enum dlg_text_style { 17 dlg_text_style_reset = 0, 18 dlg_text_style_bold = 1, 19 dlg_text_style_dim = 2, 20 dlg_text_style_italic = 3, 21 dlg_text_style_underline = 4, 22 dlg_text_style_blink = 5, 23 dlg_text_style_rblink = 6, 24 dlg_text_style_reversed = 7, 25 dlg_text_style_conceal = 8, 26 dlg_text_style_crossed = 9, 27 dlg_text_style_none, 28 }; 29 30 // Text color 31 enum dlg_color { 32 dlg_color_black = 0, 33 dlg_color_red, 34 dlg_color_green, 35 dlg_color_yellow, 36 dlg_color_blue, 37 dlg_color_magenta, 38 dlg_color_cyan, 39 dlg_color_gray, 40 dlg_color_reset = 9, 41 42 dlg_color_black2 = 60, 43 dlg_color_red2, 44 dlg_color_green2, 45 dlg_color_yellow2, 46 dlg_color_blue2, 47 dlg_color_magenta2, 48 dlg_color_cyan2, 49 dlg_color_gray2, 50 51 dlg_color_none = 69, 52 }; 53 54 struct dlg_style { 55 enum dlg_text_style style; 56 enum dlg_color fg; 57 enum dlg_color bg; 58 }; 59 60 // Like fprintf but fixes utf-8 output to console on windows. 61 // On non-windows sytems just uses the corresponding standard library 62 // functions. On windows, if dlg was compiled with the win_console option, 63 // will first try to output it in a way that allows the default console 64 // to display utf-8. If that fails, will fall back to the standard 65 // library functions. 66 DLG_API int dlg_fprintf(FILE* stream, const char* format, ...) DLG_PRINTF_ATTRIB(2, 3); 67 DLG_API int dlg_vfprintf(FILE* stream, const char* format, va_list list); 68 69 // Like dlg_printf, but also applies the given style to this output. 70 // The style will always be applied (using escape sequences), independent of the given stream. 71 // On windows escape sequences don't work out of the box, see dlg_win_init_ansi(). 72 DLG_API int dlg_styled_fprintf(FILE* stream, struct dlg_style style, 73 const char* format, ...) DLG_PRINTF_ATTRIB(3, 4); 74 75 // Features to output from the generic output handler. 76 // Some features might have only an effect in the specializations. 77 enum dlg_output_feature { 78 dlg_output_tags = 1, // output tags list 79 dlg_output_time = 2, // output time of log call (hour:minute:second) 80 dlg_output_style = 4, // whether to use the supplied styles 81 dlg_output_func = 8, // output function 82 dlg_output_file_line = 16, // output file:line, 83 dlg_output_newline = 32, // output a newline at the end 84 dlg_output_threadsafe = 64, // locks stream before printing 85 dlg_output_time_msecs = 128 // output micro seconds (ms on windows) 86 }; 87 88 // The default level-dependent output styles. The array values represent the styles 89 // to be used for the associated level (i.e. [0] for trace level). 90 DLG_API extern const struct dlg_style dlg_default_output_styles[6]; 91 92 // Generic output function. Used by the default output handler and might be useful 93 // for custom output handlers (that don't want to manually format the output). 94 // Will call the given output func with the given data (and format + args to print) 95 // for everything it has to print in printf format. 96 // See also the *_stream and *_buf specializations for common usage. 97 // The given output function must not be NULL. 98 typedef void(*dlg_generic_output_handler)(void* data, const char* format, ...); 99 DLG_API void dlg_generic_output(dlg_generic_output_handler output, void* data, 100 unsigned int features, const struct dlg_origin* origin, const char* string, 101 const struct dlg_style styles[6]); 102 103 // Generic output function, using a format string instead of feature flags. 104 // Use following conversion characters: 105 // %h - output the time in H:M:S format 106 // %m - output the time in milliseconds 107 // %t - output the full list of tags, comma separated 108 // %f - output the function name noted in the origin 109 // %o - output the file:line of the origin 110 // %s - print the appropriate style escape sequence. 111 // %r - print the escape sequence to reset the style. 112 // %c - The content of the log/assert 113 // %% - print the '%' character 114 // Only the above specified conversion characters are valid, the rest are 115 // written as it is. 116 DLG_API void dlg_generic_outputf(dlg_generic_output_handler output, void* data, 117 const char* format_string, const struct dlg_origin* origin, 118 const char* string, const struct dlg_style styles[6]); 119 120 // Generic output function. Used by the default output handler and might be useful 121 // for custom output handlers (that don't want to manually format the output). 122 // If stream is NULL uses stdout. 123 // Automatically uses dlg_fprintf to assure correct utf-8 even on windows consoles. 124 // Locks the stream (i.e. assures threadsafe access) when the associated feature 125 // is passed (note that stdout/stderr might still mix from multiple threads). 126 DLG_API void dlg_generic_output_stream(FILE* stream, unsigned int features, 127 const struct dlg_origin* origin, const char* string, 128 const struct dlg_style styles[6]); 129 DLG_API void dlg_generic_outputf_stream(FILE* stream, const char* format_string, 130 const struct dlg_origin* origin, const char* string, 131 const struct dlg_style styles[6], bool lock_stream); 132 133 // Generic output function (see dlg_generic_output) that uses a buffer instead of 134 // a stream. buf must at least point to *size bytes. Will set *size to the number 135 // of bytes written (capped to the given size), if buf == NULL will set *size 136 // to the needed size. The size parameter must not be NULL. 137 DLG_API void dlg_generic_output_buf(char* buf, size_t* size, unsigned int features, 138 const struct dlg_origin* origin, const char* string, 139 const struct dlg_style styles[6]); 140 DLG_API void dlg_generic_outputf_buf(char* buf, size_t* size, const char* format_string, 141 const struct dlg_origin* origin, const char* string, 142 const struct dlg_style styles[6]); 143 144 // Returns if the given stream is a tty. Useful for custom output handlers 145 // e.g. to determine whether to use color. 146 // NOTE: Due to windows limitations currently returns false for wsl ttys. 147 DLG_API bool dlg_is_tty(FILE* stream); 148 149 // Returns the null-terminated escape sequence for the given style into buf. 150 // Undefined behvaiour if any member of style has a value outside its enum range (will 151 // probably result in a buffer overflow or garbage being printed). 152 // If all member of style are 'none' will simply nullterminate the first buf char. 153 DLG_API void dlg_escape_sequence(struct dlg_style style, char buf[12]); 154 155 // The reset style escape sequence. 156 DLG_API extern const char* const dlg_reset_sequence; 157 158 // Just returns true without other effect on non-windows systems or if dlg 159 // was compiled without the win_console option. 160 // On windows tries to set the console mode to ansi to make escape sequences work. 161 // This works only on newer windows 10 versions. Returns false on error. 162 // Only the first call to it will have an effect, following calls just return the result. 163 // The function is threadsafe. Automatically called by the default output handler. 164 // This will only be able to set the mode for the stdout and stderr consoles, so 165 // other streams to consoles will still not work. 166 DLG_API bool dlg_win_init_ansi(void); 167 168 #ifdef __cplusplus 169 } // extern "C" 170 #endif 171 172 #endif // header guard 173