tool_msgs.c (4032B)
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 "tool_cfgable.h" 27 #include "tool_msgs.h" 28 #include "tool_cb_prg.h" 29 #include "terminal.h" 30 31 #include "memdebug.h" /* keep this as LAST include */ 32 33 #define WARN_PREFIX "Warning: " 34 #define NOTE_PREFIX "Note: " 35 #define ERROR_PREFIX "curl: " 36 37 static void voutf(struct GlobalConfig *global, 38 const char *prefix, 39 const char *fmt, 40 va_list ap) CURL_PRINTF(3, 0); 41 42 static void voutf(struct GlobalConfig *global, 43 const char *prefix, 44 const char *fmt, 45 va_list ap) 46 { 47 size_t width = (get_terminal_columns() - strlen(prefix)); 48 DEBUGASSERT(!strchr(fmt, '\n')); 49 if(!global->silent) { 50 size_t len; 51 char *ptr; 52 char *print_buffer; 53 54 print_buffer = vaprintf(fmt, ap); 55 if(!print_buffer) 56 return; 57 len = strlen(print_buffer); 58 59 ptr = print_buffer; 60 while(len > 0) { 61 fputs(prefix, tool_stderr); 62 63 if(len > width) { 64 size_t cut = width-1; 65 66 while(!ISBLANK(ptr[cut]) && cut) { 67 cut--; 68 } 69 if(0 == cut) 70 /* not a single cutting position was found, just cut it at the 71 max text width then! */ 72 cut = width-1; 73 74 (void)fwrite(ptr, cut + 1, 1, tool_stderr); 75 fputs("\n", tool_stderr); 76 ptr += cut + 1; /* skip the space too */ 77 len -= cut + 1; 78 } 79 else { 80 fputs(ptr, tool_stderr); 81 fputs("\n", tool_stderr); 82 len = 0; 83 } 84 } 85 curl_free(print_buffer); 86 } 87 } 88 89 /* 90 * Emit 'note' formatted message on configured 'errors' stream, if verbose was 91 * selected. 92 */ 93 void notef(struct GlobalConfig *global, const char *fmt, ...) 94 { 95 va_list ap; 96 va_start(ap, fmt); 97 if(global->tracetype) 98 voutf(global, NOTE_PREFIX, fmt, ap); 99 va_end(ap); 100 } 101 102 /* 103 * Emit warning formatted message on configured 'errors' stream unless 104 * mute (--silent) was selected. 105 */ 106 void warnf(struct GlobalConfig *global, const char *fmt, ...) 107 { 108 va_list ap; 109 va_start(ap, fmt); 110 voutf(global, WARN_PREFIX, fmt, ap); 111 va_end(ap); 112 } 113 114 /* 115 * Emit help formatted message on given stream. This is for errors with or 116 * related to command line arguments. 117 */ 118 void helpf(FILE *errors, const char *fmt, ...) 119 { 120 if(fmt) { 121 va_list ap; 122 va_start(ap, fmt); 123 DEBUGASSERT(!strchr(fmt, '\n')); 124 fputs("curl: ", errors); /* prefix it */ 125 vfprintf(errors, fmt, ap); 126 va_end(ap); 127 fputs("\n", errors); /* newline it */ 128 } 129 fprintf(errors, "curl: try 'curl --help' " 130 #ifdef USE_MANUAL 131 "or 'curl --manual' " 132 #endif 133 "for more information\n"); 134 } 135 136 /* 137 * Emit error message on error stream if not muted. When errors are not tied 138 * to command line arguments, use helpf() for such errors. 139 */ 140 void errorf(struct GlobalConfig *global, const char *fmt, ...) 141 { 142 if(!global->silent || global->showerror) { 143 va_list ap; 144 va_start(ap, fmt); 145 voutf(global, ERROR_PREFIX, fmt, ap); 146 va_end(ap); 147 } 148 }