mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 05:55:45 -04:00
dep: Add cpuinfo
This commit is contained in:
19
dep/cpuinfo/deps/clog/.gitignore
vendored
Normal file
19
dep/cpuinfo/deps/clog/.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Ninja files
|
||||
build.ninja
|
||||
|
||||
# Build objects and artifacts
|
||||
deps/
|
||||
build/
|
||||
bin/
|
||||
lib/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
42
dep/cpuinfo/deps/clog/CMakeLists.txt
Normal file
42
dep/cpuinfo/deps/clog/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
# ---[ Project and semantic versioning.
|
||||
PROJECT(clog C CXX)
|
||||
|
||||
# ---[ Options.
|
||||
SET(CLOG_RUNTIME_TYPE "default" CACHE STRING "Type of runtime library (shared, static, or default) to use")
|
||||
SET_PROPERTY(CACHE CLOG_RUNTIME_TYPE PROPERTY STRINGS default static shared)
|
||||
IF(ANDROID)
|
||||
OPTION(CLOG_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" OFF)
|
||||
ELSE()
|
||||
OPTION(CLOG_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" ON)
|
||||
ENDIF()
|
||||
|
||||
MACRO(CLOG_TARGET_RUNTIME_LIBRARY target)
|
||||
IF(MSVC AND NOT CLOG_RUNTIME_TYPE STREQUAL "default")
|
||||
IF(CLOG_RUNTIME_TYPE STREQUAL "shared")
|
||||
TARGET_COMPILE_OPTIONS(${target} PRIVATE
|
||||
"/MD$<$<CONFIG:Debug>:d>")
|
||||
ELSEIF(CLOG_RUNTIME_TYPE STREQUAL "static")
|
||||
TARGET_COMPILE_OPTIONS(${target} PRIVATE
|
||||
"/MT$<$<CONFIG:Debug>:d>")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
# ---[ clog library
|
||||
ADD_LIBRARY(clog STATIC src/clog.c)
|
||||
SET_TARGET_PROPERTIES(clog PROPERTIES
|
||||
C_STANDARD 99
|
||||
C_EXTENSIONS NO)
|
||||
CLOG_TARGET_RUNTIME_LIBRARY(clog)
|
||||
SET_TARGET_PROPERTIES(clog PROPERTIES PUBLIC_HEADER include/clog.h)
|
||||
TARGET_INCLUDE_DIRECTORIES(clog BEFORE PUBLIC include)
|
||||
IF(CLOG_LOG_TO_STDIO)
|
||||
TARGET_COMPILE_DEFINITIONS(clog PRIVATE CLOG_LOG_TO_STDIO=1)
|
||||
ELSE()
|
||||
TARGET_COMPILE_DEFINITIONS(clog PRIVATE CLOG_LOG_TO_STDIO=0)
|
||||
ENDIF()
|
||||
IF(ANDROID AND NOT CLOG_LOG_TO_STDIO)
|
||||
TARGET_LINK_LIBRARIES(clog PRIVATE log)
|
||||
ENDIF()
|
26
dep/cpuinfo/deps/clog/LICENSE
Normal file
26
dep/cpuinfo/deps/clog/LICENSE
Normal file
@ -0,0 +1,26 @@
|
||||
Copyright (C) 2018 Marat Dukhan
|
||||
Copyright (c) 2017-2018 Facebook Inc.
|
||||
Copyright (c) 2017 Georgia Institute of Technology
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
57
dep/cpuinfo/deps/clog/README.md
Normal file
57
dep/cpuinfo/deps/clog/README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# clog: C-style (a-la printf) logging library
|
||||
|
||||
[](https://github.com/pytorch/cpuinfo/blob/master/deps/clog/LICENSE)
|
||||
|
||||
C-style library for logging errors, warnings, information notes, and debug information.
|
||||
|
||||
## Features
|
||||
|
||||
- printf-style interface for formatting variadic parameters.
|
||||
- Separate functions for logging errors, warnings, information notes, and debug information.
|
||||
- Independent logging settings for different modules.
|
||||
- Logging to logcat on Android and stderr/stdout on other platforms.
|
||||
- Compatible with C99 and C++.
|
||||
- Covered with unit tests.
|
||||
|
||||
## Example
|
||||
|
||||
```c
|
||||
#include <clog.h>
|
||||
|
||||
#ifndef MYMODULE_LOG_LEVEL
|
||||
#define MYMODULE_LOG_LEVEL CLOG_DEBUG
|
||||
#endif
|
||||
|
||||
CLOG_DEFINE_LOG_DEBUG(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_INFO(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_WARNING(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_ERROR(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
|
||||
...
|
||||
|
||||
void some_function(...) {
|
||||
int status = ...
|
||||
if (status != 0) {
|
||||
mymodule_log_error(
|
||||
"something really bad happened: "
|
||||
"operation failed with status %d", status);
|
||||
}
|
||||
|
||||
uint32_t expected_zero = ...
|
||||
if (expected_zero != 0) {
|
||||
mymodule_log_warning(
|
||||
"something suspicious happened (var = %"PRIu32"), "
|
||||
"fall back to generic implementation", expected_zero);
|
||||
}
|
||||
|
||||
void* usually_non_null = ...
|
||||
if (usually_non_null == NULL) {
|
||||
mymodule_log_info(
|
||||
"something unusual, but common, happened: "
|
||||
"enabling work-around");
|
||||
}
|
||||
|
||||
float a = ...
|
||||
mymodule_log_debug("computed a = %.7f", a);
|
||||
}
|
||||
```
|
100
dep/cpuinfo/deps/clog/include/clog.h
Normal file
100
dep/cpuinfo/deps/clog/include/clog.h
Normal file
@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define CLOG_NONE 0
|
||||
#define CLOG_FATAL 1
|
||||
#define CLOG_ERROR 2
|
||||
#define CLOG_WARNING 3
|
||||
#define CLOG_INFO 4
|
||||
#define CLOG_DEBUG 5
|
||||
|
||||
#ifndef CLOG_VISIBILITY
|
||||
#if defined(__ELF__)
|
||||
#define CLOG_VISIBILITY __attribute__((__visibility__("internal")))
|
||||
#elif defined(__MACH__)
|
||||
#define CLOG_VISIBILITY __attribute__((__visibility__("hidden")))
|
||||
#else
|
||||
#define CLOG_VISIBILITY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CLOG_ARGUMENTS_FORMAT
|
||||
#if defined(__GNUC__)
|
||||
#define CLOG_ARGUMENTS_FORMAT __attribute__((__format__(__printf__, 1, 2)))
|
||||
#else
|
||||
#define CLOG_ARGUMENTS_FORMAT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CLOG_VISIBILITY void clog_vlog_debug(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_info(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_warning(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_error(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_fatal(const char* module, const char* format, va_list args);
|
||||
|
||||
#define CLOG_DEFINE_LOG_DEBUG(log_debug_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_debug_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_DEBUG) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_debug(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_INFO(log_info_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_info_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_INFO) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_info(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_WARNING(log_warning_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_warning_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_WARNING) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_warning(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_ERROR(log_error_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_error_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_ERROR) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_error(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_FATAL(log_fatal_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_fatal_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_FATAL) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_fatal(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
423
dep/cpuinfo/deps/clog/src/clog.c
Normal file
423
dep/cpuinfo/deps/clog/src/clog.c
Normal file
@ -0,0 +1,423 @@
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifndef CLOG_LOG_TO_STDIO
|
||||
#ifdef __ANDROID__
|
||||
#define CLOG_LOG_TO_STDIO 0
|
||||
#else
|
||||
#define CLOG_LOG_TO_STDIO 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <clog.h>
|
||||
|
||||
|
||||
/* Messages up to this size are formatted entirely on-stack, and don't allocate heap memory */
|
||||
#define CLOG_STACK_BUFFER_SIZE 1024
|
||||
|
||||
#define CLOG_FATAL_PREFIX "Fatal error: "
|
||||
#define CLOG_FATAL_PREFIX_LENGTH 13
|
||||
#define CLOG_FATAL_PREFIX_FORMAT "Fatal error in %s: "
|
||||
#define CLOG_ERROR_PREFIX "Error: "
|
||||
#define CLOG_ERROR_PREFIX_LENGTH 7
|
||||
#define CLOG_ERROR_PREFIX_FORMAT "Error in %s: "
|
||||
#define CLOG_WARNING_PREFIX "Warning: "
|
||||
#define CLOG_WARNING_PREFIX_LENGTH 9
|
||||
#define CLOG_WARNING_PREFIX_FORMAT "Warning in %s: "
|
||||
#define CLOG_INFO_PREFIX "Note: "
|
||||
#define CLOG_INFO_PREFIX_LENGTH 6
|
||||
#define CLOG_INFO_PREFIX_FORMAT "Note (%s): "
|
||||
#define CLOG_DEBUG_PREFIX "Debug: "
|
||||
#define CLOG_DEBUG_PREFIX_LENGTH 7
|
||||
#define CLOG_DEBUG_PREFIX_FORMAT "Debug (%s): "
|
||||
#define CLOG_SUFFIX_LENGTH 1
|
||||
|
||||
void clog_vlog_fatal(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_FATAL, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_FATAL_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_FATAL_PREFIX, CLOG_FATAL_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_FATAL_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_FATAL_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_ERROR_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_error(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_ERROR, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_ERROR_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_ERROR_PREFIX, CLOG_ERROR_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_ERROR_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_ERROR_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_ERROR_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_warning(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_WARN, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_WARNING_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_WARNING_PREFIX, CLOG_WARNING_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_WARNING_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_WARNING_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_ERROR_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_info(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_INFO, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_INFO_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_INFO_PREFIX, CLOG_INFO_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_INFO_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_INFO_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDOUT_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_debug(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_DEBUG, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_DEBUG_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_DEBUG_PREFIX, CLOG_DEBUG_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_DEBUG_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_DEBUG_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDOUT_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
Reference in New Issue
Block a user