1 #ifndef VERBOSE_H_ 2 #define VERBOSE_H_ 3 4 #include <stdarg.h> 5 #include <stdio.h> 6 #include "params.h" 7 #include "macros.h" // ATTR_PRINTF 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 /* This provides fine-grain control over which messages we want. In order 14 * to add a new flag, you must define its name as a preprocessor integer 15 * macro here, and define a corresponding text string in verbose.c 16 */ 17 18 #define CADO_VERBOSE_PRINT_CMDLINE 0 19 #define CADO_VERBOSE_PRINT_MODIFIED_FILES 1 20 #define CADO_VERBOSE_PRINT_COMPILATION_INFO 2 21 #define CADO_VERBOSE_PRINT_BWC_DISPATCH_SLAVES 3 22 #define CADO_VERBOSE_PRINT_BWC_DISPATCH_MASTER 4 23 #define CADO_VERBOSE_PRINT_BWC_TIMING_GRIDS 5 24 #define CADO_VERBOSE_PRINT_BWC_ITERATION_TIMINGS 6 25 #define CADO_VERBOSE_PRINT_BWC_CACHE_BUILD 7 26 #define CADO_VERBOSE_PRINT_BWC_DISPATCH_OUTER 8 27 #define CADO_VERBOSE_PRINT_BWC_CPUBINDING 9 28 #define CADO_VERBOSE_PRINT_BWC_CACHE_MAJOR_INFO 10 29 #define CADO_VERBOSE_PRINT_BWC_LOADING_MKSOL_FILES 11 30 31 typedef int (*vfprintf_func_t)(FILE *, const char *, va_list); 32 33 /* This must be called in single-threaded context, preferably at program 34 * start */ 35 extern void verbose_interpret_parameters(param_list pl); 36 37 extern int verbose_enabled(int flag); 38 extern int verbose_vfprintf(FILE * f, int flag, const char * fmt, va_list ap); 39 extern int verbose_vprintf(int flag, const char * fmt, va_list ap); 40 extern int verbose_fprintf(FILE * f, int flag, const char * fmt, ...); 41 extern int verbose_printf(int flag, const char * fmt, ...); 42 extern void verbose_output_flush(const size_t channel, const int verbose); 43 extern void verbose_decl_usage(param_list pl); 44 45 46 /* 47 The program can initialise zero or more "channels". 48 To each "channel", zero or more "outputs" (FILE handles) can be attached, 49 each with an output verbosity value. 50 Text can be printed to a channel, with a verbosity v, then the text is 51 sent to each output attached to this channel for which the output verbosity 52 is at least v. 53 The default behaviour, before calling the verbose_output_init() function or 54 after calling verbose_output_clear(), has 2 channels: 55 channel 0 with 1 output, going to stdout with verbosity 1, and 56 channel 1 with 1 output, going to stderr with verbosity 1. 57 All functions are mutex-protected, i.e., the output system forms a 58 "monitor." 59 */ 60 61 /* Lock the output system for exclusive use for a while. 62 Useful for, e.g., printing lines with multiple calls, or multiple 63 consecutive lines, through multiple verbose_output_*() calls. */ 64 int verbose_output_start_batch(); 65 66 /* Unlock the output system again. Only the locking thread may call it. */ 67 int verbose_output_end_batch(); 68 69 /* Init nr_channels channels, with no outputs attached 70 Returns 1 on success, and 0 on error. */ 71 int verbose_output_init(size_t nr_channels); 72 73 /* Reset channels back to the 2 default channels. 74 Returns 1 on success, and 0 on error. */ 75 int verbose_output_clear(); 76 77 /* Add an output FILE handle to a channel with the given verbosity. 78 Returns 1 on success, and 0 on error. */ 79 int verbose_output_add(size_t channel, FILE * out, int verbose); 80 81 /* Print formatted output (using libc's printf() formatting) to all outputs 82 attached to the given channel where the output's verbosity is at least 83 the given verbosity parameter. 84 Returns the return value of the last printf() call on success, 85 or 0 if nothing gets printed. Returns a negative value on error. */ 86 int verbose_output_print(size_t channel, int verbose, const char *fmt, ...) ATTR_PRINTF (3, 4); 87 88 /* Get the index-th FILE handle attached to a channel, counting only those 89 outputs whose output verbosity is at least "verbose." 90 If there are fewer than index such handles, returns NULL. 91 92 This is rather hackish, but we need it to be able to pass a FILE handle 93 to functions that, e.g., print complex data to a stream. 94 95 The idiom to use to print to every attached output would be something like 96 97 FILE *out; 98 for (size_t i=0; (out=verbose_output_get(c, v, i)) != NULL; i++) 99 print_something(out, ...); 100 */ 101 FILE *verbose_output_get(size_t channel, int verbose, size_t index); 102 103 /* Print to every attached output, using a print function with a vfprintf()- 104 like interface. E.g., 105 106 verbose_output_vfprint(0, 1, gmp_vfprintf, "%Zd\n", bigint); 107 108 Note that GMP requires stdarg.h to be included BEFORE gmp.h to be able 109 to declare prototypes for functions that take va_list. 110 111 WARNING: do not print PRI?64 format strings with gmp_vfprintf(), this 112 crashes on MinGW! */ 113 int verbose_output_vfprint(size_t channel, int verbose, vfprintf_func_t func, 114 const char * fmt, ...); 115 116 #ifdef __cplusplus 117 } 118 #endif 119 120 #endif /* VERBOSE_H_ */ 121