From 1bc2c2bcbf4e7a25a2e439b9c5767c6a2fff9a6d Mon Sep 17 00:00:00 2001 From: taynpg Date: Sun, 29 Mar 2026 19:25:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=ACJson=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .clang-format | 20 ++++++ .clangd | 12 ++++ .gitignore | 3 + .vscode/settings.json | 145 ++++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 19 ++++++ formater/fmt.json.cpp | 45 +++++++++++++ formater/fmt.json.h | 22 +++++++ main.cpp | 52 +++++++++++++++ util/axc.util.cpp | 39 ++++++++++++ util/axc.util.h | 19 ++++++ 10 files changed, 376 insertions(+) create mode 100644 .clang-format create mode 100644 .clangd create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 CMakeLists.txt create mode 100644 formater/fmt.json.cpp create mode 100644 formater/fmt.json.h create mode 100644 main.cpp create mode 100644 util/axc.util.cpp create mode 100644 util/axc.util.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..8d63d3f --- /dev/null +++ b/.clang-format @@ -0,0 +1,20 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +PointerAlignment: Left +AccessModifierOffset: -4 +ReflowComments: true +SpacesBeforeTrailingComments: 3 +AllowShortFunctionsOnASingleLine: None +AllowShortEnumsOnASingleLine: false +BreakBeforeBraces: Custom +BraceWrapping: + AfterFunction: true + AfterClass: true +TabWidth: 4 +ColumnLimit: 130 +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^<.*>' + Priority: 1 + - Regex: '^".*"' + Priority: 2 diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..40557fb --- /dev/null +++ b/.clangd @@ -0,0 +1,12 @@ +Hover: + ShowAKA: Yes +Diagnostics: + UnusedIncludes: None # 禁用未使用头文件提示 + Suppress: [ + anon_type_definition, # 禁用匿名的typedef提示 + unused-variable, # 禁用未使用变量提示 + unused-function, # 禁用未使用函数提示 + unused-includes, + ] + ClangTidy: + Remove: misc-unused-alias-decls diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..024ffc5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/ +.cache/ +.lingma/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..30a5ec2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,145 @@ +{ + "files.autoSave": "onFocusChange", + "editor.fontSize": 14, + "editor.fontFamily": "'Mononoki Nerd Font Mono', 'Mononoki Nerd Font Mono', 'Mononoki Nerd Font Mono'", + "editor.wordWrap": "on", + "terminal.integrated.fontFamily": "'Mononoki Nerd Font Mono'", + "cmake.configureOnOpen": true, + //"C_Cpp.intelliSenseEngine": "disabled", + "cmake.debugConfig": { + "console": "externalTerminal", + "setupCommands": [ + { + "description": "-gdb-set charset utf-8", + "text": "-gdb-set charset UTF-8" + }, + { + "description": "Enable gdb pretty-printing", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + //"visualizerFile": "${workspaceRoot}/.vscode/qt6.natvis", + }, + "cmake.configureArgs": [ + "-Wno-dev" + ], + "cmake.configureSettings": { + "CMAKE_PREFIX_PATH": "C:/local" + //"CXXLIBRARY_TEST": "ON" + }, + "cmake.options.statusBarVisibility": "visible", + "cmake.generator": "Ninja", + "C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json", + "C_Cpp.default.cppStandard": "c++17", + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "editor.inlayHints.enabled": "off", + "editor.unicodeHighlight.allowedLocales": { + "ja": true, + "zh-hant": true, + "zh-hans": true + }, + "files.associations": { + "*.cfg": "json", + "xstring": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "filesystem": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "functional": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xmemory0": "cpp", + "xstddef": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "bit": "cpp", + "compare": "cpp", + "concepts": "cpp", + "coroutine": "cpp", + "format": "cpp", + "stop_token": "cpp", + "bitset": "cpp", + "complex": "cpp", + "cstdarg": "cpp", + "set": "cpp", + "variant": "cpp", + "expected": "cpp", + "source_location": "cpp", + "regex": "cpp", + "*.in": "cpp", + "deque": "cpp", + "future": "cpp", + "queue": "cpp", + "resumable": "cpp", + "any": "cpp", + "codecvt": "cpp", + "csignal": "cpp", + "cwctype": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "shared_mutex": "cpp", + "cinttypes": "cpp", + "cfenv": "cpp", + "unordered_set": "cpp", + "ranges": "cpp", + "typeindex": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bb8f58e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.16) + +project(aux_cmd LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 17) + +if (MSVC) + add_compile_options(/utf-8) +endif() + +set(SOURCES + formater/fmt.json.h formater/fmt.json.cpp + util/axc.util.h util/axc.util.cpp +) + +find_package(cxxLibrary CONFIG REQUIRED) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +add_executable(aux_cmd main.cpp ${SOURCES}) +target_link_libraries(aux_cmd PRIVATE cxxLibrary::cxxLibrary) diff --git a/formater/fmt.json.cpp b/formater/fmt.json.cpp new file mode 100644 index 0000000..b5cabb5 --- /dev/null +++ b/formater/fmt.json.cpp @@ -0,0 +1,45 @@ +#include "fmt.json.h" + +#include +#include +#include + +using json = nlohmann::json; + +JsonFormatter::JsonFormatter() +{ +} + +std::string JsonFormatter::format(const std::string& path, const FormatterArg& arg) +{ + std::string result; + boost::nowide::ifstream ifs(path); + if (!ifs.is_open()) + return ""; + std::string content((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + // std::cout << "Content: " << content << std::endl; + + formatContent(content, arg, result); + return result; +} + +bool JsonFormatter::formatContent(const std::string& content, const FormatterArg& arg, std::string& outContent) +{ + try { + json j = json::parse(content); + outContent = j.dump(arg.indent); + return true; + } catch (json::parse_error& e) { + AxcUtil::getLogger()->error("Parse json content error: [{}], return default content.", e.what()); + return false; + } +} + +bool JsonFormatter::save(const std::string& path, const std::string& content) +{ + boost::nowide::ofstream ofs(path); + if (!ofs.is_open()) + return false; + ofs << content; + return true; +} diff --git a/formater/fmt.json.h b/formater/fmt.json.h new file mode 100644 index 0000000..ec68310 --- /dev/null +++ b/formater/fmt.json.h @@ -0,0 +1,22 @@ +#ifndef FMT_JSON_H +#define FMT_JSON_H + +#include + +#include "util/axc.util.h" + +class JsonFormatter +{ +public: + JsonFormatter(); + +public: + std::string format(const std::string& path, const FormatterArg& arg); + bool formatContent(const std::string& content, const FormatterArg& arg, std::string& outContent); + bool save(const std::string& path, const std::string& content); + +private: + std::shared_ptr logger; +}; + +#endif // FMT_JSON_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..cd7a65c --- /dev/null +++ b/main.cpp @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "formater/fmt.json.h" +#include "util/axc.util.h" + +#include + +int main(int argc, char* argv[]) +{ + zoostCommon::SetOutputU8(); + + if (!AxcUtil::initLogger("aux_cmd.log")) { + std::cerr << "Failed to init logger." << std::endl; + return 1; + } + // AxcUtil::getLogger()->info("Starting..."); + // 中文测试。 + CLI::App app("A simple command line tool"); + argv = app.ensure_utf8(argv); + + FormatterArg formatArg; + + try { + auto jsonSub = app.add_subcommand("json", "Json Operator."); + jsonSub->add_option("-i,--indent", formatArg.indent, "Indent size for json format"); + jsonSub->add_option("-f,--file", formatArg.file, "format file.")->required()->check(CLI::ExistingFile); + app.parse(argc, argv); + + if (jsonSub->parsed()) { + JsonFormatter jf; + auto content = jf.format(formatArg.file, formatArg); + if (content.empty()) { + AxcUtil::getLogger()->error("Failed to format json file."); + return 1; + } + if (!jf.save(formatArg.file, content)) { + AxcUtil::getLogger()->error("Failed to save json file."); + return 1; + } else { + AxcUtil::getLogger()->info("Json file saved successfully."); + } + } + + } catch (const CLI::ParseError& e) { + return app.exit(e); + } + + std::cout << "Hello, world! This is ..." << std::endl; + return 0; +} diff --git a/util/axc.util.cpp b/util/axc.util.cpp new file mode 100644 index 0000000..ed5d34a --- /dev/null +++ b/util/axc.util.cpp @@ -0,0 +1,39 @@ +#include "axc.util.h" + +#include +#include +#include +#include +#include + +static std::shared_ptr logger; + +bool AxcUtil::initLogger(const std::string& logFile) +{ + if (logger) { + return true; + } + try { + auto fileSink = std::make_shared("aux_cmd.log", 1024 * 1024 * 5, 3); + auto consoleSink = std::make_shared(); + fileSink->set_pattern("[%Y-%m-%d %H:%M:%S.%e][%l]: %v"); + consoleSink->set_pattern("[%H:%M:%S.%e] %^[%l] %v%$"); + std::vector sinks{fileSink, consoleSink}; + logger = std::make_shared("aux_cmd", sinks.begin(), sinks.end()); + logger->set_level(spdlog::level::debug); + logger->flush_on(spdlog::level::debug); + spdlog::register_logger(logger); + } catch (const spdlog::spdlog_ex& ex) { + boost::nowide::cerr << "Error creating logger: " << ex.what() << std::endl; + return false; + } + return true; +} + +std::shared_ptr AxcUtil::getLogger() +{ + if (!logger) { + logger = spdlog::get("aux_cmd"); + } + return logger; +} diff --git a/util/axc.util.h b/util/axc.util.h new file mode 100644 index 0000000..9d5189c --- /dev/null +++ b/util/axc.util.h @@ -0,0 +1,19 @@ +#ifndef AXC_UTIL_H +#define AXC_UTIL_H + +#include +#include + +struct FormatterArg { + int indent{4}; + std::string file; +}; + +class AxcUtil +{ +public: + static bool initLogger(const std::string& logFile); + static std::shared_ptr getLogger(); +}; + +#endif