xref: /curl/src/tool_msgs.c (revision 573e7e82)
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 #include "tool_setup.h"
25 
26 #include "curlx.h"
27 
28 #include "tool_cfgable.h"
29 #include "tool_msgs.h"
30 #include "tool_cb_prg.h"
31 #include "terminal.h"
32 
33 #include "memdebug.h" /* keep this as LAST include */
34 
35 #define WARN_PREFIX "Warning: "
36 #define NOTE_PREFIX "Note: "
37 #define ERROR_PREFIX "curl: "
38 
39 static void voutf(struct GlobalConfig *config,
40                   const char *prefix,
41                   const char *fmt,
42                   va_list ap) CURL_PRINTF(3, 0);
43 
voutf(struct GlobalConfig * config,const char * prefix,const char * fmt,va_list ap)44 static void voutf(struct GlobalConfig *config,
45                   const char *prefix,
46                   const char *fmt,
47                   va_list ap)
48 {
49   size_t width = (get_terminal_columns() - strlen(prefix));
50   DEBUGASSERT(!strchr(fmt, '\n'));
51   if(!config->silent) {
52     size_t len;
53     char *ptr;
54     char *print_buffer;
55 
56     print_buffer = vaprintf(fmt, ap);
57     if(!print_buffer)
58       return;
59     len = strlen(print_buffer);
60 
61     ptr = print_buffer;
62     while(len > 0) {
63       fputs(prefix, tool_stderr);
64 
65       if(len > width) {
66         size_t cut = width-1;
67 
68         while(!ISBLANK(ptr[cut]) && cut) {
69           cut--;
70         }
71         if(0 == cut)
72           /* not a single cutting position was found, just cut it at the
73              max text width then! */
74           cut = width-1;
75 
76         (void)fwrite(ptr, cut + 1, 1, tool_stderr);
77         fputs("\n", tool_stderr);
78         ptr += cut + 1; /* skip the space too */
79         len -= cut + 1;
80       }
81       else {
82         fputs(ptr, tool_stderr);
83         fputs("\n", tool_stderr);
84         len = 0;
85       }
86     }
87     curl_free(print_buffer);
88   }
89 }
90 
91 /*
92  * Emit 'note' formatted message on configured 'errors' stream, if verbose was
93  * selected.
94  */
notef(struct GlobalConfig * config,const char * fmt,...)95 void notef(struct GlobalConfig *config, const char *fmt, ...)
96 {
97   va_list ap;
98   va_start(ap, fmt);
99   if(config->tracetype)
100     voutf(config, NOTE_PREFIX, fmt, ap);
101   va_end(ap);
102 }
103 
104 /*
105  * Emit warning formatted message on configured 'errors' stream unless
106  * mute (--silent) was selected.
107  */
warnf(struct GlobalConfig * config,const char * fmt,...)108 void warnf(struct GlobalConfig *config, const char *fmt, ...)
109 {
110   va_list ap;
111   va_start(ap, fmt);
112   voutf(config, WARN_PREFIX, fmt, ap);
113   va_end(ap);
114 }
115 
116 /*
117  * Emit help formatted message on given stream. This is for errors with or
118  * related to command line arguments.
119  */
helpf(FILE * errors,const char * fmt,...)120 void helpf(FILE *errors, const char *fmt, ...)
121 {
122   if(fmt) {
123     va_list ap;
124     va_start(ap, fmt);
125     DEBUGASSERT(!strchr(fmt, '\n'));
126     fputs("curl: ", errors); /* prefix it */
127     vfprintf(errors, fmt, ap);
128     va_end(ap);
129     fputs("\n", errors); /* newline it */
130   }
131   fprintf(errors, "curl: try 'curl --help' "
132 #ifdef USE_MANUAL
133           "or 'curl --manual' "
134 #endif
135           "for more information\n");
136 }
137 
138 /*
139  * Emit error message on error stream if not muted. When errors are not tied
140  * to command line arguments, use helpf() for such errors.
141  */
errorf(struct GlobalConfig * config,const char * fmt,...)142 void errorf(struct GlobalConfig *config, const char *fmt, ...)
143 {
144   if(!config->silent || config->showerror) {
145     va_list ap;
146     va_start(ap, fmt);
147     voutf(config, ERROR_PREFIX, fmt, ap);
148     va_end(ap);
149   }
150 }
151