4057 lines
143 KiB
Diff
4057 lines
143 KiB
Diff
From 4611bb6a513f43fee84946994d5b5fe05e341c16 Mon Sep 17 00:00:00 2001
|
|
From: tian2020 <tian_hang@hoperun.com>
|
|
Date: Wed, 14 Jun 2023 17:32:44 +0800
|
|
Subject: [PATCH 1/3] init and adapt to openeuler
|
|
|
|
---
|
|
frameworks/libhilog/BUILD.gn | 101 +-
|
|
frameworks/libhilog/base/hilog_base.cpp | 535 +++----
|
|
frameworks/libhilog/hilog.cpp | 121 +-
|
|
frameworks/libhilog/hilog_printf.cpp | 3 +-
|
|
frameworks/libhilog/include/hilog_cmd.h | 2 +-
|
|
frameworks/libhilog/utils/include/log_print.h | 94 +-
|
|
frameworks/libhilog/utils/include/log_utils.h | 220 +--
|
|
frameworks/libhilog/utils/log_print.cpp | 360 ++---
|
|
frameworks/libhilog/utils/log_utils.cpp | 1044 ++++++-------
|
|
.../libhilog/vsnprintf/include/output_p.inl | 1294 +++++++++++++++++
|
|
hilog.gni | 6 +-
|
|
interfaces/bundle.json | 5 +-
|
|
interfaces/native/innerkits/BUILD.gn | 41 +-
|
|
.../native/innerkits/include/hilog/log_c.h | 4 +-
|
|
.../native/innerkits/include/hilog/log_cpp.h | 17 +-
|
|
15 files changed, 2590 insertions(+), 1257 deletions(-)
|
|
create mode 100644 frameworks/libhilog/vsnprintf/include/output_p.inl
|
|
|
|
diff --git a/frameworks/libhilog/BUILD.gn b/frameworks/libhilog/BUILD.gn
|
|
index fe1a662..f8372a9 100644
|
|
--- a/frameworks/libhilog/BUILD.gn
|
|
+++ b/frameworks/libhilog/BUILD.gn
|
|
@@ -39,78 +39,33 @@ config("libhilog_config") {
|
|
]
|
|
}
|
|
|
|
-template("libhilog_source") {
|
|
- forward_variables_from(invoker, "*")
|
|
- ohos_source_set(target_name) {
|
|
- if (platform != "windows" && platform != "mac" && platform != "linux") {
|
|
- param_sources = [ "$param_root/properties.cpp" ]
|
|
- ioctl_sources = [ "$ioctl_root/log_ioctl.cpp" ]
|
|
-
|
|
- socket_sources = [
|
|
- "$socket_root/dgram_socket_client.cpp",
|
|
- "$socket_root/dgram_socket_server.cpp",
|
|
- "$socket_root/hilog_input_socket_client.cpp",
|
|
- "$socket_root/hilog_input_socket_server.cpp",
|
|
- "$socket_root/seq_packet_socket_client.cpp",
|
|
- "$socket_root/seq_packet_socket_server.cpp",
|
|
- "$socket_root/socket.cpp",
|
|
- "$socket_root/socket_client.cpp",
|
|
- "$socket_root/socket_server.cpp",
|
|
- ]
|
|
- }
|
|
-
|
|
- utils_sources = [
|
|
- "$utils_root/log_print.cpp",
|
|
- "$utils_root/log_utils.cpp",
|
|
- ]
|
|
-
|
|
- vsnprintf_sources = [ "$vsnprintf_root/vsnprintf_s_p.cpp" ]
|
|
-
|
|
- sources = [
|
|
- "hilog.cpp",
|
|
- "hilog_printf.cpp",
|
|
- ]
|
|
- if (platform != "windows" && platform != "mac" && platform != "linux") {
|
|
- sources += param_sources
|
|
- sources += ioctl_sources
|
|
- sources += socket_sources
|
|
- }
|
|
- sources += utils_sources
|
|
- sources += vsnprintf_sources
|
|
-
|
|
- defines = []
|
|
- if (platform == "windows") {
|
|
- cflags_cc = [ "-std=c++17" ]
|
|
- defines += [ "__WINDOWS__" ]
|
|
- } else if (platform == "mac") {
|
|
- defines += [ "__MAC__" ]
|
|
- } else if (platform == "linux") {
|
|
- cflags_cc = [ "-std=c++17" ]
|
|
- defines += [ "__LINUX__" ]
|
|
- } else {
|
|
- defines = [ "__RECV_MSG_WITH_UCRED_" ]
|
|
- if (use_musl) {
|
|
- defines += [ "HILOG_USE_MUSL" ]
|
|
- }
|
|
- }
|
|
- public_configs = [ ":libhilog_config" ]
|
|
- configs = [ ":libhilog_config" ]
|
|
-
|
|
- deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
|
|
-
|
|
- if (platform != "windows" && platform != "mac" && platform != "linux") {
|
|
- external_deps = [ "init:libbegetutil" ]
|
|
- }
|
|
-
|
|
- part_name = "hilog_native"
|
|
- subsystem_name = "hiviewdfx"
|
|
- }
|
|
-}
|
|
+ohos_source_set("libhilog_source") {
|
|
+
|
|
+ utils_sources = [
|
|
+ "$utils_root/log_print.cpp",
|
|
+ "$utils_root/log_utils.cpp",
|
|
+ ]
|
|
+
|
|
+ vsnprintf_sources = [ "$vsnprintf_root/vsnprintf_s_p.cpp" ]
|
|
+
|
|
+ sources = [
|
|
+ "hilog.cpp",
|
|
+ "hilog_printf.cpp",
|
|
+ ]
|
|
+ sources += utils_sources
|
|
+ sources += vsnprintf_sources
|
|
|
|
-foreach(item, platforms) {
|
|
- libhilog_source("libhilog_source_" + item) {
|
|
- platform = item
|
|
- }
|
|
+ defines = []
|
|
+ cflags_cc = [ "-std=c++17" ]
|
|
+ defines += [ "__LINUX__" ]
|
|
+
|
|
+ public_configs = [ ":libhilog_config" ]
|
|
+ configs = [ ":libhilog_config" ]
|
|
+
|
|
+ deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
|
|
+
|
|
+ part_name = "hilog_native"
|
|
+ subsystem_name = "hiviewdfx"
|
|
}
|
|
|
|
config("libhilog_base_config") {
|
|
@@ -124,10 +79,10 @@ ohos_source_set("libhilog_base_source") {
|
|
"//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
|
|
]
|
|
|
|
- vsnprintf_sources = [ "$vsnprintf_root/vsnprintf_s_p.cpp" ]
|
|
+ # vsnprintf_sources = [ "$vsnprintf_root/vsnprintf_s_p.cpp" ]
|
|
|
|
sources = [ "$libhilog_base_root/hilog_base.cpp" ]
|
|
- sources += vsnprintf_sources
|
|
+ # sources += vsnprintf_sources
|
|
|
|
defines = [
|
|
"__RECV_MSG_WITH_UCRED_",
|
|
diff --git a/frameworks/libhilog/base/hilog_base.cpp b/frameworks/libhilog/base/hilog_base.cpp
|
|
index 8e8e248..85337b8 100644
|
|
--- a/frameworks/libhilog/base/hilog_base.cpp
|
|
+++ b/frameworks/libhilog/base/hilog_base.cpp
|
|
@@ -16,279 +16,280 @@
|
|
#include "hilog_base/log_base.h"
|
|
|
|
#include <hilog_common.h>
|
|
-#include <vsnprintf_s_p.h>
|
|
-
|
|
-#include <array>
|
|
-#include <atomic>
|
|
-#include <cstring>
|
|
-#include <fstream>
|
|
-#include <iostream>
|
|
-#include <sys/socket.h>
|
|
-#include <sys/time.h>
|
|
-#include <sys/uio.h>
|
|
-#include <sys/un.h>
|
|
-#include <unistd.h>
|
|
-
|
|
-namespace {
|
|
-constexpr int SOCKET_TYPE = SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC;
|
|
-constexpr int INVALID_SOCKET = -1;
|
|
-constexpr size_t HILOG_VEC_MAX_SIZE = 4;
|
|
-constexpr size_t HILOG_VEC_SIZE_OHCORE = 4;
|
|
-constexpr size_t HILOG_VEC_SIZE_OH = 3;
|
|
-constexpr int32_t MAX_DOMAIN_TAGSIZE = 64;
|
|
-
|
|
-struct SocketHandler {
|
|
- std::atomic_int socketFd {INVALID_SOCKET};
|
|
- std::atomic_bool isConnected {false};
|
|
- ~SocketHandler()
|
|
- {
|
|
- int currentFd = socketFd.exchange(INVALID_SOCKET);
|
|
- if (currentFd >= 0) {
|
|
- close(currentFd);
|
|
- }
|
|
- }
|
|
-};
|
|
-
|
|
-typedef struct LogTime {
|
|
- uint32_t tvSec;
|
|
- uint32_t tvNsec;
|
|
-} __attribute__((__packed__)) LogTime;
|
|
-
|
|
-typedef struct __attribute__((__packed__)) {
|
|
- uint8_t id;
|
|
- uint16_t tid;
|
|
- uint16_t ohPid;
|
|
- LogTime realtime;
|
|
-} LogHeader;
|
|
-
|
|
-struct HiLogMsgInfo {
|
|
- HilogMsg *header_;
|
|
- const char *tag_;
|
|
- uint16_t tagLen_;
|
|
- const char *fmt_;
|
|
- uint16_t fmtLen_;
|
|
- HiLogMsgInfo(HilogMsg *header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen)
|
|
- {
|
|
- header_ = header;
|
|
- tag_ = tag;
|
|
- tagLen_ = tagLen;
|
|
- fmt_ = fmt;
|
|
- fmtLen_ = fmtLen;
|
|
- }
|
|
-};
|
|
-
|
|
-typedef enum {
|
|
- TYPE_OH = 0,
|
|
- TYPE_OHCORE = 1,
|
|
-} HiLogProtocolType;
|
|
-
|
|
-sockaddr_un g_sockAddr = {AF_UNIX, SOCKET_FILE_DIR INPUT_SOCKET_NAME};
|
|
-HiLogProtocolType g_protocolType = TYPE_OH;
|
|
-
|
|
-struct Initializer {
|
|
- Initializer()
|
|
- {
|
|
- constexpr char configFile[] = "/system/etc/hilog_config";
|
|
- if (access(configFile, F_OK) != 0) {
|
|
- return;
|
|
- }
|
|
- std::ifstream file;
|
|
- file.open(configFile);
|
|
- if (file.fail()) {
|
|
- std::cerr << "open hilog_config config file failed" << std::endl;
|
|
- return;
|
|
- }
|
|
-
|
|
- std::string sock;
|
|
- std::string protocol;
|
|
- file >> sock >> protocol;
|
|
- if (auto posColon = sock.find(":"); posColon != sock.npos) {
|
|
- std::string sockPath = sock.substr(posColon + 1);
|
|
- size_t pos = 0;
|
|
- while (pos < sockPath.size() && pos < (sizeof(g_sockAddr.sun_path) - 1)) {
|
|
- g_sockAddr.sun_path[pos] = sockPath[pos];
|
|
- pos++;
|
|
- }
|
|
- g_sockAddr.sun_path[pos] = '\0';
|
|
- }
|
|
- if (auto posColon = protocol.find(":"); posColon != protocol.npos) {
|
|
- g_protocolType = protocol.substr(posColon + 1) == "ohcore" ? TYPE_OHCORE : TYPE_OH;
|
|
- }
|
|
- file.close();
|
|
- }
|
|
-};
|
|
-Initializer g_initializer;
|
|
-
|
|
-static int GenerateFD()
|
|
-{
|
|
- int tmpFd = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCKET_TYPE, 0));
|
|
- int res = tmpFd;
|
|
- if (tmpFd == 0) {
|
|
- res = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCKET_TYPE, 0));
|
|
- close(tmpFd);
|
|
- }
|
|
- return res;
|
|
-}
|
|
-
|
|
-static int CheckSocket(SocketHandler& socketHandler)
|
|
-{
|
|
- int currentFd = socketHandler.socketFd.load();
|
|
- if (currentFd >= 0) {
|
|
- return currentFd;
|
|
- }
|
|
-
|
|
- int fd = GenerateFD();
|
|
- if (fd < 0) {
|
|
- std::cerr << "Can't get hilog socket! Errno: " << errno << std::endl;
|
|
- return fd;
|
|
- }
|
|
-
|
|
- currentFd = INVALID_SOCKET;
|
|
- if (!socketHandler.socketFd.compare_exchange_strong(currentFd, fd)) {
|
|
- close(fd);
|
|
- return currentFd;
|
|
- }
|
|
- return fd;
|
|
-}
|
|
-
|
|
-static int CheckConnection(SocketHandler& socketHandler)
|
|
-{
|
|
- bool isConnected = socketHandler.isConnected.load();
|
|
- if (isConnected) {
|
|
- return 0;
|
|
- }
|
|
-
|
|
- isConnected = socketHandler.isConnected.load();
|
|
- if (isConnected) {
|
|
- return 0;
|
|
- }
|
|
-
|
|
- auto result = TEMP_FAILURE_RETRY(connect(socketHandler.socketFd.load(),
|
|
- reinterpret_cast<const sockaddr*>(&g_sockAddr), sizeof(g_sockAddr)));
|
|
- if (result < 0) {
|
|
- std::cerr << "Can't connect to hilog server. Errno: " << errno << std::endl;
|
|
- return result;
|
|
- }
|
|
- socketHandler.isConnected.store(true);
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static size_t BuildHilogMessageForOhCore(struct HiLogMsgInfo* logMsgInfo, LogHeader& logHeader, uint16_t& logLevel,
|
|
- char tagBuf[], struct iovec *vec)
|
|
-{
|
|
- struct timespec ts = {0};
|
|
- (void)clock_gettime(CLOCK_REALTIME, &ts);
|
|
- logHeader.realtime.tvSec = static_cast<uint32_t>(ts.tv_sec);
|
|
- logHeader.realtime.tvNsec = static_cast<uint32_t>(ts.tv_nsec);
|
|
- logHeader.tid = static_cast<uint32_t>(gettid());
|
|
- logHeader.ohPid = static_cast<uint32_t>(getpid());
|
|
- logLevel = logMsgInfo->header_->level;
|
|
- constexpr uint32_t domainFilter = 0x000FFFFF;
|
|
- if (vsnprintfp_s(tagBuf, MAX_DOMAIN_TAGSIZE, MAX_DOMAIN_TAGSIZE - 1, false, "%05X/%s",
|
|
- (logMsgInfo->header_->domain & domainFilter), logMsgInfo->tag_) < 0) {
|
|
- return 0;
|
|
- }
|
|
-
|
|
- vec[0].iov_base = reinterpret_cast<unsigned char *>(&logHeader); // 0 : index of hos log header
|
|
- vec[0].iov_len = sizeof(logHeader); // 0 : index of hos log header
|
|
- vec[1].iov_base = reinterpret_cast<unsigned char *>(&logLevel); // 1 : index of log level
|
|
- vec[1].iov_len = 1; // 1 : index of log level
|
|
- vec[2].iov_base = reinterpret_cast<void *>(const_cast<char*>(tagBuf)); // 2 : index of log tag
|
|
- vec[2].iov_len = strlen(tagBuf) + 1; // 2 : index of log tag
|
|
- vec[3].iov_base = reinterpret_cast<void *>(const_cast<char*>(logMsgInfo->fmt_)); // 3 : index of log format
|
|
- vec[3].iov_len = logMsgInfo->fmtLen_; // 3 : index of log format
|
|
- return HILOG_VEC_SIZE_OHCORE;
|
|
-}
|
|
-
|
|
-static size_t BuildHilogMessageForOh(struct HiLogMsgInfo* logMsgInfo, struct iovec *vec)
|
|
-{
|
|
- struct timespec ts = {0};
|
|
- (void)clock_gettime(CLOCK_REALTIME, &ts);
|
|
- struct timespec tsMono = {0};
|
|
- (void)clock_gettime(CLOCK_MONOTONIC, &tsMono);
|
|
- logMsgInfo->header_->tv_sec = static_cast<uint32_t>(ts.tv_sec);
|
|
- logMsgInfo->header_->tv_nsec = static_cast<uint32_t>(ts.tv_nsec);
|
|
- logMsgInfo->header_->mono_sec = static_cast<uint32_t>(tsMono.tv_sec);
|
|
- logMsgInfo->header_->len = sizeof(HilogMsg) + logMsgInfo->tagLen_ + logMsgInfo->fmtLen_;
|
|
- logMsgInfo->header_->tag_len = logMsgInfo->tagLen_;
|
|
-
|
|
- vec[0].iov_base = logMsgInfo->header_; // 0 : index of hos log header
|
|
- vec[0].iov_len = sizeof(HilogMsg); // 0 : index of hos log header
|
|
- vec[1].iov_base = reinterpret_cast<void*>(const_cast<char *>(logMsgInfo->tag_)); // 1 : index of log tag
|
|
- vec[1].iov_len = logMsgInfo->tagLen_; // 1 : index of log tag
|
|
- vec[2].iov_base = reinterpret_cast<void*>(const_cast<char *>(logMsgInfo->fmt_)); // 2 : index of log content
|
|
- vec[2].iov_len = logMsgInfo->fmtLen_; // 2 : index of log content
|
|
- return HILOG_VEC_SIZE_OH;
|
|
-}
|
|
-
|
|
-static int SendMessage(HilogMsg *header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen)
|
|
-{
|
|
- SocketHandler socketHandler;
|
|
- int ret = CheckSocket(socketHandler);
|
|
- if (ret < 0) {
|
|
- return ret;
|
|
- }
|
|
- ret = CheckConnection(socketHandler);
|
|
- if (ret < 0) {
|
|
- return ret;
|
|
- }
|
|
-
|
|
- struct iovec vec[HILOG_VEC_MAX_SIZE];
|
|
- struct HiLogMsgInfo msgInfo(header, tag, tagLen, fmt, fmtLen);
|
|
- LogHeader logHeader;
|
|
- uint16_t logLevel = 0;
|
|
- char tagBuf[MAX_DOMAIN_TAGSIZE] = {0};
|
|
- auto vecSize = (g_protocolType == TYPE_OHCORE) ?
|
|
- BuildHilogMessageForOhCore(&msgInfo, logHeader, logLevel, tagBuf, vec) :
|
|
- BuildHilogMessageForOh(&msgInfo, vec);
|
|
- if (vecSize == 0) {
|
|
- std::cerr << "BuildHilogMessage failed ret = " << vecSize << std::endl;
|
|
- return RET_FAIL;
|
|
- }
|
|
- return TEMP_FAILURE_RETRY(::writev(socketHandler.socketFd.load(), vec, vecSize));
|
|
-}
|
|
-
|
|
-static int HiLogBasePrintArgs(const LogType type, const LogLevel level, const unsigned int domain, const char *tag,
|
|
- const char *fmt, va_list ap)
|
|
-{
|
|
- if (!HiLogBaseIsLoggable(domain, tag, level)) {
|
|
- return -1;
|
|
- }
|
|
-
|
|
- char buf[MAX_LOG_LEN] = {0};
|
|
-
|
|
- vsnprintfp_s(buf, MAX_LOG_LEN, MAX_LOG_LEN - 1, true, fmt, ap);
|
|
-
|
|
- auto tagLen = strnlen(tag, MAX_TAG_LEN - 1);
|
|
- auto logLen = strnlen(buf, MAX_LOG_LEN - 1);
|
|
- HilogMsg header = {0};
|
|
- header.type = type;
|
|
- header.level = level;
|
|
-#ifndef __RECV_MSG_WITH_UCRED_
|
|
- header.pid = getpid();
|
|
-#endif
|
|
- header.tid = static_cast<uint32_t>(gettid());
|
|
- header.domain = domain;
|
|
-
|
|
- return SendMessage(&header, tag, tagLen + 1, buf, logLen + 1);
|
|
-}
|
|
-
|
|
-} // namespace
|
|
+// #include <vsnprintf_s_p.h>
|
|
+
|
|
+// #include <array>
|
|
+// #include <atomic>
|
|
+// #include <cstring>
|
|
+// #include <fstream>
|
|
+// #include <iostream>
|
|
+// #include <sys/socket.h>
|
|
+// #include <sys/time.h>
|
|
+// #include <sys/uio.h>
|
|
+// #include <sys/un.h>
|
|
+// #include <unistd.h>
|
|
+
|
|
+// namespace {
|
|
+// constexpr int SOCKET_TYPE = SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC;
|
|
+// constexpr int INVALID_SOCKET = -1;
|
|
+// constexpr size_t HILOG_VEC_MAX_SIZE = 4;
|
|
+// constexpr size_t HILOG_VEC_SIZE_OHCORE = 4;
|
|
+// constexpr size_t HILOG_VEC_SIZE_OH = 3;
|
|
+// constexpr int32_t MAX_DOMAIN_TAGSIZE = 64;
|
|
+
|
|
+// struct SocketHandler {
|
|
+// std::atomic_int socketFd {INVALID_SOCKET};
|
|
+// std::atomic_bool isConnected {false};
|
|
+// ~SocketHandler()
|
|
+// {
|
|
+// int currentFd = socketFd.exchange(INVALID_SOCKET);
|
|
+// if (currentFd >= 0) {
|
|
+// close(currentFd);
|
|
+// }
|
|
+// }
|
|
+// };
|
|
+
|
|
+// typedef struct LogTime {
|
|
+// uint32_t tvSec;
|
|
+// uint32_t tvNsec;
|
|
+// } __attribute__((__packed__)) LogTime;
|
|
+
|
|
+// typedef struct __attribute__((__packed__)) {
|
|
+// uint8_t id;
|
|
+// uint16_t tid;
|
|
+// uint16_t ohPid;
|
|
+// LogTime realtime;
|
|
+// } LogHeader;
|
|
+
|
|
+// struct HiLogMsgInfo {
|
|
+// HilogMsg *header_;
|
|
+// const char *tag_;
|
|
+// uint16_t tagLen_;
|
|
+// const char *fmt_;
|
|
+// uint16_t fmtLen_;
|
|
+// HiLogMsgInfo(HilogMsg *header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen)
|
|
+// {
|
|
+// header_ = header;
|
|
+// tag_ = tag;
|
|
+// tagLen_ = tagLen;
|
|
+// fmt_ = fmt;
|
|
+// fmtLen_ = fmtLen;
|
|
+// }
|
|
+// };
|
|
+
|
|
+// typedef enum {
|
|
+// TYPE_OH = 0,
|
|
+// TYPE_OHCORE = 1,
|
|
+// } HiLogProtocolType;
|
|
+
|
|
+// sockaddr_un g_sockAddr = {AF_UNIX, SOCKET_FILE_DIR INPUT_SOCKET_NAME};
|
|
+// HiLogProtocolType g_protocolType = TYPE_OH;
|
|
+
|
|
+// struct Initializer {
|
|
+// Initializer()
|
|
+// {
|
|
+// constexpr char configFile[] = "/system/etc/hilog_config";
|
|
+// if (access(configFile, F_OK) != 0) {
|
|
+// return;
|
|
+// }
|
|
+// std::ifstream file;
|
|
+// file.open(configFile);
|
|
+// if (file.fail()) {
|
|
+// std::cerr << "open hilog_config config file failed" << std::endl;
|
|
+// return;
|
|
+// }
|
|
+
|
|
+// std::string sock;
|
|
+// std::string protocol;
|
|
+// file >> sock >> protocol;
|
|
+// if (auto posColon = sock.find(":"); posColon != sock.npos) {
|
|
+// std::string sockPath = sock.substr(posColon + 1);
|
|
+// size_t pos = 0;
|
|
+// while (pos < sockPath.size() && pos < (sizeof(g_sockAddr.sun_path) - 1)) {
|
|
+// g_sockAddr.sun_path[pos] = sockPath[pos];
|
|
+// pos++;
|
|
+// }
|
|
+// g_sockAddr.sun_path[pos] = '\0';
|
|
+// }
|
|
+// if (auto posColon = protocol.find(":"); posColon != protocol.npos) {
|
|
+// g_protocolType = protocol.substr(posColon + 1) == "ohcore" ? TYPE_OHCORE : TYPE_OH;
|
|
+// }
|
|
+// file.close();
|
|
+// }
|
|
+// };
|
|
+// Initializer g_initializer;
|
|
+
|
|
+// static int GenerateFD()
|
|
+// {
|
|
+// int tmpFd = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCKET_TYPE, 0));
|
|
+// int res = tmpFd;
|
|
+// if (tmpFd == 0) {
|
|
+// res = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCKET_TYPE, 0));
|
|
+// close(tmpFd);
|
|
+// }
|
|
+// return res;
|
|
+// }
|
|
+
|
|
+// static int CheckSocket(SocketHandler& socketHandler)
|
|
+// {
|
|
+// int currentFd = socketHandler.socketFd.load();
|
|
+// if (currentFd >= 0) {
|
|
+// return currentFd;
|
|
+// }
|
|
+
|
|
+// int fd = GenerateFD();
|
|
+// if (fd < 0) {
|
|
+// std::cerr << "Can't get hilog socket! Errno: " << errno << std::endl;
|
|
+// return fd;
|
|
+// }
|
|
+
|
|
+// currentFd = INVALID_SOCKET;
|
|
+// if (!socketHandler.socketFd.compare_exchange_strong(currentFd, fd)) {
|
|
+// close(fd);
|
|
+// return currentFd;
|
|
+// }
|
|
+// return fd;
|
|
+// }
|
|
+
|
|
+// static int CheckConnection(SocketHandler& socketHandler)
|
|
+// {
|
|
+// bool isConnected = socketHandler.isConnected.load();
|
|
+// if (isConnected) {
|
|
+// return 0;
|
|
+// }
|
|
+
|
|
+// isConnected = socketHandler.isConnected.load();
|
|
+// if (isConnected) {
|
|
+// return 0;
|
|
+// }
|
|
+
|
|
+// auto result = TEMP_FAILURE_RETRY(connect(socketHandler.socketFd.load(),
|
|
+// reinterpret_cast<const sockaddr*>(&g_sockAddr), sizeof(g_sockAddr)));
|
|
+// if (result < 0) {
|
|
+// std::cerr << "Can't connect to hilog server. Errno: " << errno << std::endl;
|
|
+// return result;
|
|
+// }
|
|
+// socketHandler.isConnected.store(true);
|
|
+// return 0;
|
|
+// }
|
|
+
|
|
+// static size_t BuildHilogMessageForOhCore(struct HiLogMsgInfo* logMsgInfo, LogHeader& logHeader, uint16_t& logLevel,
|
|
+// char tagBuf[], struct iovec *vec)
|
|
+// {
|
|
+// struct timespec ts = {0};
|
|
+// (void)clock_gettime(CLOCK_REALTIME, &ts);
|
|
+// logHeader.realtime.tvSec = static_cast<uint32_t>(ts.tv_sec);
|
|
+// logHeader.realtime.tvNsec = static_cast<uint32_t>(ts.tv_nsec);
|
|
+// logHeader.tid = static_cast<uint32_t>(gettid());
|
|
+// logHeader.ohPid = static_cast<uint32_t>(getpid());
|
|
+// logLevel = logMsgInfo->header_->level;
|
|
+// constexpr uint32_t domainFilter = 0x000FFFFF;
|
|
+// if (vsnprintfp_s(tagBuf, MAX_DOMAIN_TAGSIZE, MAX_DOMAIN_TAGSIZE - 1, false, "%05X/%s",
|
|
+// (logMsgInfo->header_->domain & domainFilter), logMsgInfo->tag_) < 0) {
|
|
+// return 0;
|
|
+// }
|
|
+
|
|
+// vec[0].iov_base = reinterpret_cast<unsigned char *>(&logHeader); // 0 : index of hos log header
|
|
+// vec[0].iov_len = sizeof(logHeader); // 0 : index of hos log header
|
|
+// vec[1].iov_base = reinterpret_cast<unsigned char *>(&logLevel); // 1 : index of log level
|
|
+// vec[1].iov_len = 1; // 1 : index of log level
|
|
+// vec[2].iov_base = reinterpret_cast<void *>(const_cast<char*>(tagBuf)); // 2 : index of log tag
|
|
+// vec[2].iov_len = strlen(tagBuf) + 1; // 2 : index of log tag
|
|
+// vec[3].iov_base = reinterpret_cast<void *>(const_cast<char*>(logMsgInfo->fmt_)); // 3 : index of log format
|
|
+// vec[3].iov_len = logMsgInfo->fmtLen_; // 3 : index of log format
|
|
+// return HILOG_VEC_SIZE_OHCORE;
|
|
+// }
|
|
+
|
|
+// static size_t BuildHilogMessageForOh(struct HiLogMsgInfo* logMsgInfo, struct iovec *vec)
|
|
+// {
|
|
+// struct timespec ts = {0};
|
|
+// (void)clock_gettime(CLOCK_REALTIME, &ts);
|
|
+// struct timespec tsMono = {0};
|
|
+// (void)clock_gettime(CLOCK_MONOTONIC, &tsMono);
|
|
+// logMsgInfo->header_->tv_sec = static_cast<uint32_t>(ts.tv_sec);
|
|
+// logMsgInfo->header_->tv_nsec = static_cast<uint32_t>(ts.tv_nsec);
|
|
+// logMsgInfo->header_->mono_sec = static_cast<uint32_t>(tsMono.tv_sec);
|
|
+// logMsgInfo->header_->len = sizeof(HilogMsg) + logMsgInfo->tagLen_ + logMsgInfo->fmtLen_;
|
|
+// logMsgInfo->header_->tag_len = logMsgInfo->tagLen_;
|
|
+
|
|
+// vec[0].iov_base = logMsgInfo->header_; // 0 : index of hos log header
|
|
+// vec[0].iov_len = sizeof(HilogMsg); // 0 : index of hos log header
|
|
+// vec[1].iov_base = reinterpret_cast<void*>(const_cast<char *>(logMsgInfo->tag_)); // 1 : index of log tag
|
|
+// vec[1].iov_len = logMsgInfo->tagLen_; // 1 : index of log tag
|
|
+// vec[2].iov_base = reinterpret_cast<void*>(const_cast<char *>(logMsgInfo->fmt_)); // 2 : index of log content
|
|
+// vec[2].iov_len = logMsgInfo->fmtLen_; // 2 : index of log content
|
|
+// return HILOG_VEC_SIZE_OH;
|
|
+// }
|
|
+
|
|
+// static int SendMessage(HilogMsg *header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen)
|
|
+// {
|
|
+// SocketHandler socketHandler;
|
|
+// int ret = CheckSocket(socketHandler);
|
|
+// if (ret < 0) {
|
|
+// return ret;
|
|
+// }
|
|
+// ret = CheckConnection(socketHandler);
|
|
+// if (ret < 0) {
|
|
+// return ret;
|
|
+// }
|
|
+
|
|
+// struct iovec vec[HILOG_VEC_MAX_SIZE];
|
|
+// struct HiLogMsgInfo msgInfo(header, tag, tagLen, fmt, fmtLen);
|
|
+// LogHeader logHeader;
|
|
+// uint16_t logLevel = 0;
|
|
+// char tagBuf[MAX_DOMAIN_TAGSIZE] = {0};
|
|
+// auto vecSize = (g_protocolType == TYPE_OHCORE) ?
|
|
+// BuildHilogMessageForOhCore(&msgInfo, logHeader, logLevel, tagBuf, vec) :
|
|
+// BuildHilogMessageForOh(&msgInfo, vec);
|
|
+// if (vecSize == 0) {
|
|
+// std::cerr << "BuildHilogMessage failed ret = " << vecSize << std::endl;
|
|
+// return RET_FAIL;
|
|
+// }
|
|
+// return TEMP_FAILURE_RETRY(::writev(socketHandler.socketFd.load(), vec, vecSize));
|
|
+// }
|
|
+
|
|
+// static int HiLogBasePrintArgs(const LogType type, const LogLevel level, const unsigned int domain, const char *tag,
|
|
+// const char *fmt, va_list ap)
|
|
+// {
|
|
+// if (!HiLogBaseIsLoggable(domain, tag, level)) {
|
|
+// return -1;
|
|
+// }
|
|
+
|
|
+// char buf[MAX_LOG_LEN] = {0};
|
|
+
|
|
+// vsnprintfp_s(buf, MAX_LOG_LEN, MAX_LOG_LEN - 1, true, fmt, ap);
|
|
+
|
|
+// auto tagLen = strnlen(tag, MAX_TAG_LEN - 1);
|
|
+// auto logLen = strnlen(buf, MAX_LOG_LEN - 1);
|
|
+// HilogMsg header = {0};
|
|
+// header.type = type;
|
|
+// header.level = level;
|
|
+// #ifndef __RECV_MSG_WITH_UCRED_
|
|
+// header.pid = getpid();
|
|
+// #endif
|
|
+// header.tid = static_cast<uint32_t>(gettid());
|
|
+// header.domain = domain;
|
|
+
|
|
+// return SendMessage(&header, tag, tagLen + 1, buf, logLen + 1);
|
|
+// }
|
|
+
|
|
+// } // namespace
|
|
|
|
int HiLogBasePrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)
|
|
{
|
|
- int ret;
|
|
- va_list ap;
|
|
- va_start(ap, fmt);
|
|
- ret = HiLogBasePrintArgs(type, level, domain, tag, fmt, ap);
|
|
- va_end(ap);
|
|
- return ret;
|
|
+ // int ret;
|
|
+ // va_list ap;
|
|
+ // va_start(ap, fmt);
|
|
+ // ret = HiLogBasePrintArgs(type, level, domain, tag, fmt, ap);
|
|
+ // va_end(ap);
|
|
+ // return ret;
|
|
+ return 0;
|
|
}
|
|
|
|
bool HiLogBaseIsLoggable(unsigned int domain, const char *tag, LogLevel level)
|
|
{
|
|
- if ((level <= LOG_LEVEL_MIN) || (level >= LOG_LEVEL_MAX) || tag == nullptr) {
|
|
- return false;
|
|
- }
|
|
+ // if ((level <= LOG_LEVEL_MIN) || (level >= LOG_LEVEL_MAX) || tag == nullptr) {
|
|
+ // return false;
|
|
+ // }
|
|
return true;
|
|
}
|
|
diff --git a/frameworks/libhilog/hilog.cpp b/frameworks/libhilog/hilog.cpp
|
|
index 80980cb..e58c6d6 100644
|
|
--- a/frameworks/libhilog/hilog.cpp
|
|
+++ b/frameworks/libhilog/hilog.cpp
|
|
@@ -1,23 +1,26 @@
|
|
-/*
|
|
- * Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
- * Licensed under the Apache License, Version 2.0 (the "License");
|
|
- * you may not use this file except in compliance with the License.
|
|
- * You may obtain a copy of the License at
|
|
- *
|
|
- * http://www.apache.org/licenses/LICENSE-2.0
|
|
- *
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
- * See the License for the specific language governing permissions and
|
|
- * limitations under the License.
|
|
- */
|
|
-
|
|
#include "hilog/log.h"
|
|
-#include "hilog_inner.h"
|
|
|
|
+#include <cerrno>
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
+#include <ctime>
|
|
+#include <fstream>
|
|
+#include <iostream>
|
|
+#include <mutex>
|
|
+#include <securec.h>
|
|
+#include <atomic>
|
|
+#include <sys/syscall.h>
|
|
+#include <unistd.h>
|
|
+#include <functional>
|
|
+
|
|
+#include "log_utils.h"
|
|
+#include "hilog_common.h"
|
|
+#include "log_timestamp.h"
|
|
+#include "vsnprintf_s_p.h"
|
|
+#include "log_print.h"
|
|
+
|
|
+using namespace std;
|
|
+using namespace OHOS::HiviewDFX;
|
|
|
|
namespace OHOS {
|
|
namespace HiviewDFX {
|
|
@@ -29,6 +32,82 @@ namespace HiviewDFX {
|
|
va_end(args); \
|
|
} while (0)
|
|
|
|
+int HiPrintLog(HilogMsg& header, const char *tag, uint16_t tagLen, const char *fmt, uint16_t fmtLen)
|
|
+{
|
|
+ LogContent content = {
|
|
+ .level = header.level,
|
|
+ .type = header.type,
|
|
+ .pid = header.pid,
|
|
+ .tid = header.tid,
|
|
+ .domain = header.domain,
|
|
+ .tv_sec = header.tv_sec,
|
|
+ .tv_nsec = header.tv_nsec,
|
|
+ .mono_sec = header.mono_sec,
|
|
+ .tag = tag,
|
|
+ .log = fmt,
|
|
+ };
|
|
+ LogFormat format = {
|
|
+ .colorful = false,
|
|
+ .timeFormat = FormatTime::TIME,
|
|
+ .timeAccuFormat = FormatTimeAccu::MSEC,
|
|
+ .year = false,
|
|
+ .zone = false,
|
|
+ };
|
|
+ LogPrintWithFormat(content, format);
|
|
+ return RET_SUCCESS;
|
|
+}
|
|
+
|
|
+int HiLogPrintArgs(const LogType type, const LogLevel level, const unsigned int domain, const char *tag,
|
|
+ const char *fmt, va_list ap)
|
|
+{
|
|
+ if ((tag == nullptr)) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ HilogMsg header = {0};
|
|
+ struct timespec ts = {0};
|
|
+ (void)clock_gettime(CLOCK_REALTIME, &ts);
|
|
+ struct timespec ts_mono = {0};
|
|
+ (void)clock_gettime(CLOCK_MONOTONIC, &ts_mono);
|
|
+ header.tv_sec = static_cast<uint32_t>(ts.tv_sec);
|
|
+ header.tv_nsec = static_cast<uint32_t>(ts.tv_nsec);
|
|
+ header.mono_sec = static_cast<uint32_t>(ts_mono.tv_sec);
|
|
+
|
|
+ char buf[MAX_LOG_LEN] = {0};
|
|
+ char *logBuf = buf;
|
|
+ int traceBufLen = 0;
|
|
+ int ret;
|
|
+ bool priv = true;
|
|
+
|
|
+#ifdef __clang__
|
|
+/* code specific to clang compiler */
|
|
+#pragma clang diagnostic push
|
|
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
|
|
+#elif __GNUC__
|
|
+/* code for GNU C compiler */
|
|
+#pragma GCC diagnostic push
|
|
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
|
+#endif
|
|
+ ret = vsnprintfp_s(logBuf, MAX_LOG_LEN - traceBufLen, MAX_LOG_LEN - traceBufLen - 1, priv, fmt, ap);
|
|
+#ifdef __clang__
|
|
+#pragma clang diagnostic pop
|
|
+#elif __GNUC__
|
|
+#pragma GCC diagnostic pop
|
|
+#endif
|
|
+
|
|
+ /* fill header info */
|
|
+ auto tagLen = strnlen(tag, MAX_TAG_LEN - 1);
|
|
+ auto logLen = strnlen(buf, MAX_LOG_LEN - 1);
|
|
+ header.type = type;
|
|
+ header.level = level;
|
|
+ header.pid = getpid();
|
|
+ header.tid = static_cast<uint32_t>(syscall(SYS_gettid));
|
|
+ header.domain = domain;
|
|
+
|
|
+ return HiPrintLog(header, tag, tagLen + 1, buf, logLen + 1);
|
|
+
|
|
+}
|
|
+
|
|
int HiLog::Debug(const HiLogLabel &label, const char *fmt, ...)
|
|
{
|
|
int ret;
|
|
@@ -65,3 +144,13 @@ int HiLog::Fatal(const HiLogLabel &label, const char *fmt, ...)
|
|
}
|
|
} // namespace HiviewDFX
|
|
} // namespace OHOS
|
|
+
|
|
+int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)
|
|
+{
|
|
+ int ret;
|
|
+ va_list ap;
|
|
+ va_start(ap, fmt);
|
|
+ ret = HiLogPrintArgs(type, level, domain, tag, fmt, ap);
|
|
+ va_end(ap);
|
|
+ return ret;
|
|
+}
|
|
diff --git a/frameworks/libhilog/hilog_printf.cpp b/frameworks/libhilog/hilog_printf.cpp
|
|
index 9db1742..1316128 100644
|
|
--- a/frameworks/libhilog/hilog_printf.cpp
|
|
+++ b/frameworks/libhilog/hilog_printf.cpp
|
|
@@ -55,8 +55,7 @@ static atomic_int g_hiLogGetIdCallCount = 0;
|
|
// protected by static lock guard
|
|
static char g_hiLogLastFatalMessage[MAX_LOG_LEN] = { 0 }; // MAX_lOG_LEN : 1024
|
|
|
|
-HILOG_PUBLIC_API
|
|
-extern "C" const char* GetLastFatalMessage()
|
|
+extern "C" HILOG_PUBLIC_API const char* GetLastFatalMessage()
|
|
{
|
|
return g_hiLogLastFatalMessage;
|
|
}
|
|
diff --git a/frameworks/libhilog/include/hilog_cmd.h b/frameworks/libhilog/include/hilog_cmd.h
|
|
index 1043e1b..677da27 100644
|
|
--- a/frameworks/libhilog/include/hilog_cmd.h
|
|
+++ b/frameworks/libhilog/include/hilog_cmd.h
|
|
@@ -258,4 +258,4 @@ struct KmsgEnableRqst {
|
|
struct KmsgEnableRsp {
|
|
char placeholder;
|
|
} __attribute__((__packed__));
|
|
-#endif /* HILOG_CMD_H */
|
|
\ No newline at end of file
|
|
+#endif /* HILOG_CMD_H */
|
|
diff --git a/frameworks/libhilog/utils/include/log_print.h b/frameworks/libhilog/utils/include/log_print.h
|
|
index a84cdc5..e90626a 100644
|
|
--- a/frameworks/libhilog/utils/include/log_print.h
|
|
+++ b/frameworks/libhilog/utils/include/log_print.h
|
|
@@ -1,47 +1,47 @@
|
|
-/*
|
|
- * Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
- * Licensed under the Apache License, Version 2.0 (the "License");
|
|
- * you may not use this file except in compliance with the License.
|
|
- * You may obtain a copy of the License at
|
|
- *
|
|
- * http://www.apache.org/licenses/LICENSE-2.0
|
|
- *
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
- * See the License for the specific language governing permissions and
|
|
- * limitations under the License.
|
|
- */
|
|
-#ifndef LOG_PRINT_H
|
|
-#define LOG_PRINT_H
|
|
-#include <iostream>
|
|
-
|
|
-#include "hilog_cmd.h"
|
|
-
|
|
-namespace OHOS {
|
|
-namespace HiviewDFX {
|
|
-struct LogContent {
|
|
- uint8_t level;
|
|
- uint8_t type;
|
|
- uint32_t pid;
|
|
- uint32_t tid;
|
|
- uint32_t domain;
|
|
- uint32_t tv_sec;
|
|
- uint32_t tv_nsec;
|
|
- uint32_t mono_sec;
|
|
- const char *tag;
|
|
- const char *log;
|
|
-};
|
|
-
|
|
-struct LogFormat {
|
|
- bool colorful;
|
|
- FormatTime timeFormat;
|
|
- FormatTimeAccu timeAccuFormat;
|
|
- bool year;
|
|
- bool zone;
|
|
-};
|
|
-
|
|
-void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std::ostream& out = std::cout);
|
|
-} // namespace HiviewDFX
|
|
-} // namespace OHOS
|
|
-#endif /* LOG_PRINT_H */
|
|
\ No newline at end of file
|
|
+/*
|
|
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+#ifndef LOG_PRINT_H
|
|
+#define LOG_PRINT_H
|
|
+#include <iostream>
|
|
+
|
|
+#include "hilog_cmd.h"
|
|
+
|
|
+namespace OHOS {
|
|
+namespace HiviewDFX {
|
|
+struct LogContent {
|
|
+ uint8_t level;
|
|
+ uint8_t type;
|
|
+ uint32_t pid;
|
|
+ uint32_t tid;
|
|
+ uint32_t domain;
|
|
+ uint32_t tv_sec;
|
|
+ uint32_t tv_nsec;
|
|
+ uint32_t mono_sec;
|
|
+ const char *tag;
|
|
+ const char *log;
|
|
+};
|
|
+
|
|
+struct LogFormat {
|
|
+ bool colorful;
|
|
+ FormatTime timeFormat;
|
|
+ FormatTimeAccu timeAccuFormat;
|
|
+ bool year;
|
|
+ bool zone;
|
|
+};
|
|
+
|
|
+void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std::ostream& out = std::cout);
|
|
+} // namespace HiviewDFX
|
|
+} // namespace OHOS
|
|
+#endif /* LOG_PRINT_H */
|
|
diff --git a/frameworks/libhilog/utils/include/log_utils.h b/frameworks/libhilog/utils/include/log_utils.h
|
|
index 464fe84..6a79155 100644
|
|
--- a/frameworks/libhilog/utils/include/log_utils.h
|
|
+++ b/frameworks/libhilog/utils/include/log_utils.h
|
|
@@ -1,110 +1,110 @@
|
|
-/*
|
|
- * Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
- * Licensed under the Apache License, Version 2.0 (the "License");
|
|
- * you may not use this file except in compliance with the License.
|
|
- * You may obtain a copy of the License at
|
|
- *
|
|
- * http://www.apache.org/licenses/LICENSE-2.0
|
|
- *
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
- * See the License for the specific language governing permissions and
|
|
- * limitations under the License.
|
|
- */
|
|
-#ifndef LOG_UTILS_H
|
|
-#define LOG_UTILS_H
|
|
-
|
|
-#include <string>
|
|
-#include <vector>
|
|
-#include <unordered_map>
|
|
-
|
|
-namespace OHOS {
|
|
-namespace HiviewDFX {
|
|
-template<typename K, typename V>
|
|
-class KVMap {
|
|
-using ValueCmp = std::function<bool(const V& v1, const V& v2)>;
|
|
-public:
|
|
- KVMap(std::unordered_map<K, V> map, K def_k, V def_v,
|
|
- ValueCmp cmp = [](const V& v1, const V& v2) { return v1 == v2; })
|
|
- : str_map(map), def_key(def_k), def_value(def_v), compare(cmp)
|
|
- {
|
|
- }
|
|
-
|
|
- const V& GetValue(K key) const
|
|
- {
|
|
- auto it = str_map.find(key);
|
|
- return it == str_map.end() ? def_value : it->second;
|
|
- }
|
|
-
|
|
- const K GetKey(const V& value) const
|
|
- {
|
|
- for (auto& it : str_map) {
|
|
- if (compare(value, it.second)) {
|
|
- return it.first;
|
|
- }
|
|
- }
|
|
- return def_key;
|
|
- }
|
|
-
|
|
- std::vector<K> GetAllKeys() const
|
|
- {
|
|
- std::vector<K> keys;
|
|
- for (auto& it : str_map) {
|
|
- keys.push_back(it.first);
|
|
- }
|
|
- return keys;
|
|
- }
|
|
-
|
|
- bool IsValidKey(K key) const
|
|
- {
|
|
- return (str_map.find(key) != str_map.end());
|
|
- }
|
|
-
|
|
-private:
|
|
- const std::unordered_map<K, V> str_map;
|
|
- const K def_key;
|
|
- const V def_value;
|
|
- const ValueCmp compare;
|
|
-};
|
|
-using StringMap = KVMap<uint16_t, std::string>;
|
|
-std::string ErrorCode2Str(int16_t errorCode);
|
|
-std::string LogType2Str(uint16_t logType);
|
|
-uint16_t Str2LogType(const std::string& str);
|
|
-std::string ComboLogType2Str(uint16_t shiftType);
|
|
-uint16_t Str2ComboLogType(const std::string& str);
|
|
-std::vector<uint16_t> GetAllLogTypes();
|
|
-std::string LogLevel2Str(uint16_t logLevel);
|
|
-uint16_t Str2LogLevel(const std::string& str);
|
|
-std::string LogLevel2ShortStr(uint16_t logLevel);
|
|
-uint16_t ShortStr2LogLevel(const std::string& str);
|
|
-uint16_t PrettyStr2LogLevel(const std::string& str);
|
|
-std::string ComboLogLevel2Str(uint16_t shiftLevel);
|
|
-uint16_t Str2ComboLogLevel(const std::string& str);
|
|
-std::string ShowFormat2Str(uint16_t showFormat);
|
|
-uint16_t Str2ShowFormat(const std::string& str);
|
|
-std::string Size2Str(uint64_t size);
|
|
-uint64_t Str2Size(const std::string& str);
|
|
-
|
|
-constexpr char DEFAULT_SPLIT_DELIMIT[] = ",";
|
|
-void Split(const std::string& src, std::vector<std::string>& dest,
|
|
- const std::string& separator = DEFAULT_SPLIT_DELIMIT);
|
|
-uint32_t GetBitsCount(uint64_t n);
|
|
-uint16_t GetBitPos(uint64_t n);
|
|
-
|
|
-std::string Uint2DecStr(uint32_t i);
|
|
-uint32_t DecStr2Uint(const std::string& str);
|
|
-std::string Uint2HexStr(uint32_t i);
|
|
-uint32_t HexStr2Uint(const std::string& str);
|
|
-
|
|
-#if !defined(__WINDOWS__) and !defined(__LINUX__)
|
|
-std::string GetProgName();
|
|
-#endif
|
|
-std::string GetNameByPid(uint32_t pid);
|
|
-uint32_t GetPPidByPid(uint32_t pid);
|
|
-uint64_t GenerateHash(const char *p, size_t size);
|
|
-void PrintErrorno(int err);
|
|
-int WaitingToDo(int max, const std::string& path, std::function<int(const std::string &path)> func);
|
|
-} // namespace HiviewDFX
|
|
-} // namespace OHOS
|
|
-#endif // LOG_UTILS_H
|
|
\ No newline at end of file
|
|
+/*
|
|
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+#ifndef LOG_UTILS_H
|
|
+#define LOG_UTILS_H
|
|
+
|
|
+#include <string>
|
|
+#include <vector>
|
|
+#include <unordered_map>
|
|
+
|
|
+namespace OHOS {
|
|
+namespace HiviewDFX {
|
|
+template<typename K, typename V>
|
|
+class KVMap {
|
|
+using ValueCmp = std::function<bool(const V& v1, const V& v2)>;
|
|
+public:
|
|
+ KVMap(std::unordered_map<K, V> map, K def_k, V def_v,
|
|
+ ValueCmp cmp = [](const V& v1, const V& v2) { return v1 == v2; })
|
|
+ : str_map(map), def_key(def_k), def_value(def_v), compare(cmp)
|
|
+ {
|
|
+ }
|
|
+
|
|
+ const V& GetValue(K key) const
|
|
+ {
|
|
+ auto it = str_map.find(key);
|
|
+ return it == str_map.end() ? def_value : it->second;
|
|
+ }
|
|
+
|
|
+ const K GetKey(const V& value) const
|
|
+ {
|
|
+ for (auto& it : str_map) {
|
|
+ if (compare(value, it.second)) {
|
|
+ return it.first;
|
|
+ }
|
|
+ }
|
|
+ return def_key;
|
|
+ }
|
|
+
|
|
+ std::vector<K> GetAllKeys() const
|
|
+ {
|
|
+ std::vector<K> keys;
|
|
+ for (auto& it : str_map) {
|
|
+ keys.push_back(it.first);
|
|
+ }
|
|
+ return keys;
|
|
+ }
|
|
+
|
|
+ bool IsValidKey(K key) const
|
|
+ {
|
|
+ return (str_map.find(key) != str_map.end());
|
|
+ }
|
|
+
|
|
+private:
|
|
+ const std::unordered_map<K, V> str_map;
|
|
+ const K def_key;
|
|
+ const V def_value;
|
|
+ const ValueCmp compare;
|
|
+};
|
|
+using StringMap = KVMap<uint16_t, std::string>;
|
|
+std::string ErrorCode2Str(int16_t errorCode);
|
|
+std::string LogType2Str(uint16_t logType);
|
|
+uint16_t Str2LogType(const std::string& str);
|
|
+std::string ComboLogType2Str(uint16_t shiftType);
|
|
+uint16_t Str2ComboLogType(const std::string& str);
|
|
+std::vector<uint16_t> GetAllLogTypes();
|
|
+std::string LogLevel2Str(uint16_t logLevel);
|
|
+uint16_t Str2LogLevel(const std::string& str);
|
|
+std::string LogLevel2ShortStr(uint16_t logLevel);
|
|
+uint16_t ShortStr2LogLevel(const std::string& str);
|
|
+uint16_t PrettyStr2LogLevel(const std::string& str);
|
|
+std::string ComboLogLevel2Str(uint16_t shiftLevel);
|
|
+uint16_t Str2ComboLogLevel(const std::string& str);
|
|
+std::string ShowFormat2Str(uint16_t showFormat);
|
|
+uint16_t Str2ShowFormat(const std::string& str);
|
|
+std::string Size2Str(uint64_t size);
|
|
+uint64_t Str2Size(const std::string& str);
|
|
+
|
|
+constexpr char DEFAULT_SPLIT_DELIMIT[] = ",";
|
|
+void Split(const std::string& src, std::vector<std::string>& dest,
|
|
+ const std::string& separator = DEFAULT_SPLIT_DELIMIT);
|
|
+uint32_t GetBitsCount(uint64_t n);
|
|
+uint16_t GetBitPos(uint64_t n);
|
|
+
|
|
+std::string Uint2DecStr(uint32_t i);
|
|
+uint32_t DecStr2Uint(const std::string& str);
|
|
+std::string Uint2HexStr(uint32_t i);
|
|
+uint32_t HexStr2Uint(const std::string& str);
|
|
+
|
|
+#if !defined(__WINDOWS__) and !defined(__LINUX__)
|
|
+std::string GetProgName();
|
|
+#endif
|
|
+std::string GetNameByPid(uint32_t pid);
|
|
+uint32_t GetPPidByPid(uint32_t pid);
|
|
+uint64_t GenerateHash(const char *p, size_t size);
|
|
+void PrintErrorno(int err);
|
|
+int WaitingToDo(int max, const std::string& path, std::function<int(const std::string &path)> func);
|
|
+} // namespace HiviewDFX
|
|
+} // namespace OHOS
|
|
+#endif // LOG_UTILS_H
|
|
diff --git a/frameworks/libhilog/utils/log_print.cpp b/frameworks/libhilog/utils/log_print.cpp
|
|
index 6d47a9a..c7ebf21 100644
|
|
--- a/frameworks/libhilog/utils/log_print.cpp
|
|
+++ b/frameworks/libhilog/utils/log_print.cpp
|
|
@@ -1,180 +1,180 @@
|
|
-/*
|
|
- * Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
- * Licensed under the Apache License, Version 2.0 (the "License");
|
|
- * you may not use this file except in compliance with the License.
|
|
- * You may obtain a copy of the License at
|
|
- *
|
|
- * http://www.apache.org/licenses/LICENSE-2.0
|
|
- *
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
- * See the License for the specific language governing permissions and
|
|
- * limitations under the License.
|
|
- */
|
|
-#include <sys/time.h>
|
|
-#include <iomanip>
|
|
-#include <map>
|
|
-#include <securec.h>
|
|
-#include <hilog/log.h>
|
|
-
|
|
-#include "hilog_common.h"
|
|
-#include "log_utils.h"
|
|
-#include "log_print.h"
|
|
-
|
|
-namespace OHOS {
|
|
-namespace HiviewDFX {
|
|
-using namespace std;
|
|
-
|
|
-static constexpr int COLOR_BLUE = 75;
|
|
-static constexpr int COLOR_DEFAULT = 231;
|
|
-static constexpr int COLOR_GREEN = 40;
|
|
-static constexpr int COLOR_ORANGE = 166;
|
|
-static constexpr int COLOR_RED = 196;
|
|
-static constexpr int COLOR_YELLOW = 226;
|
|
-static constexpr int TM_YEAR_BASE = 1900;
|
|
-static constexpr int DT_WIDTH = 2;
|
|
-static constexpr long long NS2US = 1000LL;
|
|
-static constexpr long long NS2MS = 1000000LL;
|
|
-static constexpr int MONO_WIDTH = 8;
|
|
-static constexpr int EPOCH_WIDTH = 10;
|
|
-static constexpr int MSEC_WIDTH = 3;
|
|
-static constexpr int USEC_WIDTH = 6;
|
|
-static constexpr int NSEC_WIDTH = 9;
|
|
-static constexpr int PID_WIDTH = 5;
|
|
-static constexpr int DOMAIN_WIDTH = 5;
|
|
-static constexpr int DOMAIN_SHORT_MASK = 0xFFFFF;
|
|
-
|
|
-static inline int GetColor(uint16_t level)
|
|
-{
|
|
- switch (LogLevel(level)) {
|
|
- case LOG_DEBUG: return COLOR_BLUE;
|
|
- case LOG_INFO: return COLOR_GREEN;
|
|
- case LOG_WARN: return COLOR_ORANGE;
|
|
- case LOG_ERROR: return COLOR_RED;
|
|
- case LOG_FATAL: return COLOR_YELLOW;
|
|
- default: return COLOR_DEFAULT;
|
|
- }
|
|
-}
|
|
-
|
|
-static inline const char* GetLogTypePrefix(uint16_t type)
|
|
-{
|
|
- switch (LogType(type)) {
|
|
- case LOG_APP: return "A";
|
|
- case LOG_INIT: return "I";
|
|
- case LOG_CORE: return "C";
|
|
- case LOG_KMSG: return "K";
|
|
- default: return " ";
|
|
- }
|
|
-}
|
|
-
|
|
-static inline uint32_t ShortDomain(uint32_t d)
|
|
-{
|
|
- return (d) & DOMAIN_SHORT_MASK;
|
|
-}
|
|
-
|
|
-static void PrintLogPrefix(const LogContent& content, const LogFormat& format, std::ostream& out)
|
|
-{
|
|
- // 1. print day & time
|
|
- if (format.timeFormat == FormatTime::TIME) {
|
|
- struct tm tl;
|
|
- time_t time = content.tv_sec;
|
|
-#if (defined( __WINDOWS__ ))
|
|
- if (localtime_s(&tl, &time) != 0) {
|
|
- return;
|
|
- }
|
|
-#else
|
|
- if (localtime_r(&time, &tl) == nullptr) {
|
|
- return;
|
|
- }
|
|
- if (format.zone) {
|
|
- out << tl.tm_zone << " ";
|
|
- }
|
|
-#endif
|
|
- if (format.year) {
|
|
- out << (tl.tm_year + TM_YEAR_BASE) << "-";
|
|
- }
|
|
- out << setfill('0');
|
|
- out << setw(DT_WIDTH) << (tl.tm_mon + 1) << "-" << setw(DT_WIDTH) << tl.tm_mday << " ";
|
|
- out << setw(DT_WIDTH) << tl.tm_hour << ":" << setw(DT_WIDTH) << tl.tm_min << ":";
|
|
- out << setw(DT_WIDTH) << tl.tm_sec;
|
|
- } else if (format.timeFormat == FormatTime::MONOTONIC) {
|
|
- out << setfill(' ');
|
|
- out << setw(MONO_WIDTH) << content.mono_sec;
|
|
- } else if (format.timeFormat == FormatTime::EPOCH) {
|
|
- out << setfill(' ');
|
|
- out << setw(EPOCH_WIDTH) << content.tv_sec;
|
|
- } else {
|
|
- out << "Invalid time format" << endl;
|
|
- return;
|
|
- }
|
|
- // 1.1 print msec/usec/nsec
|
|
- out << ".";
|
|
- out << setfill('0');
|
|
- if (format.timeAccuFormat == FormatTimeAccu::MSEC) {
|
|
- out << setw(MSEC_WIDTH) << (content.tv_nsec / NS2MS);
|
|
- } else if (format.timeAccuFormat == FormatTimeAccu::USEC) {
|
|
- out << setw(USEC_WIDTH) << (content.tv_nsec / NS2US);
|
|
- } else if (format.timeAccuFormat == FormatTimeAccu::NSEC) {
|
|
- out << setw(NSEC_WIDTH) << content.tv_nsec;
|
|
- } else {
|
|
- out << "Invalid time accuracy format" << endl;
|
|
- return;
|
|
- }
|
|
- out << setfill(' ');
|
|
- // 2. print pid/tid
|
|
- out << " " << setw(PID_WIDTH) << content.pid << " " << setw(PID_WIDTH) << content.tid;
|
|
- // 3. print level
|
|
- out << " " << LogLevel2ShortStr(content.level) << " ";
|
|
- // 4. print log type
|
|
- out << GetLogTypePrefix(content.type);
|
|
- // 5. print domain
|
|
- out << setfill('0');
|
|
- out << hex << setw(DOMAIN_WIDTH) << ShortDomain(content.domain) << dec;
|
|
- // 5. print tag & log
|
|
- out << "/" << content.tag << ": ";
|
|
-}
|
|
-
|
|
-void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std::ostream& out)
|
|
-{
|
|
- // set colorful log
|
|
- if (format.colorful) {
|
|
- out << "\x1B[38;5;" << GetColor(content.level) << "m";
|
|
- }
|
|
-
|
|
- const char *pHead = content.log;
|
|
- const char *pScan = content.log;
|
|
- // split the log content by '\n', and add log prefix(datetime, pid, tid....) to each new line
|
|
- while (*pScan != '\0') {
|
|
- if (*pScan == '\n') {
|
|
- char tmp[MAX_LOG_LEN];
|
|
- int len = static_cast<int>(pScan - pHead);
|
|
- errno_t ret = memcpy_s(tmp, MAX_LOG_LEN - 1, pHead, len);
|
|
- if (ret != EOK) {
|
|
- break;
|
|
- }
|
|
- tmp[(MAX_LOG_LEN - 1) > len ? len : (MAX_LOG_LEN -1)] = '\0';
|
|
- if (tmp[0] != '\0') {
|
|
- PrintLogPrefix(content, format, out);
|
|
- out << tmp << endl;
|
|
- }
|
|
- pHead = pScan + 1;
|
|
- }
|
|
- pScan++;
|
|
- }
|
|
- if (pHead[0] != '\0') {
|
|
- PrintLogPrefix(content, format, out);
|
|
- out << pHead;
|
|
- }
|
|
-
|
|
- // restore color
|
|
- if (format.colorful) {
|
|
- out << "\x1B[0m";
|
|
- }
|
|
- if (pHead[0] != '\0') {
|
|
- out << endl;
|
|
- }
|
|
- return;
|
|
-}
|
|
-} // namespace HiviewDFX
|
|
-} // namespace OHOS
|
|
\ No newline at end of file
|
|
+/*
|
|
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+#include <sys/time.h>
|
|
+#include <iomanip>
|
|
+#include <map>
|
|
+#include <securec.h>
|
|
+#include <hilog/log.h>
|
|
+
|
|
+#include "hilog_common.h"
|
|
+#include "log_utils.h"
|
|
+#include "log_print.h"
|
|
+
|
|
+namespace OHOS {
|
|
+namespace HiviewDFX {
|
|
+using namespace std;
|
|
+
|
|
+static constexpr int COLOR_BLUE = 75;
|
|
+static constexpr int COLOR_DEFAULT = 231;
|
|
+static constexpr int COLOR_GREEN = 40;
|
|
+static constexpr int COLOR_ORANGE = 166;
|
|
+static constexpr int COLOR_RED = 196;
|
|
+static constexpr int COLOR_YELLOW = 226;
|
|
+static constexpr int TM_YEAR_BASE = 1900;
|
|
+static constexpr int DT_WIDTH = 2;
|
|
+static constexpr long long NS2US = 1000LL;
|
|
+static constexpr long long NS2MS = 1000000LL;
|
|
+static constexpr int MONO_WIDTH = 8;
|
|
+static constexpr int EPOCH_WIDTH = 10;
|
|
+static constexpr int MSEC_WIDTH = 3;
|
|
+static constexpr int USEC_WIDTH = 6;
|
|
+static constexpr int NSEC_WIDTH = 9;
|
|
+static constexpr int PID_WIDTH = 5;
|
|
+static constexpr int DOMAIN_WIDTH = 5;
|
|
+static constexpr int DOMAIN_SHORT_MASK = 0xFFFFF;
|
|
+
|
|
+static inline int GetColor(uint16_t level)
|
|
+{
|
|
+ switch (LogLevel(level)) {
|
|
+ case LOG_DEBUG: return COLOR_BLUE;
|
|
+ case LOG_INFO: return COLOR_GREEN;
|
|
+ case LOG_WARN: return COLOR_ORANGE;
|
|
+ case LOG_ERROR: return COLOR_RED;
|
|
+ case LOG_FATAL: return COLOR_YELLOW;
|
|
+ default: return COLOR_DEFAULT;
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline const char* GetLogTypePrefix(uint16_t type)
|
|
+{
|
|
+ switch (LogType(type)) {
|
|
+ case LOG_APP: return "A";
|
|
+ case LOG_INIT: return "I";
|
|
+ case LOG_CORE: return "C";
|
|
+ case LOG_KMSG: return "K";
|
|
+ default: return " ";
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline uint32_t ShortDomain(uint32_t d)
|
|
+{
|
|
+ return (d) & DOMAIN_SHORT_MASK;
|
|
+}
|
|
+
|
|
+static void PrintLogPrefix(const LogContent& content, const LogFormat& format, std::ostream& out)
|
|
+{
|
|
+ // 1. print day & time
|
|
+ if (format.timeFormat == FormatTime::TIME) {
|
|
+ struct tm tl;
|
|
+ time_t time = content.tv_sec;
|
|
+#if (defined( __WINDOWS__ ))
|
|
+ if (localtime_s(&tl, &time) != 0) {
|
|
+ return;
|
|
+ }
|
|
+#else
|
|
+ if (localtime_r(&time, &tl) == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ if (format.zone) {
|
|
+ out << tl.tm_zone << " ";
|
|
+ }
|
|
+#endif
|
|
+ if (format.year) {
|
|
+ out << (tl.tm_year + TM_YEAR_BASE) << "-";
|
|
+ }
|
|
+ out << setfill('0');
|
|
+ out << setw(DT_WIDTH) << (tl.tm_mon + 1) << "-" << setw(DT_WIDTH) << tl.tm_mday << " ";
|
|
+ out << setw(DT_WIDTH) << tl.tm_hour << ":" << setw(DT_WIDTH) << tl.tm_min << ":";
|
|
+ out << setw(DT_WIDTH) << tl.tm_sec;
|
|
+ } else if (format.timeFormat == FormatTime::MONOTONIC) {
|
|
+ out << setfill(' ');
|
|
+ out << setw(MONO_WIDTH) << content.mono_sec;
|
|
+ } else if (format.timeFormat == FormatTime::EPOCH) {
|
|
+ out << setfill(' ');
|
|
+ out << setw(EPOCH_WIDTH) << content.tv_sec;
|
|
+ } else {
|
|
+ out << "Invalid time format" << endl;
|
|
+ return;
|
|
+ }
|
|
+ // 1.1 print msec/usec/nsec
|
|
+ out << ".";
|
|
+ out << setfill('0');
|
|
+ if (format.timeAccuFormat == FormatTimeAccu::MSEC) {
|
|
+ out << setw(MSEC_WIDTH) << (content.tv_nsec / NS2MS);
|
|
+ } else if (format.timeAccuFormat == FormatTimeAccu::USEC) {
|
|
+ out << setw(USEC_WIDTH) << (content.tv_nsec / NS2US);
|
|
+ } else if (format.timeAccuFormat == FormatTimeAccu::NSEC) {
|
|
+ out << setw(NSEC_WIDTH) << content.tv_nsec;
|
|
+ } else {
|
|
+ out << "Invalid time accuracy format" << endl;
|
|
+ return;
|
|
+ }
|
|
+ out << setfill(' ');
|
|
+ // 2. print pid/tid
|
|
+ out << " " << setw(PID_WIDTH) << content.pid << " " << setw(PID_WIDTH) << content.tid;
|
|
+ // 3. print level
|
|
+ out << " " << LogLevel2ShortStr(content.level) << " ";
|
|
+ // 4. print log type
|
|
+ out << GetLogTypePrefix(content.type);
|
|
+ // 5. print domain
|
|
+ out << setfill('0');
|
|
+ out << hex << setw(DOMAIN_WIDTH) << ShortDomain(content.domain) << dec;
|
|
+ // 5. print tag & log
|
|
+ out << "/" << content.tag << ": ";
|
|
+}
|
|
+
|
|
+void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std::ostream& out)
|
|
+{
|
|
+ // set colorful log
|
|
+ if (format.colorful) {
|
|
+ out << "\x1B[38;5;" << GetColor(content.level) << "m";
|
|
+ }
|
|
+
|
|
+ const char *pHead = content.log;
|
|
+ const char *pScan = content.log;
|
|
+ // split the log content by '\n', and add log prefix(datetime, pid, tid....) to each new line
|
|
+ while (*pScan != '\0') {
|
|
+ if (*pScan == '\n') {
|
|
+ char tmp[MAX_LOG_LEN];
|
|
+ int len = static_cast<int>(pScan - pHead);
|
|
+ errno_t ret = memcpy_s(tmp, MAX_LOG_LEN - 1, pHead, len);
|
|
+ if (ret != EOK) {
|
|
+ break;
|
|
+ }
|
|
+ tmp[(MAX_LOG_LEN - 1) > len ? len : (MAX_LOG_LEN -1)] = '\0';
|
|
+ if (tmp[0] != '\0') {
|
|
+ PrintLogPrefix(content, format, out);
|
|
+ out << tmp << endl;
|
|
+ }
|
|
+ pHead = pScan + 1;
|
|
+ }
|
|
+ pScan++;
|
|
+ }
|
|
+ if (pHead[0] != '\0') {
|
|
+ PrintLogPrefix(content, format, out);
|
|
+ out << pHead;
|
|
+ }
|
|
+
|
|
+ // restore color
|
|
+ if (format.colorful) {
|
|
+ out << "\x1B[0m";
|
|
+ }
|
|
+ if (pHead[0] != '\0') {
|
|
+ out << endl;
|
|
+ }
|
|
+ return;
|
|
+}
|
|
+} // namespace HiviewDFX
|
|
+} // namespace OHOS
|
|
diff --git a/frameworks/libhilog/utils/log_utils.cpp b/frameworks/libhilog/utils/log_utils.cpp
|
|
index 7cef847..af130c4 100644
|
|
--- a/frameworks/libhilog/utils/log_utils.cpp
|
|
+++ b/frameworks/libhilog/utils/log_utils.cpp
|
|
@@ -1,522 +1,522 @@
|
|
-/*
|
|
- * Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
- * Licensed under the Apache License, Version 2.0 (the "License");
|
|
- * you may not use this file except in compliance with the License.
|
|
- * You may obtain a copy of the License at
|
|
- *
|
|
- * http://www.apache.org/licenses/LICENSE-2.0
|
|
- *
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
- * See the License for the specific language governing permissions and
|
|
- * limitations under the License.
|
|
- */
|
|
-#include <cstdint>
|
|
-#include <cstdlib>
|
|
-#include <chrono>
|
|
-#include <functional>
|
|
-#include <regex>
|
|
-#include <sstream>
|
|
-#include <thread>
|
|
-#include <fstream>
|
|
-#include <fcntl.h>
|
|
-#include <securec.h>
|
|
-#include <hilog/log.h>
|
|
-#include <unistd.h>
|
|
-#include "hilog_common.h"
|
|
-#include "hilog_cmd.h"
|
|
-#include "log_utils.h"
|
|
-
|
|
-namespace {
|
|
- constexpr uint32_t ONE_KB = (1UL << 10);
|
|
- constexpr uint32_t ONE_MB = (1UL << 20);
|
|
- constexpr uint32_t ONE_GB = (1UL << 30);
|
|
- constexpr uint64_t ONE_TB = (1ULL << 40);
|
|
- constexpr uint32_t DOMAIN_MIN = DOMAIN_APP_MIN;
|
|
- constexpr uint32_t DOMAIN_MAX = DOMAIN_OS_MAX;
|
|
- constexpr int CMDLINE_PATH_LEN = 32;
|
|
- constexpr int CMDLINE_LEN = 128;
|
|
- constexpr int STATUS_PATH_LEN = 32;
|
|
- constexpr int STATUS_LEN = 1024;
|
|
- const std::string SH_NAMES[] = { "sh", "/bin/sh", "/system/bin/sh", "/xbin/sh", "/system/xbin/sh"};
|
|
-}
|
|
-
|
|
-namespace OHOS {
|
|
-namespace HiviewDFX {
|
|
-using namespace std;
|
|
-using namespace std::chrono;
|
|
-
|
|
-// Buffer Size&Char Map
|
|
-static const KVMap<char, uint64_t> g_SizeMap({
|
|
- {'B', 1}, {'K', ONE_KB}, {'M', ONE_MB},
|
|
- {'G', ONE_GB}, {'T', ONE_TB}
|
|
-}, ' ', 0);
|
|
-
|
|
-string Size2Str(uint64_t size)
|
|
-{
|
|
- string str;
|
|
- uint64_t unit = 1;
|
|
- switch (size) {
|
|
- case 0 ... ONE_KB - 1: unit = 1; break;
|
|
- case ONE_KB ... ONE_MB - 1: unit = ONE_KB; break;
|
|
- case ONE_MB ... ONE_GB - 1: unit = ONE_MB; break;
|
|
- case ONE_GB ... ONE_TB - 1: unit = ONE_GB; break;
|
|
- default: unit = ONE_TB; break;
|
|
- }
|
|
- float i = (static_cast<float>(size)) / unit;
|
|
- constexpr int len = 16;
|
|
- char buf[len] = { 0 };
|
|
- int ret = snprintf_s(buf, len, len - 1, "%.1f", i);
|
|
- if (ret <= 0) {
|
|
- str = to_string(size);
|
|
- } else {
|
|
- str = buf;
|
|
- }
|
|
- return str + g_SizeMap.GetKey(unit);
|
|
-}
|
|
-
|
|
-uint64_t Str2Size(const string& str)
|
|
-{
|
|
- std::regex reg("[0-9]+[BKMGT]?");
|
|
- if (!std::regex_match(str, reg)) {
|
|
- return 0;
|
|
- }
|
|
- uint64_t index = str.size() - 1;
|
|
- uint64_t unit = g_SizeMap.GetValue(str[index]);
|
|
-
|
|
- uint64_t value = stoull(str.substr(0, unit !=0 ? index : index + 1));
|
|
- return value * (unit != 0 ? unit : 1);
|
|
-}
|
|
-
|
|
-// Error Codes&Strings Map
|
|
-static const KVMap<int16_t, string> g_ErrorMsgs({
|
|
- {RET_SUCCESS, "Success"},
|
|
- {RET_FAIL, "Unknown failure reason"},
|
|
- {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"
|
|
- " or DEBUG/INFO/WARN/ERROR/FATAL"},
|
|
- {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg"},
|
|
- {ERR_INVALID_RQST_CMD, "Invalid request cmd, please check sourcecode"},
|
|
- {ERR_QUERY_TYPE_INVALID, "Can't query kmsg type logs combined with other types logs."},
|
|
- {ERR_INVALID_DOMAIN_STR, "Invalid domain string"},
|
|
- {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be in range ["
|
|
- + Size2Str(MIN_LOG_FILE_SIZE) + ", " + Size2Str(MAX_LOG_FILE_SIZE) + "]"},
|
|
- {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"},
|
|
- {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"},
|
|
- {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"},
|
|
- {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"},
|
|
- {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"},
|
|
- {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"},
|
|
- {ERR_LOG_PERSIST_TASK_EXISTED, "Log persist task is existed"},
|
|
- {ERR_DOMAIN_INVALID, ("Invalid domain, domain should be in range (" + Uint2HexStr(DOMAIN_MIN)
|
|
- + ", " +Uint2HexStr(DOMAIN_MAX) +"]")},
|
|
- {ERR_MSG_LEN_INVALID, "Invalid message length"},
|
|
- {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be in range [" + to_string(JOB_ID_MIN)
|
|
- + ", " + to_string(JOB_ID_MAX) + ")"},
|
|
- {ERR_BUFF_SIZE_INVALID, ("Invalid buffer size, buffer size should be in range [" + Size2Str(MIN_BUFFER_SIZE)
|
|
- + ", " + Size2Str(MAX_BUFFER_SIZE) + "]")},
|
|
- {ERR_COMMAND_INVALID, "Mutlti commands can't be used in combination"},
|
|
- {ERR_LOG_FILE_NUM_INVALID, "Invalid number of files"},
|
|
- {ERR_NOT_NUMBER_STR, "Not a numeric string"},
|
|
- {ERR_TOO_MANY_ARGUMENTS, "Too many arguments"},
|
|
- {ERR_DUPLICATE_OPTION, "Too many duplicate options"},
|
|
- {ERR_INVALID_ARGUMENT, "Invalid argument"},
|
|
- {ERR_TOO_MANY_DOMAINS, "Max domain count is " + to_string(MAX_DOMAINS)},
|
|
- {ERR_INVALID_SIZE_STR, "Invalid size string"},
|
|
- {ERR_TOO_MANY_PIDS, "Max pid count is " + to_string(MAX_PIDS)},
|
|
- {ERR_TOO_MANY_TAGS, "Max tag count is " + to_string(MAX_TAGS)},
|
|
- {ERR_TAG_STR_TOO_LONG, ("Tag string too long, max length is " + to_string(MAX_TAG_LEN - 1))},
|
|
- {ERR_REGEX_STR_TOO_LONG, ("Regular expression too long, max length is " + to_string(MAX_REGEX_STR_LEN - 1))},
|
|
- {ERR_FILE_NAME_TOO_LONG, ("File name too long, max length is " + to_string(MAX_FILE_NAME_LEN))},
|
|
- {ERR_SOCKET_CLIENT_INIT_FAIL, "Socket client init failed"},
|
|
- {ERR_SOCKET_WRITE_MSG_HEADER_FAIL, "Socket rite message header failed"},
|
|
- {ERR_SOCKET_WRITE_CMD_FAIL, "Socket write command failed"},
|
|
- {ERR_SOCKET_RECEIVE_RSP, "Unable to receive message from socket"},
|
|
- {ERR_PERSIST_TASK_EMPTY, "No running persist task, please check"},
|
|
- {ERR_JOBID_NOT_EXSIST, "Persist task of this job id doesn't exist, please check"},
|
|
- {ERR_TOO_MANY_JOBS, ("Too many jobs are running, max job count is:" + to_string(MAX_JOBS))},
|
|
- {ERR_STATS_NOT_ENABLE, "Statistic feature is not enable, "
|
|
- "please set param persist.sys.hilog.stats true to enable it, "
|
|
- "further more, you can set persist.sys.hilog.stats.tag true to enable counting log by tags"},
|
|
- {ERR_NO_RUNNING_TASK, "No running persistent task"},
|
|
- {ERR_NO_PID_PERMISSION, "Permission denied, only shell and root can filter logs by pid"},
|
|
-}, RET_FAIL, "Unknown error code");
|
|
-
|
|
-string ErrorCode2Str(int16_t errorCode)
|
|
-{
|
|
- return g_ErrorMsgs.GetValue((uint16_t)errorCode) + " [CODE: " + to_string(errorCode) + "]";
|
|
-}
|
|
-
|
|
-// Log Types&Strings Map
|
|
-static const StringMap g_LogTypes({
|
|
- {LOG_INIT, "init"}, {LOG_CORE, "core"}, {LOG_APP, "app"}, {LOG_KMSG, "kmsg"}
|
|
-}, LOG_TYPE_MAX, "invalid");
|
|
-
|
|
-string LogType2Str(uint16_t logType)
|
|
-{
|
|
- return g_LogTypes.GetValue(logType);
|
|
-}
|
|
-
|
|
-uint16_t Str2LogType(const string& str)
|
|
-{
|
|
- return g_LogTypes.GetKey(str);
|
|
-}
|
|
-
|
|
-string ComboLogType2Str(uint16_t shiftType)
|
|
-{
|
|
- vector<uint16_t> types = g_LogTypes.GetAllKeys();
|
|
- string str = "";
|
|
- uint16_t typeAll = 0;
|
|
-
|
|
- for (uint16_t t : types) {
|
|
- typeAll |= (1 << t);
|
|
- }
|
|
- shiftType &= typeAll;
|
|
- for (uint16_t t: types) {
|
|
- if ((1 << t) & shiftType) {
|
|
- shiftType &= (~(1 << t));
|
|
- str += (LogType2Str(t) + (shiftType != 0 ? "," : ""));
|
|
- }
|
|
- if (shiftType == 0) {
|
|
- break;
|
|
- }
|
|
- }
|
|
- return str;
|
|
-}
|
|
-
|
|
-uint16_t Str2ComboLogType(const string& str)
|
|
-{
|
|
- uint16_t logTypes = 0;
|
|
- if (str == "") {
|
|
- logTypes = (1 << LOG_CORE) | (1 << LOG_APP);
|
|
- return logTypes;
|
|
- }
|
|
- vector<string> vec;
|
|
- Split(str, vec);
|
|
- for (auto& it : vec) {
|
|
- if (it == "") {
|
|
- continue;
|
|
- }
|
|
- uint16_t t = Str2LogType(it);
|
|
- if (t == LOG_TYPE_MAX) {
|
|
- return 0;
|
|
- }
|
|
- logTypes |= (1 << t);
|
|
- }
|
|
- return logTypes;
|
|
-}
|
|
-
|
|
-vector<uint16_t> GetAllLogTypes()
|
|
-{
|
|
- return g_LogTypes.GetAllKeys();
|
|
-}
|
|
-
|
|
-// Log Levels&Strings Map
|
|
-static const StringMap g_LogLevels({
|
|
- {LOG_DEBUG, "DEBUG"}, {LOG_INFO, "INFO"}, {LOG_WARN, "WARN"},
|
|
- {LOG_ERROR, "ERROR"}, {LOG_FATAL, "FATAL"}, {LOG_LEVEL_MAX, "X"}
|
|
-}, LOG_LEVEL_MIN, "INVALID", [](const string& l1, const string& l2) {
|
|
- if (l1.length() == l2.length()) {
|
|
- return std::equal(l1.begin(), l1.end(), l2.begin(), [](char a, char b) {
|
|
- return std::tolower(a) == std::tolower(b);
|
|
- });
|
|
- } else {
|
|
- return false;
|
|
- }
|
|
-});
|
|
-
|
|
-string LogLevel2Str(uint16_t logLevel)
|
|
-{
|
|
- return g_LogLevels.GetValue(logLevel);
|
|
-}
|
|
-
|
|
-uint16_t Str2LogLevel(const string& str)
|
|
-{
|
|
- return g_LogLevels.GetKey(str);
|
|
-}
|
|
-
|
|
-// Log Levels&Short Strings Map
|
|
-static const StringMap g_ShortLogLevels({
|
|
- {LOG_DEBUG, "D"}, {LOG_INFO, "I"}, {LOG_WARN, "W"},
|
|
- {LOG_ERROR, "E"}, {LOG_FATAL, "F"}, {LOG_LEVEL_MAX, "X"}
|
|
-}, LOG_LEVEL_MIN, "V", [](const string& l1, const string& l2) {
|
|
- return (l1.length() == 1 && std::tolower(l1[0]) == std::tolower(l2[0]));
|
|
-});
|
|
-
|
|
-string LogLevel2ShortStr(uint16_t logLevel)
|
|
-{
|
|
- return g_ShortLogLevels.GetValue(logLevel);
|
|
-}
|
|
-
|
|
-uint16_t ShortStr2LogLevel(const string& str)
|
|
-{
|
|
- return g_ShortLogLevels.GetKey(str);
|
|
-}
|
|
-
|
|
-uint16_t PrettyStr2LogLevel(const string& str)
|
|
-{
|
|
- uint16_t level = ShortStr2LogLevel(str);
|
|
- if (level == static_cast<uint16_t>(LOG_LEVEL_MIN)) {
|
|
- return Str2LogLevel(str);
|
|
- }
|
|
- return level;
|
|
-}
|
|
-
|
|
-string ComboLogLevel2Str(uint16_t shiftLevel)
|
|
-{
|
|
- vector<uint16_t> levels = g_ShortLogLevels.GetAllKeys();
|
|
- string str = "";
|
|
- uint16_t levelAll = 0;
|
|
-
|
|
- for (uint16_t l : levels) {
|
|
- levelAll |= (1 << l);
|
|
- }
|
|
- shiftLevel &= levelAll;
|
|
- for (uint16_t l: levels) {
|
|
- if ((1 << l) & shiftLevel) {
|
|
- shiftLevel &= (~(1 << l));
|
|
- str += (LogLevel2Str(l) + (shiftLevel != 0 ? "," : ""));
|
|
- }
|
|
- if (shiftLevel == 0) {
|
|
- break;
|
|
- }
|
|
- }
|
|
- return str;
|
|
-}
|
|
-
|
|
-uint16_t Str2ComboLogLevel(const string& str)
|
|
-{
|
|
- uint16_t logLevels = 0;
|
|
- if (str == "") {
|
|
- logLevels = 0xFFFF;
|
|
- return logLevels;
|
|
- }
|
|
- vector<string> vec;
|
|
- Split(str, vec);
|
|
- for (auto& it : vec) {
|
|
- if (it == "") {
|
|
- continue;
|
|
- }
|
|
- uint16_t t = PrettyStr2LogLevel(it);
|
|
- if (t == LOG_LEVEL_MIN || t >= LOG_LEVEL_MAX) {
|
|
- return 0;
|
|
- }
|
|
- logLevels |= (1 << t);
|
|
- }
|
|
- return logLevels;
|
|
-}
|
|
-
|
|
-void Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator)
|
|
-{
|
|
- std::string str = src;
|
|
- std::string substring;
|
|
- std::string::size_type start = 0;
|
|
- std::string::size_type index;
|
|
- dest.clear();
|
|
- index = str.find_first_of(separator, start);
|
|
- if (index == std::string::npos) {
|
|
- dest.emplace_back(str);
|
|
- return;
|
|
- }
|
|
- do {
|
|
- substring = str.substr(start, index - start);
|
|
- dest.emplace_back(substring);
|
|
- start = index + separator.size();
|
|
- index = str.find(separator, start);
|
|
- } while (index != std::string::npos);
|
|
- substring = str.substr(start);
|
|
- if (substring != "") {
|
|
- dest.emplace_back(substring);
|
|
- }
|
|
-}
|
|
-
|
|
-uint32_t GetBitsCount(uint64_t n)
|
|
-{
|
|
- uint32_t count = 0;
|
|
- while (n != 0) {
|
|
- ++count;
|
|
- n = n & (n-1);
|
|
- }
|
|
- return count;
|
|
-}
|
|
-
|
|
-uint16_t GetBitPos(uint64_t n)
|
|
-{
|
|
- if (!(n && (!(n & (n-1))))) { // only accpet the number which is power of 2
|
|
- return 0;
|
|
- }
|
|
-
|
|
- uint16_t i = 0;
|
|
- while (n >> (i++)) {}
|
|
- i--;
|
|
- return i-1;
|
|
-}
|
|
-
|
|
-enum class Radix {
|
|
- RADIX_DEC,
|
|
- RADIX_HEX,
|
|
-};
|
|
-template<typename T>
|
|
-static string Num2Str(T num, Radix radix)
|
|
-{
|
|
- stringstream ss;
|
|
- auto r = std::dec;
|
|
- if (radix == Radix::RADIX_HEX) {
|
|
- r = std::hex;
|
|
- }
|
|
- ss << r << num;
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-template<typename T>
|
|
-static void Str2Num(const string& str, T& num, Radix radix)
|
|
-{
|
|
- T i = 0;
|
|
- std::stringstream ss;
|
|
- auto r = std::dec;
|
|
- if (radix == Radix::RADIX_HEX) {
|
|
- r = std::hex;
|
|
- }
|
|
- ss << r << str;
|
|
- ss >> i;
|
|
- num = i;
|
|
- return;
|
|
-}
|
|
-
|
|
-string Uint2DecStr(uint32_t i)
|
|
-{
|
|
- return Num2Str(i, Radix::RADIX_DEC);
|
|
-}
|
|
-
|
|
-uint32_t DecStr2Uint(const string& str)
|
|
-{
|
|
- uint32_t i = 0;
|
|
- Str2Num(str, i, Radix::RADIX_DEC);
|
|
- return i;
|
|
-}
|
|
-
|
|
-string Uint2HexStr(uint32_t i)
|
|
-{
|
|
- return Num2Str(i, Radix::RADIX_HEX);
|
|
-}
|
|
-
|
|
-uint32_t HexStr2Uint(const string& str)
|
|
-{
|
|
- uint32_t i = 0;
|
|
- Str2Num(str, i, Radix::RADIX_HEX);
|
|
- return i;
|
|
-}
|
|
-
|
|
-#if !defined(__WINDOWS__) and !defined(__LINUX__)
|
|
-string GetProgName()
|
|
-{
|
|
-#ifdef HILOG_USE_MUSL
|
|
- return program_invocation_short_name;
|
|
-#else
|
|
- return getprogname();
|
|
-#endif
|
|
-}
|
|
-#endif
|
|
-
|
|
-string GetNameByPid(uint32_t pid)
|
|
-{
|
|
- char path[CMDLINE_PATH_LEN] = { 0 };
|
|
- if (snprintf_s(path, CMDLINE_PATH_LEN, CMDLINE_PATH_LEN - 1, "/proc/%d/cmdline", pid) <= 0) {
|
|
- return "";
|
|
- }
|
|
- char cmdline[CMDLINE_LEN] = { 0 };
|
|
- int i = 0;
|
|
- FILE *fp = fopen(path, "r");
|
|
- if (fp == nullptr) {
|
|
- return "";
|
|
- }
|
|
- while (i < (CMDLINE_LEN - 1)) {
|
|
- char c = static_cast<char>(fgetc(fp));
|
|
- // 0. don't need args of cmdline
|
|
- // 1. ignore unvisible character
|
|
- if (!isgraph(c)) {
|
|
- break;
|
|
- }
|
|
- cmdline[i] = c;
|
|
- i++;
|
|
- }
|
|
- (void)fclose(fp);
|
|
- return cmdline;
|
|
-}
|
|
-
|
|
-uint32_t GetPPidByPid(uint32_t pid)
|
|
-{
|
|
- uint32_t ppid = 0;
|
|
- char path[STATUS_PATH_LEN] = { 0 };
|
|
- if (snprintf_s(path, STATUS_PATH_LEN, STATUS_PATH_LEN - 1, "/proc/%u/status", pid) <= 0) {
|
|
- return ppid;
|
|
- }
|
|
- FILE *fp = fopen(path, "r");
|
|
- if (fp == nullptr) {
|
|
- return ppid;
|
|
- }
|
|
- char buf[STATUS_LEN] = { 0 };
|
|
- size_t ret = fread(buf, sizeof(char), STATUS_LEN - 1, fp);
|
|
- (void)fclose(fp);
|
|
- if (ret <= 0) {
|
|
- return ppid;
|
|
- } else {
|
|
- buf[ret++] = '\0';
|
|
- }
|
|
- char *ppidLoc = strstr(buf, "PPid:");
|
|
- if ((ppidLoc == nullptr) || (sscanf_s(ppidLoc, "PPid:%d", &ppid) == -1)) {
|
|
- return ppid;
|
|
- }
|
|
- std::string ppidName = GetNameByPid(ppid);
|
|
- // ppid fork the sh to execute hilog, sh is not wanted ppid
|
|
- if (std::find(std::begin(SH_NAMES), std::end(SH_NAMES), ppidName) != std::end(SH_NAMES)) {
|
|
- return GetPPidByPid(ppid);
|
|
- }
|
|
- return ppid;
|
|
-}
|
|
-
|
|
-uint64_t GenerateHash(const char *p, size_t size)
|
|
-{
|
|
- static const uint64_t PRIME = 0x100000001B3ull;
|
|
- static const uint64_t BASIS = 0xCBF29CE484222325ull;
|
|
- uint64_t ret {BASIS};
|
|
- unsigned long i = 0;
|
|
- while (i < size) {
|
|
- ret ^= *(p + i);
|
|
- ret *= PRIME;
|
|
- i++;
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
-void PrintErrorno(int err)
|
|
-{
|
|
- constexpr int bufSize = 256;
|
|
- char buf[bufSize] = { 0 };
|
|
-#ifndef __WINDOWS__
|
|
- (void)strerror_r(err, buf, bufSize);
|
|
-#else
|
|
- (void)strerror_s(buf, bufSize, err);
|
|
-#endif
|
|
- std::cerr << "Errno: " << err << ", " << buf << std::endl;
|
|
-}
|
|
-
|
|
-int WaitingToDo(int max, const string& path, function<int(const string &path)> func)
|
|
-{
|
|
- chrono::steady_clock::time_point start = chrono::steady_clock::now();
|
|
- chrono::milliseconds wait(max);
|
|
- while (true) {
|
|
- if (func(path) != RET_FAIL) {
|
|
- cout << "waiting for " << path << " successfully!" << endl;
|
|
- return RET_SUCCESS;
|
|
- }
|
|
-
|
|
- std::this_thread::sleep_for(10ms);
|
|
- if ((chrono::steady_clock::now() - start) > wait) {
|
|
- cerr << "waiting for " << path << " failed!" << endl;
|
|
- return RET_FAIL;
|
|
- }
|
|
- }
|
|
-}
|
|
-} // namespace HiviewDFX
|
|
-} // namespace OHOS
|
|
+/*
|
|
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+#include <cstdint>
|
|
+#include <cstdlib>
|
|
+#include <chrono>
|
|
+#include <functional>
|
|
+#include <regex>
|
|
+#include <sstream>
|
|
+#include <thread>
|
|
+#include <fstream>
|
|
+#include <fcntl.h>
|
|
+#include <securec.h>
|
|
+#include <hilog/log.h>
|
|
+#include <unistd.h>
|
|
+#include "hilog_common.h"
|
|
+#include "hilog_cmd.h"
|
|
+#include "log_utils.h"
|
|
+
|
|
+namespace {
|
|
+ constexpr uint32_t ONE_KB = (1UL << 10);
|
|
+ constexpr uint32_t ONE_MB = (1UL << 20);
|
|
+ constexpr uint32_t ONE_GB = (1UL << 30);
|
|
+ constexpr uint64_t ONE_TB = (1ULL << 40);
|
|
+ constexpr uint32_t DOMAIN_MIN = DOMAIN_APP_MIN;
|
|
+ constexpr uint32_t DOMAIN_MAX = DOMAIN_OS_MAX;
|
|
+ constexpr int CMDLINE_PATH_LEN = 32;
|
|
+ constexpr int CMDLINE_LEN = 128;
|
|
+ constexpr int STATUS_PATH_LEN = 32;
|
|
+ constexpr int STATUS_LEN = 1024;
|
|
+ const std::string SH_NAMES[] = { "sh", "/bin/sh", "/system/bin/sh", "/xbin/sh", "/system/xbin/sh"};
|
|
+}
|
|
+
|
|
+namespace OHOS {
|
|
+namespace HiviewDFX {
|
|
+using namespace std;
|
|
+using namespace std::chrono;
|
|
+
|
|
+// Buffer Size&Char Map
|
|
+static const KVMap<char, uint64_t> g_SizeMap({
|
|
+ {'B', 1}, {'K', ONE_KB}, {'M', ONE_MB},
|
|
+ {'G', ONE_GB}, {'T', ONE_TB}
|
|
+}, ' ', 0);
|
|
+
|
|
+string Size2Str(uint64_t size)
|
|
+{
|
|
+ string str;
|
|
+ uint64_t unit = 1;
|
|
+ switch (size) {
|
|
+ case 0 ... ONE_KB - 1: unit = 1; break;
|
|
+ case ONE_KB ... ONE_MB - 1: unit = ONE_KB; break;
|
|
+ case ONE_MB ... ONE_GB - 1: unit = ONE_MB; break;
|
|
+ case ONE_GB ... ONE_TB - 1: unit = ONE_GB; break;
|
|
+ default: unit = ONE_TB; break;
|
|
+ }
|
|
+ float i = (static_cast<float>(size)) / unit;
|
|
+ constexpr int len = 16;
|
|
+ char buf[len] = { 0 };
|
|
+ int ret = snprintf_s(buf, len, len - 1, "%.1f", i);
|
|
+ if (ret <= 0) {
|
|
+ str = to_string(size);
|
|
+ } else {
|
|
+ str = buf;
|
|
+ }
|
|
+ return str + g_SizeMap.GetKey(unit);
|
|
+}
|
|
+
|
|
+uint64_t Str2Size(const string& str)
|
|
+{
|
|
+ std::regex reg("[0-9]+[BKMGT]?");
|
|
+ if (!std::regex_match(str, reg)) {
|
|
+ return 0;
|
|
+ }
|
|
+ uint64_t index = str.size() - 1;
|
|
+ uint64_t unit = g_SizeMap.GetValue(str[index]);
|
|
+
|
|
+ uint64_t value = stoull(str.substr(0, unit !=0 ? index : index + 1));
|
|
+ return value * (unit != 0 ? unit : 1);
|
|
+}
|
|
+
|
|
+// Error Codes&Strings Map
|
|
+static const KVMap<int16_t, string> g_ErrorMsgs({
|
|
+ {RET_SUCCESS, "Success"},
|
|
+ {RET_FAIL, "Unknown failure reason"},
|
|
+ {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"
|
|
+ " or DEBUG/INFO/WARN/ERROR/FATAL"},
|
|
+ {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg"},
|
|
+ {ERR_INVALID_RQST_CMD, "Invalid request cmd, please check sourcecode"},
|
|
+ {ERR_QUERY_TYPE_INVALID, "Can't query kmsg type logs combined with other types logs."},
|
|
+ {ERR_INVALID_DOMAIN_STR, "Invalid domain string"},
|
|
+ {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be in range ["
|
|
+ + Size2Str(MIN_LOG_FILE_SIZE) + ", " + Size2Str(MAX_LOG_FILE_SIZE) + "]"},
|
|
+ {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"},
|
|
+ {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"},
|
|
+ {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"},
|
|
+ {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"},
|
|
+ {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"},
|
|
+ {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"},
|
|
+ {ERR_LOG_PERSIST_TASK_EXISTED, "Log persist task is existed"},
|
|
+ {ERR_DOMAIN_INVALID, ("Invalid domain, domain should be in range (" + Uint2HexStr(DOMAIN_MIN)
|
|
+ + ", " +Uint2HexStr(DOMAIN_MAX) +"]")},
|
|
+ {ERR_MSG_LEN_INVALID, "Invalid message length"},
|
|
+ {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be in range [" + to_string(JOB_ID_MIN)
|
|
+ + ", " + to_string(JOB_ID_MAX) + ")"},
|
|
+ {ERR_BUFF_SIZE_INVALID, ("Invalid buffer size, buffer size should be in range [" + Size2Str(MIN_BUFFER_SIZE)
|
|
+ + ", " + Size2Str(MAX_BUFFER_SIZE) + "]")},
|
|
+ {ERR_COMMAND_INVALID, "Mutlti commands can't be used in combination"},
|
|
+ {ERR_LOG_FILE_NUM_INVALID, "Invalid number of files"},
|
|
+ {ERR_NOT_NUMBER_STR, "Not a numeric string"},
|
|
+ {ERR_TOO_MANY_ARGUMENTS, "Too many arguments"},
|
|
+ {ERR_DUPLICATE_OPTION, "Too many duplicate options"},
|
|
+ {ERR_INVALID_ARGUMENT, "Invalid argument"},
|
|
+ {ERR_TOO_MANY_DOMAINS, "Max domain count is " + to_string(MAX_DOMAINS)},
|
|
+ {ERR_INVALID_SIZE_STR, "Invalid size string"},
|
|
+ {ERR_TOO_MANY_PIDS, "Max pid count is " + to_string(MAX_PIDS)},
|
|
+ {ERR_TOO_MANY_TAGS, "Max tag count is " + to_string(MAX_TAGS)},
|
|
+ {ERR_TAG_STR_TOO_LONG, ("Tag string too long, max length is " + to_string(MAX_TAG_LEN - 1))},
|
|
+ {ERR_REGEX_STR_TOO_LONG, ("Regular expression too long, max length is " + to_string(MAX_REGEX_STR_LEN - 1))},
|
|
+ {ERR_FILE_NAME_TOO_LONG, ("File name too long, max length is " + to_string(MAX_FILE_NAME_LEN))},
|
|
+ {ERR_SOCKET_CLIENT_INIT_FAIL, "Socket client init failed"},
|
|
+ {ERR_SOCKET_WRITE_MSG_HEADER_FAIL, "Socket rite message header failed"},
|
|
+ {ERR_SOCKET_WRITE_CMD_FAIL, "Socket write command failed"},
|
|
+ {ERR_SOCKET_RECEIVE_RSP, "Unable to receive message from socket"},
|
|
+ {ERR_PERSIST_TASK_EMPTY, "No running persist task, please check"},
|
|
+ {ERR_JOBID_NOT_EXSIST, "Persist task of this job id doesn't exist, please check"},
|
|
+ {ERR_TOO_MANY_JOBS, ("Too many jobs are running, max job count is:" + to_string(MAX_JOBS))},
|
|
+ {ERR_STATS_NOT_ENABLE, "Statistic feature is not enable, "
|
|
+ "please set param persist.sys.hilog.stats true to enable it, "
|
|
+ "further more, you can set persist.sys.hilog.stats.tag true to enable counting log by tags"},
|
|
+ {ERR_NO_RUNNING_TASK, "No running persistent task"},
|
|
+ {ERR_NO_PID_PERMISSION, "Permission denied, only shell and root can filter logs by pid"},
|
|
+}, RET_FAIL, "Unknown error code");
|
|
+
|
|
+string ErrorCode2Str(int16_t errorCode)
|
|
+{
|
|
+ return g_ErrorMsgs.GetValue((uint16_t)errorCode) + " [CODE: " + to_string(errorCode) + "]";
|
|
+}
|
|
+
|
|
+// Log Types&Strings Map
|
|
+static const StringMap g_LogTypes({
|
|
+ {LOG_INIT, "init"}, {LOG_CORE, "core"}, {LOG_APP, "app"}, {LOG_KMSG, "kmsg"}
|
|
+}, LOG_TYPE_MAX, "invalid");
|
|
+
|
|
+string LogType2Str(uint16_t logType)
|
|
+{
|
|
+ return g_LogTypes.GetValue(logType);
|
|
+}
|
|
+
|
|
+uint16_t Str2LogType(const string& str)
|
|
+{
|
|
+ return g_LogTypes.GetKey(str);
|
|
+}
|
|
+
|
|
+string ComboLogType2Str(uint16_t shiftType)
|
|
+{
|
|
+ vector<uint16_t> types = g_LogTypes.GetAllKeys();
|
|
+ string str = "";
|
|
+ uint16_t typeAll = 0;
|
|
+
|
|
+ for (uint16_t t : types) {
|
|
+ typeAll |= (1 << t);
|
|
+ }
|
|
+ shiftType &= typeAll;
|
|
+ for (uint16_t t: types) {
|
|
+ if ((1 << t) & shiftType) {
|
|
+ shiftType &= (~(1 << t));
|
|
+ str += (LogType2Str(t) + (shiftType != 0 ? "," : ""));
|
|
+ }
|
|
+ if (shiftType == 0) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return str;
|
|
+}
|
|
+
|
|
+uint16_t Str2ComboLogType(const string& str)
|
|
+{
|
|
+ uint16_t logTypes = 0;
|
|
+ if (str == "") {
|
|
+ logTypes = (1 << LOG_CORE) | (1 << LOG_APP);
|
|
+ return logTypes;
|
|
+ }
|
|
+ vector<string> vec;
|
|
+ Split(str, vec);
|
|
+ for (auto& it : vec) {
|
|
+ if (it == "") {
|
|
+ continue;
|
|
+ }
|
|
+ uint16_t t = Str2LogType(it);
|
|
+ if (t == LOG_TYPE_MAX) {
|
|
+ return 0;
|
|
+ }
|
|
+ logTypes |= (1 << t);
|
|
+ }
|
|
+ return logTypes;
|
|
+}
|
|
+
|
|
+vector<uint16_t> GetAllLogTypes()
|
|
+{
|
|
+ return g_LogTypes.GetAllKeys();
|
|
+}
|
|
+
|
|
+// Log Levels&Strings Map
|
|
+static const StringMap g_LogLevels({
|
|
+ {LOG_DEBUG, "DEBUG"}, {LOG_INFO, "INFO"}, {LOG_WARN, "WARN"},
|
|
+ {LOG_ERROR, "ERROR"}, {LOG_FATAL, "FATAL"}, {LOG_LEVEL_MAX, "X"}
|
|
+}, LOG_LEVEL_MIN, "INVALID", [](const string& l1, const string& l2) {
|
|
+ if (l1.length() == l2.length()) {
|
|
+ return std::equal(l1.begin(), l1.end(), l2.begin(), [](char a, char b) {
|
|
+ return std::tolower(a) == std::tolower(b);
|
|
+ });
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+});
|
|
+
|
|
+string LogLevel2Str(uint16_t logLevel)
|
|
+{
|
|
+ return g_LogLevels.GetValue(logLevel);
|
|
+}
|
|
+
|
|
+uint16_t Str2LogLevel(const string& str)
|
|
+{
|
|
+ return g_LogLevels.GetKey(str);
|
|
+}
|
|
+
|
|
+// Log Levels&Short Strings Map
|
|
+static const StringMap g_ShortLogLevels({
|
|
+ {LOG_DEBUG, "D"}, {LOG_INFO, "I"}, {LOG_WARN, "W"},
|
|
+ {LOG_ERROR, "E"}, {LOG_FATAL, "F"}, {LOG_LEVEL_MAX, "X"}
|
|
+}, LOG_LEVEL_MIN, "V", [](const string& l1, const string& l2) {
|
|
+ return (l1.length() == 1 && std::tolower(l1[0]) == std::tolower(l2[0]));
|
|
+});
|
|
+
|
|
+string LogLevel2ShortStr(uint16_t logLevel)
|
|
+{
|
|
+ return g_ShortLogLevels.GetValue(logLevel);
|
|
+}
|
|
+
|
|
+uint16_t ShortStr2LogLevel(const string& str)
|
|
+{
|
|
+ return g_ShortLogLevels.GetKey(str);
|
|
+}
|
|
+
|
|
+uint16_t PrettyStr2LogLevel(const string& str)
|
|
+{
|
|
+ uint16_t level = ShortStr2LogLevel(str);
|
|
+ if (level == static_cast<uint16_t>(LOG_LEVEL_MIN)) {
|
|
+ return Str2LogLevel(str);
|
|
+ }
|
|
+ return level;
|
|
+}
|
|
+
|
|
+string ComboLogLevel2Str(uint16_t shiftLevel)
|
|
+{
|
|
+ vector<uint16_t> levels = g_ShortLogLevels.GetAllKeys();
|
|
+ string str = "";
|
|
+ uint16_t levelAll = 0;
|
|
+
|
|
+ for (uint16_t l : levels) {
|
|
+ levelAll |= (1 << l);
|
|
+ }
|
|
+ shiftLevel &= levelAll;
|
|
+ for (uint16_t l: levels) {
|
|
+ if ((1 << l) & shiftLevel) {
|
|
+ shiftLevel &= (~(1 << l));
|
|
+ str += (LogLevel2Str(l) + (shiftLevel != 0 ? "," : ""));
|
|
+ }
|
|
+ if (shiftLevel == 0) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return str;
|
|
+}
|
|
+
|
|
+uint16_t Str2ComboLogLevel(const string& str)
|
|
+{
|
|
+ uint16_t logLevels = 0;
|
|
+ if (str == "") {
|
|
+ logLevels = 0xFFFF;
|
|
+ return logLevels;
|
|
+ }
|
|
+ vector<string> vec;
|
|
+ Split(str, vec);
|
|
+ for (auto& it : vec) {
|
|
+ if (it == "") {
|
|
+ continue;
|
|
+ }
|
|
+ uint16_t t = PrettyStr2LogLevel(it);
|
|
+ if (t == LOG_LEVEL_MIN || t >= LOG_LEVEL_MAX) {
|
|
+ return 0;
|
|
+ }
|
|
+ logLevels |= (1 << t);
|
|
+ }
|
|
+ return logLevels;
|
|
+}
|
|
+
|
|
+void Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator)
|
|
+{
|
|
+ std::string str = src;
|
|
+ std::string substring;
|
|
+ std::string::size_type start = 0;
|
|
+ std::string::size_type index;
|
|
+ dest.clear();
|
|
+ index = str.find_first_of(separator, start);
|
|
+ if (index == std::string::npos) {
|
|
+ dest.emplace_back(str);
|
|
+ return;
|
|
+ }
|
|
+ do {
|
|
+ substring = str.substr(start, index - start);
|
|
+ dest.emplace_back(substring);
|
|
+ start = index + separator.size();
|
|
+ index = str.find(separator, start);
|
|
+ } while (index != std::string::npos);
|
|
+ substring = str.substr(start);
|
|
+ if (substring != "") {
|
|
+ dest.emplace_back(substring);
|
|
+ }
|
|
+}
|
|
+
|
|
+uint32_t GetBitsCount(uint64_t n)
|
|
+{
|
|
+ uint32_t count = 0;
|
|
+ while (n != 0) {
|
|
+ ++count;
|
|
+ n = n & (n-1);
|
|
+ }
|
|
+ return count;
|
|
+}
|
|
+
|
|
+uint16_t GetBitPos(uint64_t n)
|
|
+{
|
|
+ if (!(n && (!(n & (n-1))))) { // only accpet the number which is power of 2
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ uint16_t i = 0;
|
|
+ while (n >> (i++)) {}
|
|
+ i--;
|
|
+ return i-1;
|
|
+}
|
|
+
|
|
+enum class Radix {
|
|
+ RADIX_DEC,
|
|
+ RADIX_HEX,
|
|
+};
|
|
+template<typename T>
|
|
+static string Num2Str(T num, Radix radix)
|
|
+{
|
|
+ stringstream ss;
|
|
+ auto r = std::dec;
|
|
+ if (radix == Radix::RADIX_HEX) {
|
|
+ r = std::hex;
|
|
+ }
|
|
+ ss << r << num;
|
|
+ return ss.str();
|
|
+}
|
|
+
|
|
+template<typename T>
|
|
+static void Str2Num(const string& str, T& num, Radix radix)
|
|
+{
|
|
+ T i = 0;
|
|
+ std::stringstream ss;
|
|
+ auto r = std::dec;
|
|
+ if (radix == Radix::RADIX_HEX) {
|
|
+ r = std::hex;
|
|
+ }
|
|
+ ss << r << str;
|
|
+ ss >> i;
|
|
+ num = i;
|
|
+ return;
|
|
+}
|
|
+
|
|
+string Uint2DecStr(uint32_t i)
|
|
+{
|
|
+ return Num2Str(i, Radix::RADIX_DEC);
|
|
+}
|
|
+
|
|
+uint32_t DecStr2Uint(const string& str)
|
|
+{
|
|
+ uint32_t i = 0;
|
|
+ Str2Num(str, i, Radix::RADIX_DEC);
|
|
+ return i;
|
|
+}
|
|
+
|
|
+string Uint2HexStr(uint32_t i)
|
|
+{
|
|
+ return Num2Str(i, Radix::RADIX_HEX);
|
|
+}
|
|
+
|
|
+uint32_t HexStr2Uint(const string& str)
|
|
+{
|
|
+ uint32_t i = 0;
|
|
+ Str2Num(str, i, Radix::RADIX_HEX);
|
|
+ return i;
|
|
+}
|
|
+
|
|
+#if !defined(__WINDOWS__) and !defined(__LINUX__)
|
|
+string GetProgName()
|
|
+{
|
|
+#ifdef HILOG_USE_MUSL
|
|
+ return program_invocation_short_name;
|
|
+#else
|
|
+ return getprogname();
|
|
+#endif
|
|
+}
|
|
+#endif
|
|
+
|
|
+string GetNameByPid(uint32_t pid)
|
|
+{
|
|
+ char path[CMDLINE_PATH_LEN] = { 0 };
|
|
+ if (snprintf_s(path, CMDLINE_PATH_LEN, CMDLINE_PATH_LEN - 1, "/proc/%d/cmdline", pid) <= 0) {
|
|
+ return "";
|
|
+ }
|
|
+ char cmdline[CMDLINE_LEN] = { 0 };
|
|
+ int i = 0;
|
|
+ FILE *fp = fopen(path, "r");
|
|
+ if (fp == nullptr) {
|
|
+ return "";
|
|
+ }
|
|
+ while (i < (CMDLINE_LEN - 1)) {
|
|
+ char c = static_cast<char>(fgetc(fp));
|
|
+ // 0. don't need args of cmdline
|
|
+ // 1. ignore unvisible character
|
|
+ if (!isgraph(c)) {
|
|
+ break;
|
|
+ }
|
|
+ cmdline[i] = c;
|
|
+ i++;
|
|
+ }
|
|
+ (void)fclose(fp);
|
|
+ return cmdline;
|
|
+}
|
|
+
|
|
+uint32_t GetPPidByPid(uint32_t pid)
|
|
+{
|
|
+ uint32_t ppid = 0;
|
|
+ char path[STATUS_PATH_LEN] = { 0 };
|
|
+ if (snprintf_s(path, STATUS_PATH_LEN, STATUS_PATH_LEN - 1, "/proc/%u/status", pid) <= 0) {
|
|
+ return ppid;
|
|
+ }
|
|
+ FILE *fp = fopen(path, "r");
|
|
+ if (fp == nullptr) {
|
|
+ return ppid;
|
|
+ }
|
|
+ char buf[STATUS_LEN] = { 0 };
|
|
+ size_t ret = fread(buf, sizeof(char), STATUS_LEN - 1, fp);
|
|
+ (void)fclose(fp);
|
|
+ if (ret <= 0) {
|
|
+ return ppid;
|
|
+ } else {
|
|
+ buf[ret++] = '\0';
|
|
+ }
|
|
+ char *ppidLoc = strstr(buf, "PPid:");
|
|
+ if ((ppidLoc == nullptr) || (sscanf_s(ppidLoc, "PPid:%d", &ppid) == -1)) {
|
|
+ return ppid;
|
|
+ }
|
|
+ std::string ppidName = GetNameByPid(ppid);
|
|
+ // ppid fork the sh to execute hilog, sh is not wanted ppid
|
|
+ if (std::find(std::begin(SH_NAMES), std::end(SH_NAMES), ppidName) != std::end(SH_NAMES)) {
|
|
+ return GetPPidByPid(ppid);
|
|
+ }
|
|
+ return ppid;
|
|
+}
|
|
+
|
|
+uint64_t GenerateHash(const char *p, size_t size)
|
|
+{
|
|
+ static const uint64_t PRIME = 0x100000001B3ull;
|
|
+ static const uint64_t BASIS = 0xCBF29CE484222325ull;
|
|
+ uint64_t ret {BASIS};
|
|
+ unsigned long i = 0;
|
|
+ while (i < size) {
|
|
+ ret ^= *(p + i);
|
|
+ ret *= PRIME;
|
|
+ i++;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+void PrintErrorno(int err)
|
|
+{
|
|
+ constexpr int bufSize = 256;
|
|
+ char buf[bufSize] = { 0 };
|
|
+#ifndef __WINDOWS__
|
|
+ (void)strerror_r(err, buf, bufSize);
|
|
+#else
|
|
+ (void)strerror_s(buf, bufSize, err);
|
|
+#endif
|
|
+ std::cerr << "Errno: " << err << ", " << buf << std::endl;
|
|
+}
|
|
+
|
|
+int WaitingToDo(int max, const string& path, function<int(const string &path)> func)
|
|
+{
|
|
+ chrono::steady_clock::time_point start = chrono::steady_clock::now();
|
|
+ chrono::milliseconds wait(max);
|
|
+ while (true) {
|
|
+ if (func(path) != RET_FAIL) {
|
|
+ cout << "waiting for " << path << " successfully!" << endl;
|
|
+ return RET_SUCCESS;
|
|
+ }
|
|
+
|
|
+ std::this_thread::sleep_for(10ms);
|
|
+ if ((chrono::steady_clock::now() - start) > wait) {
|
|
+ cerr << "waiting for " << path << " failed!" << endl;
|
|
+ return RET_FAIL;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+} // namespace HiviewDFX
|
|
+} // namespace OHOS
|
|
diff --git a/frameworks/libhilog/vsnprintf/include/output_p.inl b/frameworks/libhilog/vsnprintf/include/output_p.inl
|
|
new file mode 100644
|
|
index 0000000..d58873b
|
|
--- /dev/null
|
|
+++ b/frameworks/libhilog/vsnprintf/include/output_p.inl
|
|
@@ -0,0 +1,1294 @@
|
|
+/*
|
|
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+
|
|
+/* [Standardize-exceptions] Use unsafe function: Portability
|
|
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
|
|
+ * And sufficient input validation is performed before calling
|
|
+ */
|
|
+
|
|
+#ifndef OUTPUT_P_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5
|
|
+#define OUTPUT_P_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5
|
|
+
|
|
+#define SECUREC_FLOAT_BUFSIZE (309+40) /* max float point value */
|
|
+#define SECUREC_FLOAT_BUFSIZE_LB (4932+40) /* max long double value */
|
|
+
|
|
+#define SECUREC_INT_MAX 2147483647
|
|
+
|
|
+#define SECUREC_MUL10(x) ((((x) << 2) + (x)) << 1)
|
|
+#define SECUREC_INT_MAX_DIV_TEN 21474836
|
|
+#define SECUREC_MUL10_ADD_BEYOND_MAX(val) (((val) > SECUREC_INT_MAX_DIV_TEN))
|
|
+
|
|
+#ifdef SECUREC_STACK_SIZE_LESS_THAN_1K
|
|
+#define SECUREC_FMT_STR_LEN (8)
|
|
+#else
|
|
+#define SECUREC_FMT_STR_LEN (16)
|
|
+#endif
|
|
+
|
|
+typedef struct {
|
|
+ unsigned int flags;
|
|
+ int fldWidth;
|
|
+ int precision;
|
|
+ int bufferIsWide; /* flag for buffer contains wide chars */
|
|
+ int dynWidth; /* %* 1 width from variable parameter ;0 not */
|
|
+ int dynPrecision; /* %.* 1 precision from variable parameter ;0 not */
|
|
+} SecFormatAttr;
|
|
+
|
|
+typedef union {
|
|
+ char *str; /* not a null terminated string */
|
|
+ wchar_t *wStr;
|
|
+} SecFormatBuf;
|
|
+
|
|
+typedef union {
|
|
+ char str[SECUREC_BUFFER_SIZE + 1];
|
|
+#ifdef SECUREC_FOR_WCHAR
|
|
+ wchar_t wStr[SECUREC_BUFFER_SIZE + 1];
|
|
+#endif
|
|
+} SecBuffer;
|
|
+
|
|
+static int SecIndirectSprintf(char *strDest, const char *format, ...)
|
|
+{
|
|
+ int ret; /* If initialization causes e838 */
|
|
+ va_list arglist;
|
|
+
|
|
+ va_start(arglist, format);
|
|
+ SECUREC_MASK_MSVC_CRT_WARNING
|
|
+ ret = vsprintf(strDest, format, arglist);
|
|
+ SECUREC_END_MASK_MSVC_CRT_WARNING
|
|
+ va_end(arglist);
|
|
+ (void)arglist; /* to clear e438 last value assigned not used , the compiler will optimize this code */
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+/* to clear e506 warning */
|
|
+static int SecIsSameSize(size_t sizeA, size_t sizeB)
|
|
+{
|
|
+ return sizeA == sizeB;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#define SECUREC_SPECIAL(_val, Base) \
|
|
+ case Base: \
|
|
+ do { \
|
|
+ *--formatBuf.str = digits[_val % Base]; \
|
|
+ }while ((_val /= Base) != 0)
|
|
+
|
|
+#define SECUREC_SAFE_WRITE_PREFIX(src, txtLen, _stream, outChars) do { \
|
|
+ for (ii = 0; ii < txtLen; ++ii) { \
|
|
+ *((SecChar *)(void *)(_stream->cur)) = *(src); \
|
|
+ _stream->cur += sizeof(SecChar); \
|
|
+ ++(src); \
|
|
+ } \
|
|
+ _stream->count -= txtLen * (int)(sizeof(SecChar)); \
|
|
+ *(outChars) = *(outChars) + (txtLen); \
|
|
+ } SECUREC_WHILE_ZERO
|
|
+
|
|
+#define SECUREC_SAFE_WRITE_STR(src, txtLen, _stream, outChars) do { \
|
|
+ if (txtLen < 12 /* for mobile number length */) { \
|
|
+ for (ii = 0; ii < txtLen; ++ii) { \
|
|
+ *((SecChar *)(void *)(_stream->cur)) = *(src); \
|
|
+ _stream->cur += sizeof(SecChar); \
|
|
+ ++(src); \
|
|
+ } \
|
|
+ } else { \
|
|
+ (void)memcpy(_stream->cur, src, ((size_t)(unsigned int)txtLen * (sizeof(SecChar)))); \
|
|
+ _stream->cur += (size_t)(unsigned int)txtLen * (sizeof(SecChar)); \
|
|
+ } \
|
|
+ _stream->count -= txtLen * (int)(sizeof(SecChar)); \
|
|
+ *(outChars) = *(outChars) + (txtLen); \
|
|
+ } SECUREC_WHILE_ZERO
|
|
+
|
|
+#define SECUREC_SAFE_WRITE_CHAR(_ch, _stream, outChars) do { \
|
|
+ *((SecChar *)(void *)(_stream->cur)) = (SecChar)_ch; \
|
|
+ _stream->cur += sizeof(SecChar); \
|
|
+ _stream->count -= (int)(sizeof(SecChar)); \
|
|
+ *(outChars) = *(outChars) + 1; \
|
|
+ } SECUREC_WHILE_ZERO
|
|
+
|
|
+#define SECUREC_SAFE_PADDING(padChar, padLen, _stream, outChars) do { \
|
|
+ for (ii = 0; ii < padLen; ++ii) { \
|
|
+ *((SecChar *)(void *)(_stream->cur)) = (SecChar)padChar; \
|
|
+ _stream->cur += sizeof(SecChar); \
|
|
+ } \
|
|
+ _stream->count -= padLen * (int)(sizeof(SecChar)); \
|
|
+ *(outChars) = *(outChars) + (padLen); \
|
|
+ } SECUREC_WHILE_ZERO
|
|
+
|
|
+/* The count variable can be reduced to 0, and the external function complements the \0 terminator. */
|
|
+#define SECUREC_IS_REST_BUF_ENOUGH(needLen) ((int)(stream->count - (int)needLen * (int)(sizeof(SecChar))) >= 0)
|
|
+
|
|
+#define SECUREC_FMT_STATE_OFFSET 256
|
|
+#ifdef SECUREC_FOR_WCHAR
|
|
+#define SECUREC_FMT_TYPE(c, fmtTable) ((((unsigned int)(int)(c)) <= (unsigned int)(int)SECUREC_CHAR('~')) ? \
|
|
+ (fmtTable[(unsigned char)(c)]) : 0)
|
|
+#define SECUREC_DECODE_STATE(c, fmtTable, laststate) (SecFmtState)(((fmtTable[(SECUREC_FMT_TYPE(c,fmtTable)) * \
|
|
+ ((unsigned char)STAT_INVALID + 1) + \
|
|
+ (unsigned char)(laststate) + \
|
|
+ SECUREC_FMT_STATE_OFFSET])))
|
|
+#else
|
|
+#define SECUREC_DECODE_STATE(c,fmtTable,laststate) (SecFmtState)((fmtTable[(fmtTable[(unsigned char)(c)]) * \
|
|
+ ((unsigned char)STAT_INVALID + 1) + \
|
|
+ (unsigned char)(laststate) + \
|
|
+ SECUREC_FMT_STATE_OFFSET]))
|
|
+#endif
|
|
+
|
|
+#define PUBLIC_FLAG_LEN 8
|
|
+#define PRIVATE_FLAG_LEN 9
|
|
+#define PUBLIC_FLAG "{public}"
|
|
+#define PRIVATE_FLAG "{private}"
|
|
+
|
|
+static void SecWritePrivateStr(SecPrintfStream *stream, int *pCharsOut)
|
|
+{
|
|
+ int ii = 0;
|
|
+#define PRIVATE_STR_LEN (9)
|
|
+#ifndef SECUREC_FOR_WCHAR
|
|
+ static const char privacyString[] = "<private>";
|
|
+ const char *pPrivStr = privacyString;
|
|
+
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(PRIVATE_STR_LEN)) {
|
|
+ SECUREC_SAFE_WRITE_STR(pPrivStr, PRIVATE_STR_LEN, stream, pCharsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_STRING(pPrivStr, PRIVATE_STR_LEN, stream, pCharsOut);
|
|
+ }
|
|
+#else
|
|
+ static const wchar_t wprivacyString[] = { L'<', L'p', L'r', L'i', L'v', L'a', L't', L'e', L'>', L'\0' };
|
|
+ const wchar_t *pwPrivStr = wprivacyString;
|
|
+
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(PRIVATE_STR_LEN)) {
|
|
+ SECUREC_SAFE_WRITE_STR(pwPrivStr, PRIVATE_STR_LEN, stream, pCharsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_STRING(pwPrivStr, PRIVATE_STR_LEN, stream, pCharsOut);
|
|
+ }
|
|
+#endif
|
|
+}
|
|
+
|
|
+static void SecDecodeFlags(SecChar ch, SecFormatAttr *attr)
|
|
+{
|
|
+ switch (ch) {
|
|
+ case SECUREC_CHAR(' '):
|
|
+ attr->flags |= SECUREC_FLAG_SIGN_SPACE;
|
|
+ break;
|
|
+ case SECUREC_CHAR('+'):
|
|
+ attr->flags |= SECUREC_FLAG_SIGN;
|
|
+ break;
|
|
+ case SECUREC_CHAR('-'):
|
|
+ attr->flags |= SECUREC_FLAG_LEFT;
|
|
+ break;
|
|
+ case SECUREC_CHAR('0'):
|
|
+ attr->flags |= SECUREC_FLAG_LEADZERO; /* add zero th the front */
|
|
+ break;
|
|
+ case SECUREC_CHAR('#'):
|
|
+ attr->flags |= SECUREC_FLAG_ALTERNATE; /* output %x with 0x */
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ return;
|
|
+}
|
|
+
|
|
+static int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format)
|
|
+{
|
|
+ switch (ch) {
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+ case SECUREC_CHAR('j'):
|
|
+ attr->flags |= SECUREC_FLAG_INTMAX;
|
|
+ break;
|
|
+#endif
|
|
+ case SECUREC_CHAR('q'): [[fallthrough]];
|
|
+ case SECUREC_CHAR('L'):
|
|
+ attr->flags |= SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE;
|
|
+ break;
|
|
+ case SECUREC_CHAR('l'):
|
|
+ if (**format == SECUREC_CHAR('l')) {
|
|
+ ++(*format);
|
|
+ attr->flags |= SECUREC_FLAG_LONGLONG; /* long long */
|
|
+ } else {
|
|
+ attr->flags |= SECUREC_FLAG_LONG; /* long int or wchar_t */
|
|
+ }
|
|
+ break;
|
|
+ case SECUREC_CHAR('t'):
|
|
+ attr->flags |= SECUREC_FLAG_PTRDIFF;
|
|
+ break;
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+ case SECUREC_CHAR('z'):
|
|
+ attr->flags |= SECUREC_FLAG_SIZE;
|
|
+ break;
|
|
+ case SECUREC_CHAR('Z'):
|
|
+ attr->flags |= SECUREC_FLAG_SIZE;
|
|
+ break;
|
|
+#endif
|
|
+
|
|
+ case SECUREC_CHAR('I'):
|
|
+#ifdef SECUREC_ON_64BITS
|
|
+ attr->flags |= SECUREC_FLAG_I64; /* %I to INT64 */
|
|
+#endif
|
|
+ if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) {
|
|
+ (*format) += 2;
|
|
+ attr->flags |= SECUREC_FLAG_I64; /* %I64 to INT64 */
|
|
+ } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) {
|
|
+ (*format) += 2;
|
|
+ attr->flags &= ~SECUREC_FLAG_I64; /* %I64 to INT32 */
|
|
+ } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) ||
|
|
+ (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) ||
|
|
+ (**format == SECUREC_CHAR('x')) || (**format == SECUREC_CHAR('X'))) {
|
|
+ /* do nothing */
|
|
+ } else {
|
|
+ /* Compatibility code for "%I" just print I */
|
|
+ return -1;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case SECUREC_CHAR('h'):
|
|
+ if (**format == SECUREC_CHAR('h'))
|
|
+ attr->flags |= SECUREC_FLAG_CHAR; /* char */
|
|
+ else
|
|
+ attr->flags |= SECUREC_FLAG_SHORT; /* short int */
|
|
+ break;
|
|
+
|
|
+ case SECUREC_CHAR('w'):
|
|
+ attr->flags |= SECUREC_FLAG_WIDECHAR; /* wide char */
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int SecDecodeTypeC(SecFormatAttr *attr, unsigned int cValue, SecFormatBuf *formatBuf, SecBuffer *buffer)
|
|
+{
|
|
+ int textLen;
|
|
+ wchar_t wchar;
|
|
+
|
|
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS))
|
|
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
|
|
+#endif
|
|
+
|
|
+#ifdef SECUREC_FOR_WCHAR
|
|
+ attr->bufferIsWide = 1;
|
|
+ wchar = (wchar_t)cValue;
|
|
+ if (attr->flags & SECUREC_FLAG_SHORT) {
|
|
+ /* multibyte character to wide character */
|
|
+ char tempchar[2];
|
|
+ tempchar[0] = (char)(wchar & 0x00ff);
|
|
+ tempchar[1] = '\0';
|
|
+
|
|
+ if (mbtowc(buffer->wStr, tempchar, sizeof(tempchar)) < 0) {
|
|
+ return -1;
|
|
+ }
|
|
+ } else {
|
|
+ buffer->wStr[0] = wchar;
|
|
+ }
|
|
+ formatBuf->wStr = buffer->wStr;
|
|
+ textLen = 1; /* only 1 wide character */
|
|
+#else
|
|
+ attr->bufferIsWide = 0;
|
|
+ if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
|
|
+ wchar = (wchar_t)cValue;
|
|
+ /* wide character to multibyte character */
|
|
+ SECUREC_MASK_MSVC_CRT_WARNING
|
|
+ textLen = wctomb(buffer->str, wchar);
|
|
+ SECUREC_END_MASK_MSVC_CRT_WARNING
|
|
+ if (textLen < 0) {
|
|
+ return -1;
|
|
+ }
|
|
+ } else {
|
|
+ /* get multibyte character from argument */
|
|
+ unsigned short temp;
|
|
+ temp = (unsigned short)cValue;
|
|
+ buffer->str[0] = (char)temp;
|
|
+ textLen = 1;
|
|
+ }
|
|
+ formatBuf->str = buffer->str;
|
|
+#endif
|
|
+
|
|
+ return textLen;
|
|
+}
|
|
+
|
|
+static int SecDecodeTypeS(SecFormatAttr *attr, char *argPtr, SecFormatBuf *formatBuf)
|
|
+{
|
|
+ /* literal string to print null ptr, define it on stack rather than const text area
|
|
+ is to avoid gcc warning with pointing const text with variable */
|
|
+ static char strNullString[8] = "(null)";
|
|
+ static wchar_t wStrNullString[8] = { L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0' };
|
|
+
|
|
+ int finalPrecision;
|
|
+ char *strEnd = NULL;
|
|
+ wchar_t *wStrEnd = NULL;
|
|
+ int textLen;
|
|
+
|
|
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && (!defined(SECUREC_ON_UNIX))
|
|
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
|
|
+#endif
|
|
+ finalPrecision = (attr->precision == -1) ? SECUREC_INT_MAX : attr->precision;
|
|
+ formatBuf->str = argPtr;
|
|
+
|
|
+#ifdef SECUREC_FOR_WCHAR
|
|
+#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
|
|
+ if (!(attr->flags & SECUREC_FLAG_LONG)) {
|
|
+ attr->flags |= SECUREC_FLAG_SHORT;
|
|
+ }
|
|
+#endif
|
|
+ if (attr->flags & SECUREC_FLAG_SHORT) {
|
|
+ if (formatBuf->str == NULL) { /* NULL passed, use special string */
|
|
+ formatBuf->str = strNullString;
|
|
+ }
|
|
+ strEnd = formatBuf->str;
|
|
+ for (textLen = 0; textLen < finalPrecision && *strEnd; textLen++) {
|
|
+ ++strEnd;
|
|
+ }
|
|
+ /* textLen now contains length in multibyte chars */
|
|
+ } else {
|
|
+ if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
|
|
+ formatBuf->wStr = wStrNullString;
|
|
+ }
|
|
+ attr->bufferIsWide = 1;
|
|
+ wStrEnd = formatBuf->wStr;
|
|
+ while (finalPrecision-- && *wStrEnd) {
|
|
+ ++wStrEnd;
|
|
+ }
|
|
+ textLen = (int)(wStrEnd - formatBuf->wStr); /* in wchar_ts */
|
|
+ /* textLen now contains length in wide chars */
|
|
+ }
|
|
+#else /* SECUREC_FOR_WCHAR */
|
|
+ if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
|
|
+ if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
|
|
+ formatBuf->wStr = wStrNullString;
|
|
+ }
|
|
+ attr->bufferIsWide = 1;
|
|
+ wStrEnd = formatBuf->wStr;
|
|
+ while (finalPrecision-- && *wStrEnd) {
|
|
+ ++wStrEnd;
|
|
+ }
|
|
+ textLen = (int)(wStrEnd - formatBuf->wStr);
|
|
+ } else {
|
|
+ if (formatBuf->str == NULL) { /* meet NULL, use special string */
|
|
+ formatBuf->str = strNullString;
|
|
+ }
|
|
+
|
|
+ if (finalPrecision == SECUREC_INT_MAX) {
|
|
+ /* precision NOT assigned */
|
|
+ /* The strlen performance is high when the string length is greater than 32 */
|
|
+ textLen = (int)strlen(formatBuf->str);
|
|
+ } else {
|
|
+ /* precision assigned */
|
|
+ strEnd = formatBuf->str;
|
|
+ while (finalPrecision-- && *strEnd) {
|
|
+ ++strEnd;
|
|
+ }
|
|
+ textLen = (int)(strEnd - formatBuf->str); /* length of the string */
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+#endif /* SECUREC_FOR_WCHAR */
|
|
+ return textLen;
|
|
+}
|
|
+
|
|
+HILOG_LOCAL_API
|
|
+int SecOutputPS(SecPrintfStream *stream, int priv, const char *cformat, va_list arglist)
|
|
+{
|
|
+ const SecChar *format = cformat;
|
|
+
|
|
+ char *floatBuf = NULL;
|
|
+ SecFormatBuf formatBuf;
|
|
+ static const char *itoaUpperDigits = "0123456789ABCDEFX";
|
|
+ static const char *itoaLowerDigits = "0123456789abcdefx";
|
|
+ const char *digits = itoaUpperDigits;
|
|
+ int ii = 0;
|
|
+
|
|
+ unsigned int radix;
|
|
+ int charsOut; /* characters written */
|
|
+
|
|
+ int prefixLen = 0;
|
|
+ int padding = 0;
|
|
+
|
|
+ int textLen; /* length of the text */
|
|
+ int bufferSize = 0; /* size of formatBuf.str */
|
|
+ int noOutput = 0;
|
|
+
|
|
+ SecFmtState state;
|
|
+ SecFmtState laststate;
|
|
+
|
|
+ SecChar prefix[2] = { 0 };
|
|
+ SecChar ch; /* currently read character */
|
|
+
|
|
+ static const unsigned char fmtCharTable[337] = {
|
|
+ /* type 0: nospecial meaning;
|
|
+ 1: '%';
|
|
+ 2: '.'
|
|
+ 3: '*'
|
|
+ 4: '0'
|
|
+ 5: '1' ... '9'
|
|
+ 6: ' ', '+', '-', '#'
|
|
+ 7: 'h', 'l', 'L', 'F', 'w' , 'N','z','q','t','j'
|
|
+ 8: 'd','o','u','i','x','X','e','f','g'
|
|
+ */
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00,
|
|
+ 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08,
|
|
+ 0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ /* fill zero for normal char 128 byte for 0x80 - 0xff */
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
+ /* state 0: normal
|
|
+ 1: percent
|
|
+ 2: flag
|
|
+ 3: width
|
|
+ 4: dot
|
|
+ 5: precis
|
|
+ 6: size
|
|
+ 7: type
|
|
+ 8: invalid
|
|
+ */
|
|
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
|
|
+ 0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05,
|
|
+ 0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03,
|
|
+ 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
|
|
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00,
|
|
+ 0x00
|
|
+ };
|
|
+
|
|
+ SecFormatAttr formatAttr;
|
|
+ SecBuffer buffer;
|
|
+ formatAttr.flags = 0;
|
|
+ formatAttr.bufferIsWide = 0; /* flag for buffer contains wide chars */
|
|
+ formatAttr.fldWidth = 0;
|
|
+ formatAttr.precision = 0;
|
|
+ formatAttr.dynWidth = 0;
|
|
+ formatAttr.dynPrecision = 0;
|
|
+
|
|
+ charsOut = 0;
|
|
+ textLen = 0;
|
|
+ state = STAT_NORMAL; /* starting state */
|
|
+ formatBuf.str = NULL;
|
|
+
|
|
+ int isPrivacy = 1; /*whether show private string*/
|
|
+
|
|
+ /* loop each format character */
|
|
+ /* remove format != NULL */
|
|
+ while ((ch = *format++) != SECUREC_CHAR('\0') && charsOut >= 0) {
|
|
+ laststate = state;
|
|
+ state = SECUREC_DECODE_STATE(ch, fmtCharTable, laststate);
|
|
+
|
|
+ switch (state) {
|
|
+ case STAT_NORMAL:
|
|
+
|
|
+NORMAL_CHAR:
|
|
+
|
|
+ /* normal state, write character */
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(1 /* only one char */ )) {
|
|
+ SECUREC_SAFE_WRITE_CHAR(ch, stream, &charsOut); /* char * cast to wchar * */
|
|
+ } else {
|
|
+#ifdef SECUREC_FOR_WCHAR
|
|
+ SECUREC_WRITE_CHAR(ch, stream, &charsOut);
|
|
+#else
|
|
+ /* optimize function call to code */
|
|
+ charsOut = -1;
|
|
+ stream->count = -1;
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ continue;
|
|
+
|
|
+ case STAT_PERCENT:
|
|
+ /* set default values */
|
|
+ prefixLen = 0;
|
|
+ noOutput = 0;
|
|
+ formatAttr.flags = 0;
|
|
+ formatAttr.fldWidth = 0;
|
|
+ formatAttr.precision = -1;
|
|
+ formatAttr.bufferIsWide = 0;
|
|
+ if (*format == SECUREC_CHAR('{')) {
|
|
+ if (strncmp(format, PUBLIC_FLAG, PUBLIC_FLAG_LEN) == 0) {
|
|
+ isPrivacy = 0;
|
|
+ format += PUBLIC_FLAG_LEN;
|
|
+ }
|
|
+ else if (strncmp(format, PRIVATE_FLAG, PRIVATE_FLAG_LEN) == 0) {
|
|
+ isPrivacy = 1;
|
|
+ format += PRIVATE_FLAG_LEN;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ isPrivacy = 1;
|
|
+ }
|
|
+
|
|
+ if (0 == priv) {
|
|
+ isPrivacy = 0;
|
|
+ }
|
|
+
|
|
+ break;
|
|
+
|
|
+ case STAT_FLAG:
|
|
+ /* set flag based on which flag character */
|
|
+ SecDecodeFlags(ch, &formatAttr);
|
|
+ break;
|
|
+
|
|
+ case STAT_WIDTH:
|
|
+ /* update width value */
|
|
+ if (ch == SECUREC_CHAR('*')) {
|
|
+ /* get width */
|
|
+ formatAttr.fldWidth = (int)va_arg(arglist, int);
|
|
+ if (formatAttr.fldWidth < 0) {
|
|
+ formatAttr.flags |= SECUREC_FLAG_LEFT;
|
|
+ formatAttr.fldWidth = -formatAttr.fldWidth;
|
|
+ }
|
|
+ formatAttr.dynWidth = 1;
|
|
+ } else {
|
|
+ if (laststate != STAT_WIDTH) {
|
|
+ formatAttr.fldWidth = 0;
|
|
+ }
|
|
+ if (SECUREC_MUL10_ADD_BEYOND_MAX(formatAttr.fldWidth)) {
|
|
+ return -1;
|
|
+ }
|
|
+ formatAttr.fldWidth = (int)SECUREC_MUL10((unsigned int)formatAttr.fldWidth) + (ch - SECUREC_CHAR('0'));
|
|
+ formatAttr.dynWidth = 0;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case STAT_DOT:
|
|
+ formatAttr.precision = 0;
|
|
+ break;
|
|
+
|
|
+ case STAT_PRECIS:
|
|
+ /* update precision value */
|
|
+ if (ch == SECUREC_CHAR('*')) {
|
|
+ /* get precision from arg list */
|
|
+ formatAttr.precision = (int)va_arg(arglist, int);
|
|
+ if (formatAttr.precision < 0) {
|
|
+ formatAttr.precision = -1;
|
|
+ }
|
|
+ formatAttr.dynPrecision = 1;
|
|
+ } else {
|
|
+ /* add digit to current precision */
|
|
+ if (SECUREC_MUL10_ADD_BEYOND_MAX(formatAttr.precision)) {
|
|
+ return -1;
|
|
+ }
|
|
+ formatAttr.precision =
|
|
+ (int)SECUREC_MUL10((unsigned int)formatAttr.precision) + (ch - SECUREC_CHAR('0'));
|
|
+ formatAttr.dynPrecision = 0;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case STAT_SIZE:
|
|
+ /* read a size specifier, set the formatAttr.flags based on it */
|
|
+ if (SecDecodeSize(ch, &formatAttr, &format) != 0) {
|
|
+ /* Compatibility code for "%I" just print I */
|
|
+ state = STAT_NORMAL;
|
|
+ goto NORMAL_CHAR;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case STAT_TYPE:
|
|
+
|
|
+ switch (ch) {
|
|
+
|
|
+ case SECUREC_CHAR('C'):
|
|
+ /* wide char */
|
|
+ if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
|
|
+
|
|
+#ifdef SECUREC_FOR_WCHAR
|
|
+ formatAttr.flags |= SECUREC_FLAG_SHORT;
|
|
+#else
|
|
+ formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
|
|
+#endif
|
|
+ }
|
|
+ [[fallthrough]];
|
|
+ case SECUREC_CHAR('c'):
|
|
+ {
|
|
+ unsigned int cValue = (unsigned int)va_arg(arglist, int);
|
|
+ /*if it's a private arg, just write <priate> to stream*/
|
|
+ if (isPrivacy == 1) {
|
|
+ break;
|
|
+ }
|
|
+ textLen = SecDecodeTypeC(&formatAttr, cValue, &formatBuf, &buffer);
|
|
+ if (textLen < 0) {
|
|
+ noOutput = 1;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ case SECUREC_CHAR('S'): /* wide char string */
|
|
+#ifndef SECUREC_FOR_WCHAR
|
|
+ if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
|
|
+ formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
|
|
+ }
|
|
+#else
|
|
+ if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
|
|
+ formatAttr.flags |= SECUREC_FLAG_SHORT;
|
|
+ }
|
|
+#endif
|
|
+ [[fallthrough]];
|
|
+ case SECUREC_CHAR('s'):
|
|
+ {
|
|
+ char *argPtr = (char *)va_arg(arglist, char *);
|
|
+ /*if it's a private arg, just write <priate> to stream*/
|
|
+ if (isPrivacy == 1) {
|
|
+ break;
|
|
+ }
|
|
+ textLen = SecDecodeTypeS(&formatAttr, argPtr, &formatBuf);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case SECUREC_CHAR('n'):
|
|
+ /* higher risk disable it */
|
|
+ return -1;
|
|
+
|
|
+ case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('A'): /* fall-through */ /* FALLTHRU */
|
|
+ /* convert format char to lower , use Explicit conversion to clean up compilation warning */
|
|
+ ch = (SecChar)(ch + ((SecChar)(SECUREC_CHAR('a')) - (SECUREC_CHAR('A'))));
|
|
+ [[fallthrough]];
|
|
+ case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('f'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('a'):
|
|
+ {
|
|
+ /*if it's a private arg, just write <priate> to stream*/
|
|
+ if (isPrivacy == 1) {
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+ if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
|
|
+ (void)va_arg(arglist, long double);
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+ (void)va_arg(arglist, double);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* floating point conversion */
|
|
+ formatBuf.str = buffer.str; /* output buffer for float string with default size */
|
|
+
|
|
+ /* compute the precision value */
|
|
+ if (formatAttr.precision < 0) {
|
|
+ formatAttr.precision = 6;
|
|
+ } else if (formatAttr.precision == 0 && ch == SECUREC_CHAR('g')) {
|
|
+ formatAttr.precision = 1;
|
|
+ }
|
|
+
|
|
+ /* calc buffer size to store long double value */
|
|
+ if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
|
|
+ if (formatAttr.precision > (SECUREC_INT_MAX - SECUREC_FLOAT_BUFSIZE_LB)) {
|
|
+ noOutput = 1;
|
|
+ break;
|
|
+ }
|
|
+ bufferSize = SECUREC_FLOAT_BUFSIZE_LB + formatAttr.precision;
|
|
+ } else {
|
|
+ if (formatAttr.precision > (SECUREC_INT_MAX - SECUREC_FLOAT_BUFSIZE)) {
|
|
+ noOutput = 1;
|
|
+ break;
|
|
+ }
|
|
+ bufferSize = SECUREC_FLOAT_BUFSIZE + formatAttr.precision;
|
|
+ }
|
|
+ if (formatAttr.fldWidth > bufferSize) {
|
|
+ bufferSize = formatAttr.fldWidth;
|
|
+ }
|
|
+
|
|
+ if (bufferSize >= SECUREC_BUFFER_SIZE) {
|
|
+ /* the current value of SECUREC_BUFFER_SIZE could NOT store the formatted float string */
|
|
+ /* size include '+' and '\0' */
|
|
+ floatBuf = (char *)SECUREC_MALLOC(((size_t)(unsigned int)bufferSize + (size_t)2));
|
|
+ if (floatBuf != NULL) {
|
|
+ formatBuf.str = floatBuf;
|
|
+ } else {
|
|
+ noOutput = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ {
|
|
+ /* add following code to call system sprintf API for float number */
|
|
+ const SecChar *pFltFmt = format - 2; /* point to the position before 'f' or 'g' */
|
|
+ int k;
|
|
+ int fltFmtStrLen;
|
|
+ char fltFmtBuf[SECUREC_FMT_STR_LEN];
|
|
+ char *fltFmtStr = fltFmtBuf;
|
|
+ char *fltFmtHeap = NULL; /* to clear warning */
|
|
+
|
|
+ /* must meet '%' (normal format) or '}'(with{private} or{public} format)*/
|
|
+ while (SECUREC_CHAR('%') != *pFltFmt && SECUREC_CHAR('}') != *pFltFmt) {
|
|
+ --pFltFmt;
|
|
+ }
|
|
+ fltFmtStrLen = (int)((format - pFltFmt) + 1); /* with ending terminator */
|
|
+ if (fltFmtStrLen > SECUREC_FMT_STR_LEN) {
|
|
+ /* if SECUREC_FMT_STR_LEN is NOT enough, alloc a new buffer */
|
|
+ fltFmtHeap = (char *)SECUREC_MALLOC((size_t)((unsigned int)fltFmtStrLen));
|
|
+ if (fltFmtHeap == NULL) {
|
|
+ noOutput = 1;
|
|
+ break;
|
|
+ } else {
|
|
+ fltFmtHeap[0] = '%';
|
|
+ for (k = 1; k < fltFmtStrLen - 1; ++k) {
|
|
+ /* convert wchar to char */
|
|
+ fltFmtHeap[k] = (char)(pFltFmt[k]); /* copy the format string */
|
|
+ }
|
|
+ fltFmtHeap[k] = '\0';
|
|
+
|
|
+ fltFmtStr = fltFmtHeap;
|
|
+ }
|
|
+ } else {
|
|
+ /* purpose of the repeat code is to solve the tool alarm Redundant_Null_Check */
|
|
+ fltFmtBuf[0] = '%';
|
|
+ for (k = 1; k < fltFmtStrLen - 1; ++k) {
|
|
+ /* convert wchar to char */
|
|
+ fltFmtBuf[k] = (char)(pFltFmt[k]); /* copy the format string */
|
|
+ }
|
|
+ fltFmtBuf[k] = '\0';
|
|
+ }
|
|
+
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+ if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
|
|
+ long double tmp = (long double)va_arg(arglist, long double);
|
|
+ /* call system sprintf to format float value */
|
|
+ if (formatAttr.dynWidth && formatAttr.dynPrecision) {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr,
|
|
+ formatAttr.fldWidth,formatAttr.precision, tmp);
|
|
+ } else if (formatAttr.dynWidth) {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr,
|
|
+ formatAttr.fldWidth, tmp);
|
|
+ } else if (formatAttr.dynPrecision) {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr,
|
|
+ formatAttr.precision, tmp);
|
|
+ } else {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr, tmp);
|
|
+ }
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+ double tmp = (double)va_arg(arglist, double);
|
|
+ if (formatAttr.dynWidth && formatAttr.dynPrecision) {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr, formatAttr.fldWidth,
|
|
+ formatAttr.precision, tmp);
|
|
+ } else if (formatAttr.dynWidth) {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr, formatAttr.fldWidth,
|
|
+ tmp);
|
|
+ } else if (formatAttr.dynPrecision) {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr, formatAttr.precision,
|
|
+ tmp);
|
|
+ } else {
|
|
+ textLen = SecIndirectSprintf(formatBuf.str, (char *)fltFmtStr, tmp);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (fltFmtHeap != NULL) {
|
|
+ /* if buffer is allocated on heap, free it */
|
|
+ SECUREC_FREE(fltFmtHeap);
|
|
+ fltFmtHeap = NULL;
|
|
+ /* to clear e438 last value assigned not used , the compiler will optimize this code */
|
|
+ (void)fltFmtHeap;
|
|
+ }
|
|
+ if (textLen < 0) {
|
|
+ /* bufferSize is large enough,just validation the return value */
|
|
+ noOutput = 1;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ formatAttr.fldWidth = textLen; /* no padding ,this variable to calculate amount of padding */
|
|
+ prefixLen = 0; /* no padding ,this variable to calculate amount of padding */
|
|
+ formatAttr.flags = 0; /* clear all internal formatAttr.flags */
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ case SECUREC_CHAR('p'):
|
|
+ /* print a pointer */
|
|
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
|
|
+ formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
|
|
+#else
|
|
+ formatAttr.flags |= SECUREC_FLAG_POINTER;
|
|
+#endif
|
|
+
|
|
+#ifdef SECUREC_ON_64BITS
|
|
+ formatAttr.flags |= SECUREC_FLAG_I64; /* converting an int64 */
|
|
+#else
|
|
+ formatAttr.flags |= SECUREC_FLAG_LONG; /* converting a long */
|
|
+#endif
|
|
+
|
|
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX))
|
|
+
|
|
+#if defined(SECUREC_VXWORKS_PLATFORM)
|
|
+ formatAttr.precision = 1;
|
|
+#else
|
|
+ formatAttr.precision = 0;
|
|
+#endif
|
|
+ formatAttr.flags |= SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */
|
|
+ digits = itoaLowerDigits;
|
|
+ goto OUTPUT_HEX;
|
|
+#else
|
|
+/* not linux vxwoks */
|
|
+#if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
|
|
+ formatAttr.precision = 1;
|
|
+#else
|
|
+ formatAttr.precision = 2 * sizeof(void *);
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+#if defined(SECUREC_ON_UNIX)
|
|
+ digits = itoaLowerDigits;
|
|
+ goto OUTPUT_HEX;
|
|
+#endif
|
|
+
|
|
+ [[fallthrough]];
|
|
+ case SECUREC_CHAR('X'):
|
|
+ /* unsigned upper hex output */
|
|
+ digits = itoaUpperDigits;
|
|
+ goto OUTPUT_HEX;
|
|
+ case SECUREC_CHAR('x'):
|
|
+ /* unsigned lower hex output */
|
|
+ digits = itoaLowerDigits;
|
|
+
|
|
+OUTPUT_HEX:
|
|
+ radix = 16;
|
|
+ if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
|
|
+ /* alternate form means '0x' prefix */
|
|
+ prefix[0] = SECUREC_CHAR('0');
|
|
+ prefix[1] = (SecChar)(digits[16]); /* 'x' or 'X' */
|
|
+
|
|
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM))
|
|
+ if (ch == 'p') {
|
|
+ prefix[1] = SECUREC_CHAR('x');
|
|
+ }
|
|
+#endif
|
|
+#if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
|
|
+ if (ch == 'p') {
|
|
+ prefixLen = 0;
|
|
+ } else {
|
|
+ prefixLen = 2;
|
|
+ }
|
|
+#else
|
|
+ prefixLen = 2;
|
|
+#endif
|
|
+
|
|
+ }
|
|
+ goto OUTPUT_INT;
|
|
+ case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */
|
|
+ case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */
|
|
+ /* signed decimal output */
|
|
+ formatAttr.flags |= SECUREC_FLAG_SIGNED;
|
|
+ [[fallthrough]];
|
|
+ case SECUREC_CHAR('u'):
|
|
+ radix = 10;
|
|
+ goto OUTPUT_INT;
|
|
+ case SECUREC_CHAR('o'):
|
|
+ /* unsigned octal output */
|
|
+ radix = 8;
|
|
+ if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
|
|
+ /* alternate form means force a leading 0 */
|
|
+ formatAttr.flags |= SECUREC_FLAG_FORCE_OCTAL;
|
|
+ }
|
|
+OUTPUT_INT:
|
|
+ {
|
|
+
|
|
+ SecUnsignedInt64 number = 0; /* number to convert */
|
|
+ SecInt64 l; /* temp long value */
|
|
+ unsigned char tch;
|
|
+#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)
|
|
+ SecUnsignedInt32 digit = 0; /* ascii value of digit */
|
|
+ SecUnsignedInt32 quotientHigh = 0;
|
|
+ SecUnsignedInt32 quotientLow = 0;
|
|
+#endif
|
|
+
|
|
+ /* read argument into variable l */
|
|
+ if (formatAttr.flags & SECUREC_FLAG_I64) {
|
|
+ l = (SecInt64)va_arg(arglist, SecInt64);
|
|
+ } else if (formatAttr.flags & SECUREC_FLAG_LONGLONG) {
|
|
+ l = (SecInt64)va_arg(arglist, SecInt64);
|
|
+ } else
|
|
+#ifdef SECUREC_ON_64BITS
|
|
+ if (formatAttr.flags & SECUREC_FLAG_LONG) {
|
|
+ l = (long)va_arg(arglist, long);
|
|
+ } else
|
|
+#endif /* SECUREC_ON_64BITS */
|
|
+ if (formatAttr.flags & SECUREC_FLAG_CHAR) {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
|
|
+ l = (char)va_arg(arglist, int); /* sign extend */
|
|
+ if (l >= 128) { /* on some platform, char is always unsigned */
|
|
+ SecUnsignedInt64 tmpL = (SecUnsignedInt64)l;
|
|
+ formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
|
|
+ tch = (unsigned char)(~(tmpL));
|
|
+ l = tch + 1;
|
|
+ }
|
|
+ } else {
|
|
+ l = (unsigned char)va_arg(arglist, int); /* zero-extend */
|
|
+ }
|
|
+
|
|
+ } else if (formatAttr.flags & SECUREC_FLAG_SHORT) {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
|
|
+ l = (short)va_arg(arglist, int); /* sign extend */
|
|
+ } else {
|
|
+ l = (unsigned short)va_arg(arglist, int); /* zero-extend */
|
|
+ }
|
|
+
|
|
+ }
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+ else if (formatAttr.flags & SECUREC_FLAG_PTRDIFF) {
|
|
+ l = (ptrdiff_t)va_arg(arglist, ptrdiff_t); /* sign extend */
|
|
+ } else if (formatAttr.flags & SECUREC_FLAG_SIZE) {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
|
|
+ /* No suitable macros were found to handle the branch */
|
|
+ if (SecIsSameSize(sizeof(size_t), sizeof(long))) {
|
|
+ l = va_arg(arglist, long); /* sign extend */
|
|
+ } else if (SecIsSameSize(sizeof(size_t), sizeof(long long))) {
|
|
+ l = va_arg(arglist, long long); /* sign extend */
|
|
+ } else {
|
|
+ l = va_arg(arglist, int); /* sign extend */
|
|
+ }
|
|
+ } else {
|
|
+ l = (SecInt64)(size_t)va_arg(arglist, size_t); /* sign extend */
|
|
+ }
|
|
+ } else if (formatAttr.flags & SECUREC_FLAG_INTMAX) {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
|
|
+ l = va_arg(arglist, SecInt64); /* sign extend */
|
|
+ } else {
|
|
+ l = (SecInt64)(SecUnsignedInt64)va_arg(arglist, SecUnsignedInt64); /* sign extend */
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+ else {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
|
|
+ l = va_arg(arglist, int); /* sign extend */
|
|
+ } else {
|
|
+ l = (unsigned int)va_arg(arglist, int); /* zero-extend */
|
|
+ }
|
|
+
|
|
+ }
|
|
+ /*if it's a private arg, just write <priate> to stream*/
|
|
+ if (isPrivacy == 1) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* check for negative; copy into number */
|
|
+ if ((formatAttr.flags & SECUREC_FLAG_SIGNED) && l < 0) {
|
|
+ number = (SecUnsignedInt64)(-l);
|
|
+ formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
|
|
+ } else {
|
|
+ number = (SecUnsignedInt64)l;
|
|
+ }
|
|
+
|
|
+ if (((formatAttr.flags & SECUREC_FLAG_I64) == 0) &&
|
|
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
|
|
+ ((formatAttr.flags & SECUREC_FLAG_INTMAX) == 0) &&
|
|
+#endif
|
|
+#ifdef SECUREC_ON_64BITS
|
|
+ ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) == 0) &&
|
|
+ ((formatAttr.flags & SECUREC_FLAG_SIZE) == 0) &&
|
|
+#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */
|
|
+ ((formatAttr.flags & SECUREC_FLAG_LONG) == 0) &&
|
|
+#endif
|
|
+#endif
|
|
+ ((formatAttr.flags & SECUREC_FLAG_LONGLONG) == 0)) {
|
|
+
|
|
+ number &= 0xffffffff;
|
|
+ }
|
|
+
|
|
+ /* check precision value for default */
|
|
+ if (formatAttr.precision < 0) {
|
|
+ formatAttr.precision = 1; /* default precision */
|
|
+ } else {
|
|
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
|
|
+ formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
|
|
+#else
|
|
+ if (!(formatAttr.flags & SECUREC_FLAG_POINTER)) {
|
|
+ formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
|
|
+ }
|
|
+#endif
|
|
+ if (formatAttr.precision > SECUREC_MAX_PRECISION) {
|
|
+ formatAttr.precision = SECUREC_MAX_PRECISION;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Check if data is 0; if so, turn off hex prefix,if 'p',add 0x prefix,else not add prefix */
|
|
+ if (number == 0) {
|
|
+#if !(defined(SECUREC_VXWORKS_PLATFORM)||defined(__hpux))
|
|
+ prefixLen = 0;
|
|
+#else
|
|
+ if ((ch == 'p') && (formatAttr.flags & SECUREC_FLAG_ALTERNATE))
|
|
+ prefixLen = 2;
|
|
+ else
|
|
+ prefixLen = 0;
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ /* Convert data to ASCII */
|
|
+ formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE];
|
|
+
|
|
+ if (number > 0) {
|
|
+#ifdef SECUREC_ON_64BITS
|
|
+ switch (radix) {
|
|
+ /* the compiler will optimize each one */
|
|
+ SECUREC_SPECIAL(number, 10);
|
|
+ break;
|
|
+ SECUREC_SPECIAL(number, 16);
|
|
+ break;
|
|
+ SECUREC_SPECIAL(number, 8);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+#else /* for 32 bits system */
|
|
+ if (number <= 0xFFFFFFFFUL) {
|
|
+ /* in most case, the value to be converted is small value */
|
|
+ SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number;
|
|
+ switch (radix) {
|
|
+ SECUREC_SPECIAL(n32Tmp, 16);
|
|
+ break;
|
|
+ SECUREC_SPECIAL(n32Tmp, 8);
|
|
+ break;
|
|
+
|
|
+#ifdef _AIX
|
|
+ /* the compiler will optimize div 10 */
|
|
+ SECUREC_SPECIAL(n32Tmp, 10);
|
|
+ break;
|
|
+#else
|
|
+ case 10:
|
|
+ {
|
|
+ /* fast div 10 */
|
|
+ SecUnsignedInt32 q;
|
|
+ SecUnsignedInt32 r;
|
|
+ do {
|
|
+ *--formatBuf.str = digits[n32Tmp % 10];
|
|
+ q = (n32Tmp >> 1) + (n32Tmp >> 2);
|
|
+ q = q + (q >> 4);
|
|
+ q = q + (q >> 8);
|
|
+ q = q + (q >> 16);
|
|
+ q = q >> 3;
|
|
+ r = n32Tmp - (((q << 2) + q) << 1);
|
|
+ n32Tmp = (r > 9) ? (q + 1) : q;
|
|
+ } while (n32Tmp != 0);
|
|
+ }
|
|
+ break;
|
|
+#endif
|
|
+ default:
|
|
+ break;
|
|
+ } /* end switch */
|
|
+ } else {
|
|
+ /* the value to be converted is greater than 4G */
|
|
+#if defined(SECUREC_VXWORKS_VERSION_5_4)
|
|
+ do {
|
|
+ if (0 != SecU64Div32((SecUnsignedInt32)((number >> 16) >> 16),
|
|
+ (SecUnsignedInt32)number,
|
|
+ (SecUnsignedInt32)radix, "ientHigh, "ientLow, &digit)) {
|
|
+ noOutput = 1;
|
|
+ break;
|
|
+ }
|
|
+ *--formatBuf.str = digits[digit];
|
|
+
|
|
+ number = (SecUnsignedInt64)quotientHigh;
|
|
+ number = (number << 32) + quotientLow;
|
|
+ } while (number != 0);
|
|
+#else
|
|
+ switch (radix) {
|
|
+ /* the compiler will optimize div 10 */
|
|
+ SECUREC_SPECIAL(number, 10);
|
|
+ break;
|
|
+ SECUREC_SPECIAL(number, 16);
|
|
+ break;
|
|
+ SECUREC_SPECIAL(number, 8);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+#endif
|
|
+ } /* END if (number > 0) */
|
|
+ /* compute length of number,.if textLen > 0, then formatBuf.str must be in buffer.str */
|
|
+ textLen = (int)((char *)&buffer.str[SECUREC_BUFFER_SIZE] - formatBuf.str);
|
|
+ if (formatAttr.precision > textLen) {
|
|
+ for (ii = 0; ii < formatAttr.precision - textLen; ++ii) {
|
|
+ *--formatBuf.str = '0';
|
|
+ }
|
|
+ textLen = formatAttr.precision;
|
|
+ }
|
|
+
|
|
+ /* Force a leading zero if FORCEOCTAL flag set */
|
|
+ if ((formatAttr.flags & SECUREC_FLAG_FORCE_OCTAL) && (textLen == 0 || formatBuf.str[0] != '0')) {
|
|
+ *--formatBuf.str = '0';
|
|
+ ++textLen; /* add a zero */
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ /*if it's a private arg, just write <priate> to stream*/
|
|
+ if (isPrivacy == 1) {
|
|
+ SecWritePrivateStr(stream, &charsOut);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (noOutput == 0) {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
|
|
+ if (formatAttr.flags & SECUREC_FLAG_NEGATIVE) {
|
|
+ /* prefix is a '-' */
|
|
+ prefix[0] = SECUREC_CHAR('-');
|
|
+ prefixLen = 1;
|
|
+ } else if (formatAttr.flags & SECUREC_FLAG_SIGN) {
|
|
+ /* prefix is '+' */
|
|
+ prefix[0] = SECUREC_CHAR('+');
|
|
+ prefixLen = 1;
|
|
+ } else if (formatAttr.flags & SECUREC_FLAG_SIGN_SPACE) {
|
|
+ /* prefix is ' ' */
|
|
+ prefix[0] = SECUREC_CHAR(' ');
|
|
+ prefixLen = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX))
|
|
+ if ((formatAttr.flags & SECUREC_FLAG_POINTER) && (0 == textLen)) {
|
|
+ formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
|
|
+ formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE - 1];
|
|
+ *formatBuf.str-- = '\0';
|
|
+ *formatBuf.str-- = ')';
|
|
+ *formatBuf.str-- = 'l';
|
|
+ *formatBuf.str-- = 'i';
|
|
+ *formatBuf.str-- = 'n';
|
|
+ *formatBuf.str = '(';
|
|
+ textLen = 5;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /* calculate amount of padding */
|
|
+ padding = (formatAttr.fldWidth - textLen) - prefixLen;
|
|
+
|
|
+ /* put out the padding, prefix, and text, in the correct order */
|
|
+
|
|
+ if (!(formatAttr.flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) && padding > 0) {
|
|
+ /* pad on left with blanks */
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
|
|
+ /* char * cast to wchar * */
|
|
+ SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* write prefix */
|
|
+ if (prefixLen > 0) {
|
|
+ SecChar *pPrefix = prefix;
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(prefixLen)) {
|
|
+ /* max prefix len is 2, use loop copy */ /* char * cast to wchar * */
|
|
+ SECUREC_SAFE_WRITE_PREFIX(pPrefix, prefixLen, stream, &charsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_STRING(prefix, prefixLen, stream, &charsOut);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ((formatAttr.flags & SECUREC_FLAG_LEADZERO) && !(formatAttr.flags & SECUREC_FLAG_LEFT)
|
|
+ && padding > 0) {
|
|
+ /* write leading zeros */
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
|
|
+ /* char * cast to wchar * */
|
|
+ SECUREC_SAFE_PADDING(SECUREC_CHAR('0'), padding, stream, &charsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR('0'), padding, stream, &charsOut);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* write text */
|
|
+#ifndef SECUREC_FOR_WCHAR
|
|
+ if (formatAttr.bufferIsWide && (textLen > 0)) {
|
|
+ wchar_t *p = formatBuf.wStr;
|
|
+ int count = textLen;
|
|
+ while (count--) {
|
|
+ char tmpBuf[SECUREC_MB_LEN + 1];
|
|
+ SECUREC_MASK_MSVC_CRT_WARNING
|
|
+ int retVal = wctomb(tmpBuf, *p++);
|
|
+ SECUREC_END_MASK_MSVC_CRT_WARNING
|
|
+ if (retVal <= 0) {
|
|
+ charsOut = -1;
|
|
+ break;
|
|
+ }
|
|
+ SECUREC_WRITE_STRING(tmpBuf, retVal, stream, &charsOut);
|
|
+ }
|
|
+ } else {
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(textLen)) {
|
|
+ SECUREC_SAFE_WRITE_STR(formatBuf.str, textLen, stream, &charsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_STRING(formatBuf.str, textLen, stream, &charsOut);
|
|
+ }
|
|
+ }
|
|
+#else /* SECUREC_FOR_WCHAR */
|
|
+ if (formatAttr.bufferIsWide == 0 && textLen > 0) {
|
|
+ int count = textLen;
|
|
+ char *p = formatBuf.str;
|
|
+
|
|
+ while (count > 0) {
|
|
+ wchar_t wchar = L'\0';
|
|
+ int retVal = mbtowc(&wchar, p, (size_t)MB_CUR_MAX);
|
|
+ if (retVal <= 0) {
|
|
+ charsOut = -1;
|
|
+ break;
|
|
+ }
|
|
+ SECUREC_WRITE_CHAR(wchar, stream, &charsOut);
|
|
+ p += retVal;
|
|
+ count -= retVal;
|
|
+ }
|
|
+ } else {
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(textLen)) {
|
|
+ SECUREC_SAFE_WRITE_STR(formatBuf.wStr, textLen, stream, &charsOut); /* char * cast to wchar * */
|
|
+ } else {
|
|
+ SECUREC_WRITE_STRING(formatBuf.wStr, textLen, stream, &charsOut);
|
|
+ }
|
|
+ }
|
|
+#endif /* SECUREC_FOR_WCHAR */
|
|
+
|
|
+ if (charsOut >= 0 && (formatAttr.flags & SECUREC_FLAG_LEFT) && padding > 0) {
|
|
+ /* pad on right with blanks */
|
|
+ if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
|
|
+ /* char * cast to wchar * */
|
|
+ SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
|
|
+ } else {
|
|
+ SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* we're done! */
|
|
+ }
|
|
+ if (floatBuf != NULL) {
|
|
+ SECUREC_FREE(floatBuf);
|
|
+ floatBuf = NULL;
|
|
+ }
|
|
+ break;
|
|
+ case STAT_INVALID:
|
|
+ return -1;
|
|
+ default:
|
|
+ return -1; /* input format is wrong, directly return */
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (state != STAT_NORMAL && state != STAT_TYPE) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return charsOut; /* the number of characters written */
|
|
+} /* arglist must not be declare as const */
|
|
+#endif /* OUTPUT_P_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 */
|
|
diff --git a/hilog.gni b/hilog.gni
|
|
index 116b058..bdd9393 100644
|
|
--- a/hilog.gni
|
|
+++ b/hilog.gni
|
|
@@ -12,9 +12,9 @@
|
|
# limitations under the License.
|
|
|
|
platforms = [
|
|
- "ohos",
|
|
- "windows",
|
|
- "mac",
|
|
+ # "ohos",
|
|
+ # "windows",
|
|
+ # "mac",
|
|
"linux",
|
|
]
|
|
|
|
diff --git a/interfaces/bundle.json b/interfaces/bundle.json
|
|
index f6b5cdf..330ffcb 100644
|
|
--- a/interfaces/bundle.json
|
|
+++ b/interfaces/bundle.json
|
|
@@ -39,10 +39,7 @@
|
|
"base_group": [
|
|
|
|
],
|
|
- "fwk_group": [
|
|
- "//base/hiviewdfx/hilog/frameworks/hilog_ndk:hilog_ndk",
|
|
- "//base/hiviewdfx/hilog/interfaces/js:hilog_napi"
|
|
- ],
|
|
+ "fwk_group": [],
|
|
"service_group": [
|
|
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_base",
|
|
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog"
|
|
diff --git a/interfaces/native/innerkits/BUILD.gn b/interfaces/native/innerkits/BUILD.gn
|
|
index 3666081..ee27551 100644
|
|
--- a/interfaces/native/innerkits/BUILD.gn
|
|
+++ b/interfaces/native/innerkits/BUILD.gn
|
|
@@ -19,40 +19,33 @@ config("libhilog_pub_config") {
|
|
include_dirs = [ "include" ]
|
|
}
|
|
|
|
-template("libhilog") {
|
|
- forward_variables_from(invoker, "*")
|
|
- ohos_shared_library(target_name) {
|
|
+ohos_shared_library("libhilog") {
|
|
public_configs = [ ":libhilog_pub_config" ]
|
|
-
|
|
- deps = [
|
|
- "//base/hiviewdfx/hilog/frameworks/libhilog:libhilog_source_$platform",
|
|
+ sources = [
|
|
+ "//base/hiviewdfx/hilog/libhilog/hilog.cpp",
|
|
+ "//base/hiviewdfx/hilog/libhilog/vsnprintf/vsnprintf_s_p.cpp",
|
|
+ "//base/hiviewdfx/hilog/libhilog/utils/log_utils.cpp",
|
|
+ "//base/hiviewdfx/hilog/libhilog/utils/log_print.cpp",
|
|
]
|
|
|
|
- if (platform == "ohos") {
|
|
- output_extension = "so"
|
|
- }
|
|
+ include_dirs = [
|
|
+ "//base/hiviewdfx/hilog/libhilog/include/",
|
|
+ "//base/hiviewdfx/hilog/libhilog/vsnprintf/include/",
|
|
+ "//base/hiviewdfx/hilog/libhilog/utils/include/",
|
|
+ ]
|
|
|
|
+ defines = []
|
|
+ cflags_cc = [ "-std=c++17", "-fpermissive" ]
|
|
+ defines += [ "__LINUX__" ]
|
|
+ deps = [
|
|
+ "//third_party/bounds_checking_function:libsec_shared"
|
|
+ ]
|
|
install_enable = !hilog_native_feature_ohcore
|
|
install_images = [
|
|
"system",
|
|
- "updater",
|
|
]
|
|
part_name = "hilog_native"
|
|
subsystem_name = "hiviewdfx"
|
|
- }
|
|
-}
|
|
-
|
|
-foreach(item, platforms) {
|
|
- if (item == "ohos") {
|
|
- libhilog("libhilog") {
|
|
- platform = item
|
|
- }
|
|
- }
|
|
- if (item == "windows" || item == "mac" || item == "linux") {
|
|
- libhilog("libhilog_" + item) {
|
|
- platform = item
|
|
- }
|
|
- }
|
|
}
|
|
|
|
config("libhilog_base_pub_cfg") {
|
|
diff --git a/interfaces/native/innerkits/include/hilog/log_c.h b/interfaces/native/innerkits/include/hilog/log_c.h
|
|
index 2649f33..08aa937 100644
|
|
--- a/interfaces/native/innerkits/include/hilog/log_c.h
|
|
+++ b/interfaces/native/innerkits/include/hilog/log_c.h
|
|
@@ -57,8 +57,8 @@ typedef enum {
|
|
|
|
const char* GetLastFatalMessage(void);
|
|
|
|
-int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)
|
|
- __attribute__((__format__(os_log, 5, 6)));
|
|
+int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...);
|
|
+ // __attribute__((__format__(os_log, 5, 6)));
|
|
|
|
#define HILOG_DEBUG(type, ...) ((void)HiLogPrint((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
|
|
|
|
diff --git a/interfaces/native/innerkits/include/hilog/log_cpp.h b/interfaces/native/innerkits/include/hilog/log_cpp.h
|
|
index ff48162..bc6077e 100644
|
|
--- a/interfaces/native/innerkits/include/hilog/log_cpp.h
|
|
+++ b/interfaces/native/innerkits/include/hilog/log_cpp.h
|
|
@@ -21,7 +21,7 @@
|
|
#ifdef __cplusplus
|
|
namespace OHOS {
|
|
namespace HiviewDFX {
|
|
-using HiLogLabel = struct {
|
|
+struct HiLogLabel {
|
|
LogType type;
|
|
unsigned int domain;
|
|
const char *tag;
|
|
@@ -29,11 +29,16 @@ using HiLogLabel = struct {
|
|
|
|
class HiLog final {
|
|
public:
|
|
- static int Debug(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
|
|
- static int Info(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
|
|
- static int Warn(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
|
|
- static int Error(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
|
|
- static int Fatal(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
|
|
+ static int Debug(const HiLogLabel &label, const char *fmt, ...);
|
|
+ // __attribute__((__format__(os_log, 2, 3)));
|
|
+ static int Info(const HiLogLabel &label, const char *fmt, ...);
|
|
+ // __attribute__((__format__(os_log, 2, 3)));
|
|
+ static int Warn(const HiLogLabel &label, const char *fmt, ...);
|
|
+ // __attribute__((__format__(os_log, 2, 3)));
|
|
+ static int Error(const HiLogLabel &label, const char *fmt, ...);
|
|
+ // __attribute__((__format__(os_log, 2, 3)));
|
|
+ static int Fatal(const HiLogLabel &label, const char *fmt, ...);
|
|
+ // __attribute__((__format__(os_log, 2, 3)));
|
|
};
|
|
} // namespace HiviewDFX
|
|
} // namespace OHOS
|
|
--
|
|
2.33.0
|
|
|