1 /* ======================================================================== */
2 /*  JZPRINT -- Wrapper around printf() to vector stdout as appropriate.     */
3 /* ======================================================================== */
4 
5 
6 #include "config.h"
7 #include "misc/printer.h"
8 #include <stdio.h>
9 #include <stdarg.h>
10 
11 int    jzp_silent = 0;
12 FILE  *jzp_stdout = NULL;
13 int  (*jzp_vprintf)(void *arg, const char *fmt, va_list ap) = NULL;
14 void  *jzp_vprintf_arg = NULL;
15 
jzp_printf_impl(const char * fmt,va_list ap)16 LOCAL int jzp_printf_impl(const char *fmt, va_list ap)
17 {
18     int retval = 0;
19 
20     if (jzp_silent)
21         return strlen(fmt); /* non-zero and plausible */
22 
23     if (jzp_stdout)
24         retval = vfprintf(jzp_stdout, fmt, ap);
25 
26     if (jzp_vprintf)
27         retval = jzp_vprintf(jzp_vprintf_arg, fmt, ap);
28 
29     if (!retval)
30         retval = strlen(fmt);
31 
32     return retval;
33 }
34 
jzp_printf(const char * fmt,...)35 int jzp_printf(const char *fmt, ...)
36 {
37     va_list ap;
38     int retval;
39     va_start(ap, fmt);
40     retval = jzp_printf_impl(fmt, ap);
41     va_end(ap);
42     return retval;
43 }
44 
45 
jzp_flush(void)46 void jzp_flush(void)
47 {
48     if (!jzp_silent && jzp_stdout)
49         fflush(jzp_stdout);
50 }
51 
jzp_clear_and_eol(int cur_len)52 void jzp_clear_and_eol(int cur_len)
53 {
54     int w = get_disp_width();
55     jzp_printf("%*s", cur_len < w ? w - cur_len - 1: 0, "\n");
56 }
57 
jzp_init(int silent,FILE * fout,int (* fn)(void *,const char *,va_list),void * fn_arg)58 void jzp_init
59 (
60     int silent,
61     FILE *fout,
62     int  (*fn)(void *, const char *, va_list),
63     void *fn_arg
64 )
65 {
66     jzp_silent  = silent;
67     jzp_stdout  = fout;
68     jzp_vprintf = fn;
69     jzp_vprintf_arg = fn_arg;
70 }
71 
jzp_printf_wrap(void * unused,const char * fmt,...)72 LOCAL void jzp_printf_wrap(void *unused, const char *fmt, ...)
73 {
74     va_list ap;
75     UNUSED(unused);
76     va_start(ap, fmt);
77     jzp_printf_impl(fmt, ap);
78     va_end(ap);
79 }
80 
81 LOCAL printer_t jzp_printer_adaptor = { jzp_printf_wrap, NULL };
82 
jzp_printer(void)83 struct printer_t *jzp_printer(void)
84 {
85     return &jzp_printer_adaptor;
86 }
87