1/*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "common/log_wrapper.h"
17
18#include <string>
19#ifdef ANDROID_PLATFORM
20#include <android/log.h>
21#else
22#include <thread>
23#include "securec.h"
24#endif
25
26namespace OHOS::ArkCompiler::Toolchain {
27void StripString(const std::string& prefix, std::string& str)
28{
29    for (auto pos = str.find(prefix, 0); pos != std::string::npos; pos = str.find(prefix, pos)) {
30        str.erase(pos, prefix.size());
31    }
32}
33
34std::string StripFormatString(const char* fmt)
35{
36    std::string newFmt(fmt);
37    StripString("{public}", newFmt);
38    StripString("{private}", newFmt);
39    return newFmt;
40}
41
42#ifdef ANDROID_PLATFORM
43const char* tag = "ArkCompiler";
44void StdLog::PrintLog(LogLevel level, const char* fmt, ...)
45{
46    std::string formatted = StripFormatString(fmt);
47    va_list args;
48    va_start(args, fmt);
49#pragma clang diagnostic push
50#pragma clang diagnostic ignored "-Wformat-nonliteral"
51    __android_log_vprint(static_cast<int>(level), tag, formatted.c_str(), args);
52#pragma clang diagnostic pop
53    va_end(args);
54}
55#else
56#ifndef ENABLE_HILOG
57constexpr int32_t MAX_BUFFER_SIZE = 100;
58void StdLog::PrintLog(LogLevel level, const char* fmt, ...)
59{
60    std::string formatted = StripFormatString(fmt);
61    va_list args;
62    va_start(args, fmt);
63
64    char buf[MAX_BUFFER_SIZE];
65    if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, formatted.c_str(), args) < 0 && errno == EINVAL) {
66        return;
67    }
68    va_end(args);
69
70    char timeBuf[MAX_BUFFER_SIZE];
71    const char* domainTag = "[ArkCompiler Debugger]";
72    std::string levelTag;
73    switch (level) {
74        case LogLevel::FATAL:
75            levelTag = "[FATAL]";
76            break;
77        case LogLevel::ERROR:
78            levelTag = "[ERROR]";
79            break;
80        case LogLevel::WARN:
81            levelTag = "[WARN]";
82            break;
83        case LogLevel::INFO:
84            levelTag = "[INFO]";
85            break;
86        case LogLevel::DEBUG:
87            levelTag = "[DEBUG]";
88            break;
89        default:
90            levelTag = "[DEFAULT]";
91            break;
92    }
93
94    if (snprintf_s(timeBuf, sizeof(timeBuf), sizeof(timeBuf) - 1, "%s %s %d",
95            domainTag, levelTag.c_str(), std::this_thread::get_id()) < 0) {
96        return;
97    }
98
99    printf("%s %s\r\n", timeBuf, buf);
100}
101#endif
102#endif
103} // namespace OHOS::ArkCompiler::Toolchain