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