1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2020 Intel Corporation. All rights reserved.
4 *
5 * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
6 */
7
8 #include "convert.h"
9 #include <ctype.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
log_vasprintf(const char * format,va_list args)15 char *log_vasprintf(const char *format, va_list args)
16 {
17 va_list args_copy;
18 int size;
19 char localbuf[1];
20 char *result;
21
22 va_copy(args_copy, args);
23 size = vsnprintf(localbuf, 1, format, args_copy);
24 va_end(args_copy);
25
26 result = malloc(size + 1);
27 if (result)
28 vsnprintf(result, size + 1, format, args);
29 return result;
30 }
31
log_asprintf(const char * format,...)32 char *log_asprintf(const char *format, ...)
33 {
34 va_list args;
35 char *result;
36
37 va_start(args, format);
38 result = log_vasprintf(format, args);
39 va_end(args);
40
41 return result;
42 }
43
44 /** Prints 1. once to stderr. 2. a second time to the global out_fd if
45 * out_fd is neither stderr nor stdout (because the -o option was used).
46 */
log_err(const char * fmt,...)47 void log_err(const char *fmt, ...)
48 {
49 FILE *out_fd = global_config ? global_config->out_fd : NULL;
50 static const char prefix[] = "error: ";
51 ssize_t needed_size;
52 va_list args, args_alloc;
53 char *buff;
54
55 va_start(args, fmt);
56
57 /* Print into buff first, then outputs buff twice */
58 va_copy(args_alloc, args);
59 needed_size = vsnprintf(NULL, 0, fmt, args_alloc) + 1;
60 buff = malloc(needed_size);
61 va_end(args_alloc);
62
63 if (buff) {
64 vsprintf(buff, fmt, args);
65 fprintf(stderr, "%s%s", prefix, buff);
66
67 /* take care about out_fd validity and duplicated logging */
68 if (out_fd && out_fd != stderr && out_fd != stdout) {
69 fprintf(out_fd, "%s%s", prefix, buff);
70 fflush(out_fd);
71 }
72 free(buff);
73 } else {
74 fprintf(stderr, "%s", prefix);
75 vfprintf(stderr, fmt, args);
76 }
77
78 va_end(args);
79 }
80
81 /* trim whitespaces from string begin */
ltrim(char * s)82 char *ltrim(char *s)
83 {
84 while (isspace((int)*s))
85 s++;
86 return s;
87 }
88
89 /* trim whitespaces from string end */
rtrim(char * s)90 char *rtrim(char *s)
91 {
92 char *ptr = s + strlen(s) - 1;
93
94 while (ptr >= s && isspace((int)*ptr)) {
95 *ptr = '\0';
96 --ptr;
97 }
98 return s;
99 }
100
101 /* trim whitespaces from string begin and end*/
trim(char * s)102 char *trim(char *s)
103 {
104 return ltrim(rtrim(s));
105 }
106