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