/proc/self/cwd/external/cpuinfo/src/log.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <assert.h> |
2 | | #include <stdarg.h> |
3 | | #include <string.h> |
4 | | #include <stdlib.h> |
5 | | #include <stdio.h> |
6 | | #ifdef _WIN32 |
7 | | #include <windows.h> |
8 | | #else |
9 | | #include <unistd.h> |
10 | | #endif |
11 | | #if defined(__ANDROID__) |
12 | | #include <android/log.h> |
13 | | #endif |
14 | | #if defined(__hexagon__) |
15 | | #include <qurt_printf.h> |
16 | | #endif |
17 | | |
18 | | #ifndef CPUINFO_LOG_TO_STDIO |
19 | | #if defined(__ANDROID__) |
20 | | #define CPUINFO_LOG_TO_STDIO 0 |
21 | | #else |
22 | | #define CPUINFO_LOG_TO_STDIO 1 |
23 | | #endif |
24 | | #endif |
25 | | |
26 | | #include <cpuinfo/log.h> |
27 | | |
28 | | |
29 | | /* Messages up to this size are formatted entirely on-stack, and don't allocate heap memory */ |
30 | 0 | #define CPUINFO_LOG_STACK_BUFFER_SIZE 1024 |
31 | | |
32 | | #ifdef _WIN32 |
33 | | #define CPUINFO_LOG_NEWLINE_LENGTH 2 |
34 | | |
35 | | #define CPUINFO_LOG_STDERR STD_ERROR_HANDLE |
36 | | #define CPUINFO_LOG_STDOUT STD_OUTPUT_HANDLE |
37 | | #elif defined(__hexagon__) |
38 | | #define CPUINFO_LOG_NEWLINE_LENGTH 1 |
39 | | |
40 | | #define CPUINFO_LOG_STDERR 0 |
41 | | #define CPUINFO_LOG_STDOUT 0 |
42 | | #else |
43 | 0 | #define CPUINFO_LOG_NEWLINE_LENGTH 1 |
44 | | |
45 | 0 | #define CPUINFO_LOG_STDERR STDERR_FILENO |
46 | | #define CPUINFO_LOG_STDOUT STDOUT_FILENO |
47 | | #endif |
48 | | |
49 | | #if CPUINFO_LOG_TO_STDIO |
50 | 0 | static void cpuinfo_vlog(int output_handle, const char* prefix, size_t prefix_length, const char* format, va_list args) { |
51 | 0 | char stack_buffer[CPUINFO_LOG_STACK_BUFFER_SIZE]; |
52 | 0 | char* heap_buffer = NULL; |
53 | 0 | char* out_buffer = &stack_buffer[0]; |
54 | | |
55 | | /* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */ |
56 | 0 | va_list args_copy; |
57 | 0 | va_copy(args_copy, args); |
58 | |
|
59 | 0 | memcpy(stack_buffer, prefix, prefix_length * sizeof(char)); |
60 | 0 | assert((prefix_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char) <= CPUINFO_LOG_STACK_BUFFER_SIZE); |
61 | | |
62 | 0 | const int format_chars = vsnprintf( |
63 | 0 | &stack_buffer[prefix_length], |
64 | 0 | CPUINFO_LOG_STACK_BUFFER_SIZE - (prefix_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char), |
65 | 0 | format, |
66 | 0 | args); |
67 | 0 | if (format_chars < 0) { |
68 | | /* Format error in the message: silently ignore this particular message. */ |
69 | 0 | goto cleanup; |
70 | 0 | } |
71 | 0 | const size_t format_length = (size_t) format_chars; |
72 | 0 | if ((prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char) > CPUINFO_LOG_STACK_BUFFER_SIZE) { |
73 | | /* Allocate a buffer on heap, and vsnprintf to this buffer */ |
74 | 0 | const size_t heap_buffer_size = (prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char); |
75 | | #if _WIN32 |
76 | | heap_buffer = HeapAlloc(GetProcessHeap(), 0, heap_buffer_size); |
77 | | #else |
78 | 0 | heap_buffer = malloc(heap_buffer_size); |
79 | 0 | #endif |
80 | 0 | if (heap_buffer == NULL) { |
81 | 0 | goto cleanup; |
82 | 0 | } |
83 | | |
84 | | /* Copy pre-formatted prefix into the on-heap buffer */ |
85 | 0 | memcpy(heap_buffer, prefix, prefix_length * sizeof(char)); |
86 | 0 | vsnprintf(&heap_buffer[prefix_length], (format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char), format, args_copy); |
87 | 0 | out_buffer = heap_buffer; |
88 | 0 | } |
89 | | #ifdef _WIN32 |
90 | | out_buffer[prefix_length + format_length] = '\r'; |
91 | | out_buffer[prefix_length + format_length + 1] = '\n'; |
92 | | |
93 | | DWORD bytes_written; |
94 | | WriteFile( |
95 | | GetStdHandle((DWORD) output_handle), |
96 | | out_buffer, (prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char), |
97 | | &bytes_written, NULL); |
98 | | #elif defined(__hexagon__) |
99 | | qurt_printf("%s", out_buffer); |
100 | | #else |
101 | 0 | out_buffer[prefix_length + format_length] = '\n'; |
102 | |
|
103 | 0 | ssize_t bytes_written = write(output_handle, out_buffer, (prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char)); |
104 | 0 | (void) bytes_written; |
105 | 0 | #endif |
106 | |
|
107 | 0 | cleanup: |
108 | | #ifdef _WIN32 |
109 | | HeapFree(GetProcessHeap(), 0, heap_buffer); |
110 | | #else |
111 | 0 | free(heap_buffer); |
112 | 0 | #endif |
113 | 0 | va_end(args_copy); |
114 | 0 | } |
115 | | #elif defined(__ANDROID__) && CPUINFO_LOG_LEVEL > CPUINFO_LOG_NONE |
116 | | static const char cpuinfo_module[] = "XNNPACK"; |
117 | | #endif |
118 | | |
119 | | #if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_DEBUG |
120 | | void cpuinfo_vlog_debug(const char* format, va_list args) { |
121 | | #if CPUINFO_LOG_TO_STDIO |
122 | | static const char debug_prefix[17] = { |
123 | | 'D', 'e', 'b', 'u', 'g', ' ', '(', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ')', ':', ' ' |
124 | | }; |
125 | | cpuinfo_vlog(CPUINFO_LOG_STDOUT, debug_prefix, 17, format, args); |
126 | | #elif defined(__ANDROID__) |
127 | | __android_log_vprint(ANDROID_LOG_DEBUG, cpuinfo_module, format, args); |
128 | | #else |
129 | | #error "Platform-specific implementation required" |
130 | | #endif |
131 | | } |
132 | | #endif |
133 | | |
134 | | #if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_INFO |
135 | | void cpuinfo_vlog_info(const char* format, va_list args) { |
136 | | #if CPUINFO_LOG_TO_STDIO |
137 | | static const char info_prefix[16] = { |
138 | | 'N', 'o', 't', 'e', ' ', '(', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ')', ':', ' ' |
139 | | }; |
140 | | cpuinfo_vlog(CPUINFO_LOG_STDOUT, info_prefix, 16, format, args); |
141 | | #elif defined(__ANDROID__) |
142 | | __android_log_vprint(ANDROID_LOG_INFO, cpuinfo_module, format, args); |
143 | | #else |
144 | | #error "Platform-specific implementation required" |
145 | | #endif |
146 | | } |
147 | | #endif |
148 | | |
149 | | #if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_WARNING |
150 | | void cpuinfo_vlog_warning(const char* format, va_list args) { |
151 | | #if CPUINFO_LOG_TO_STDIO |
152 | | static const char warning_prefix[20] = { |
153 | | 'W', 'a', 'r', 'n', 'i', 'n', 'g', ' ', 'i', 'n', ' ', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ':', ' ' |
154 | | }; |
155 | | cpuinfo_vlog(CPUINFO_LOG_STDERR, warning_prefix, 20, format, args); |
156 | | #elif defined(__ANDROID__) |
157 | | __android_log_vprint(ANDROID_LOG_WARN, cpuinfo_module, format, args); |
158 | | #else |
159 | | #error "Platform-specific implementation required" |
160 | | #endif |
161 | | } |
162 | | #endif |
163 | | |
164 | | #if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_ERROR |
165 | 0 | void cpuinfo_vlog_error(const char* format, va_list args) { |
166 | 0 | #if CPUINFO_LOG_TO_STDIO |
167 | 0 | static const char error_prefix[18] = { |
168 | 0 | 'E', 'r', 'r', 'o', 'r', ' ', 'i', 'n', ' ', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ':', ' ' |
169 | 0 | }; |
170 | 0 | cpuinfo_vlog(CPUINFO_LOG_STDERR, error_prefix, 18, format, args); |
171 | | #elif defined(__ANDROID__) |
172 | | __android_log_vprint(ANDROID_LOG_ERROR, cpuinfo_module, format, args); |
173 | | #else |
174 | | #error "Platform-specific implementation required" |
175 | | #endif |
176 | 0 | } |
177 | | #endif |
178 | | |
179 | | #if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_FATAL |
180 | 0 | void cpuinfo_vlog_fatal(const char* format, va_list args) { |
181 | 0 | #if CPUINFO_LOG_TO_STDIO |
182 | 0 | static const char fatal_prefix[24] = { |
183 | 0 | 'F', 'a', 't', 'a', 'l', ' ', 'e', 'r', 'r', 'o', 'r', ' ', 'i', 'n', ' ', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ':', ' ' |
184 | 0 | }; |
185 | 0 | cpuinfo_vlog(CPUINFO_LOG_STDERR, fatal_prefix, 24, format, args); |
186 | | #elif defined(__ANDROID__) |
187 | | __android_log_vprint(ANDROID_LOG_FATAL, cpuinfo_module, format, args); |
188 | | #else |
189 | | #error "Platform-specific implementation required" |
190 | | #endif |
191 | 0 | } |
192 | | #endif |