Переглянути джерело

refactor & feat: 新增core内容

SongZihuan 3 роки тому
батько
коміт
26b93cecae

+ 66 - 0
include/core/code.hpp

@@ -0,0 +1,66 @@
+#ifndef AFUN_CODE_H
+#define AFUN_CODE_H
+#include "iostream"
+#include "tool.hpp"
+#include "exception.hpp"
+
+namespace aFuncore {
+    typedef enum CodeType {
+        code_start = 0,
+        code_element = 1,
+        code_block = 2,
+    } CodeType;
+
+    typedef enum BlockType {
+        block_p = '(',
+        block_b = '[',
+        block_c = '{',
+    } BlockType;
+
+    typedef class Code Code;
+    class Code {
+        CodeType type;
+        char perfix=NUL;
+
+        union {
+            char *element;  // union 内不使用 std::string
+
+            struct {
+                BlockType block_type;
+                Code *son;
+            };
+        };
+
+        Code *father = nullptr;;
+        Code *next = nullptr;;
+        Code *prev = nullptr;;
+
+    public:
+        aFuntool::FileLine line;
+        aFuntool::FilePath file;
+
+        explicit Code(FileLine line, ConstFilePath file="");
+        Code (const std::string &element, aFuntool::FileLine line, aFuntool::ConstFilePath file="", char prefix=NUL);
+        Code (BlockType block_type, Code *son, aFuntool::FileLine line, aFuntool::ConstFilePath file="", char prefix=NUL);
+        ~Code();
+
+        Code *connect(Code *code);
+        void destruct();
+        void display();
+        void displayAll();
+
+        [[nodiscard]] CodeType getType() const {return type;}
+        [[nodiscard]] char getPrefix() const {return perfix;}
+
+        [[nodiscard]] const char *getElement() const {if (type != code_element) throw aFuncore::AttributesError("Code.Element"); return element;}
+        [[nodiscard]] BlockType getBlockType() const {if (type != code_block) throw aFuncore::AttributesError("Code.BlockType"); return block_type;}
+        [[nodiscard]] Code *getSon() const {if (type != code_block) return nullptr; return son;}
+
+        [[nodiscard]] Code *toNext() const {return next;}
+        [[nodiscard]] Code *toPrev() const {return prev;}
+        [[nodiscard]] Code *toFather() const {return father;}
+
+    };
+}
+
+#endif //AFUN_CODE_H

+ 14 - 0
include/core/exception.hpp

@@ -0,0 +1,14 @@
+#ifndef AFUN_EXCEPTION_HPP
+#define AFUN_EXCEPTION_HPP
+#include "iostream"
+
+namespace aFuncore {
+    class AttributesError : public std::exception {
+        std::string msg;
+    public:
+        explicit AttributesError(const std::string &attributes) {msg = (std::string("Get attributes error: ") + attributes);}
+        virtual const char *what() {return msg.c_str();}
+    };
+}
+
+#endif //AFUN_EXCEPTION_HPP

+ 0 - 37
include/core/info/magic_func.h

@@ -1,37 +0,0 @@
-/*
- * 文件名: magic_func.h
- * 目标: 定义魔法函数的名字
- */
-#ifndef AFUN_MAGIC_FUNC_H
-#define AFUN_MAGIC_FUNC_H
-/* 魔法函数 */
-#define MAGIC_NAME_BASE(type) "magic-" #type ":"
-#define MAGIC_NAME(type, job) (MAGIC_NAME_BASE(type) #job)
-
-/* gc模块 */
-#define mg_gc_destruct MAGIC_NAME(gc, destruct)
-#define mg_sys_cycle MAGIC_NAME(sys, cycle)
-
-/* 内置环境变量 */
-#define SYS_NAME(job) "sys-" #job
-
-#define ev_sys_prefix   SYS_NAME(prefix)
-#define ev_grt          SYS_NAME(grt)
-#define ev_gcmax        SYS_NAME(gc-max)
-#define ev_gccount      SYS_NAME(gc-count)
-#define ev_exit_code    SYS_NAME(exit-code)
-#define ev_argc         SYS_NAME(argc)
-#define ev_argvx_prefix SYS_NAME(argv)
-#define ev_error_std    SYS_NAME(error-std)
-
-#define ev_sigint       SYS_NAME(SIGINT)
-#define ev_sigterm      SYS_NAME(SIGTERM)
-#define ev_sigu1        SYS_NAME(SIGU1)
-#define ev_sigu2        SYS_NAME(SIGU2)
-
-#define ev_sigint_cfg   ev_sigint "-config"
-#define ev_sigterm_cfg  ev_sigterm "-config"
-#define ev_sigu1_cfg    ev_sigu1 "-config"
-#define ev_sigu2_cfg    ev_sigu2 "-config"
-
-#endif //AFUN_MAGIC_FUNC_H

+ 0 - 56
include/core/info/parserl_warning_error.h

@@ -1,56 +0,0 @@
-/*
- * 文件名: parser_warning_error.h
- * 目标: 记录parser的警告和错误信息
- */
-#ifndef AFUN_PARSERL_WARNING_ERROR_H
-#define AFUN_PARSERL_WARNING_ERROR_H
-
-/* 词法分析器错误和警告信息 */
-#define IllegalCharLog "Get illegal characters"
-#define IllegalCharConsole HT_aFunGetText(IllegalChar, "Get illegal characters")
-
-#define IncompleteFileLog "Incomplete file" /* 文件不完整 */
-#define IncompleteFileConsole HT_aFunGetText(LexicalIncompleteFile, "Incomplete file")
-
-#define IncludeControlCharLog "Include control characters in the text (not recommended)" /* 文本中包含控制符 */
-#define IncludeControlCharConsole HT_aFunGetText(LexicalIncludeCTRL, "Include control characters in the text (not recommended)")
-
-/* 语法分析器错误和经过信息 */
-#define CodeListStartErrorLog "CodeList did not get a suitable start symbol"
-#define CodeListStartErrorConsole HT_aFunGetText(SyntacticCodeListStartError, "CodeList did not get a suitable start symbol")
-
-#define CodeListEndErrorLog "CodeList did not get EOF/NUL with end"
-#define CodeListEndErrorConsole HT_aFunGetText(SyntacticCodeListEndError, "CodeList did not get EOF/NUL with end")
-
-#define CodeStartErrorLog "Code did not get a suitable start symbol"
-#define CodeStartErrorConsole HT_aFunGetText(SyntacticCodeStartError, "Code did not get a suitable start symbol")
-
-#define CodeBlockEndErrorLog "Code-Block did not get end block symbol with end"
-#define CodeBlockEndErrorConsole HT_aFunGetText(SyntacticCodeBolckEndError, "Code-Block did not get end block symbol with end")
-
-#define MakeCodeFailLog "Make code fail (Maybe by prefix)"
-#define MakeCodeFailConsole HT_aFunGetText(SyntacticMakeCodeFail, "Make code fail (Maybe by prefix)")
-
-#define MakeCodeFailLog "Make code fail (Maybe by prefix)"
-#define MakeCodeFailConsole HT_aFunGetText(SyntacticMakeCodeFail, "Make code fail (Maybe by prefix)")
-
-#define TooDeepLog "Recursion too deep"
-#define TooDeepConsole HT_aFunGetText(SyntacticTooDeep, "Recursion too deep")
-
-#define PrefixErrorLog "The system gets the prefix error"
-#define PrefixErrorConsole HT_aFunGetText(SyntacticPrefixError, "The system gets the prefix error")
-
-/* 封装Reader的错误 */
-#define BOMErrorLog "Parser utf-8 with error BOM"
-#define BOMErrorConsole HT_aFunGetText(ReaderBOMError, "Parser utf-8 with error BOM")
-
-#define FileIOErrorLog "File IO error"
-#define FileIOErrorConsole HT_aFunGetText(ReaderFileIOError, "File IO error")
-
-#define StdinErrorLog "Stdin error/eof"
-#define StdinErrorConsole HT_aFunGetText(ReaderStdinError, "Stdin error/eof")
-
-#define TooMuchInputErrorLog "Too much input for stdin"
-#define TooMuchInputErrorConsole HT_aFunGetText(TooMuchInputError, "Too much input for stdin")
-
-#endif //AFUN_PARSERL_WARNING_ERROR_H

+ 0 - 20
include/core/info/prefix_macro.h

@@ -1,20 +0,0 @@
-/*
- * 文件名: prefix_macro
- * 目标: 前缀的宏定义
- */
-#ifndef AFUN_PREFIX_MACRO_H
-#define AFUN_PREFIX_MACRO_H
-
-#define E_PREFIX "$`'"  /* element前缀 */
-#define B_PREFIX "$`'%^&<?>"  /* block前缀 */
-#define ALL_PREFIX B_PREFIX
-
-// 作为顶层代码,以及'()运行时
-#define E_QUOTE           (0)  /* element前缀: 引用 */
-
-#define B_EXEC            (1)  /* block前缀: 顺序执行 */
-#define B_EXEC_FIRST      (2)  /* block前缀: 顺序执行, 返回第一个 */
-
-#define PREFIX_SIZE       (3)  /* 前缀总数 */
-
-#endif //AFUN_PREFIX_MACRO_H

+ 0 - 46
include/core/info/runtime_error.h

@@ -1,46 +0,0 @@
-/*
- * 文件名: runtime_error.h
- * 目标: 定义aFunlang运行时错误信息
- */
-
-#ifndef AFUN_RUNTIME_ERROR_H
-#define AFUN_RUNTIME_ERROR_H
-
-#define SYNTAX_ERROR "Syntax-Error"
-#define SYNTAX_ERROR_INFO "Block syntax errors." /* block元素不足 */
-
-#define RUN_ERROR "Run-Error"
-#define NOT_CODE_INFO "Not code to run."
-#define FREE_VARSPACE_INFO "Free VarSpace error (VarSpace count error) ." /* 计数释放变量空间时产生错误 */
-#define PURE_EMBEDDED_INFO "Super pure function and super embedded function not to be used together."
-#define IMPLICIT_SET_INFO(name) "Implicit parameter (" #name ") cannot be set."
-#define FUNCBODY_ERROR_INFO "Dynamic function body is not filled."  /* 执行函数体时, 获得func_body_dynamic类型的函数体 */
-#define RETURN_OBJ_NOT_FOUND_INFO "Sequential execution but unable to return the first execution result (The result does not exist)."
-#define NOT_MSG_INFO "Don't get msg after function call."
-#define NOT_NORMAL_MSG_INFO "Don't get normal msg after function call."
-
-#define IMPORT_ERROR "Import-Error"
-#define IMPORT_OBJ_ERROR "Cannot creat an import object."
-
-#define INFIX_PROTECT "Infix-Protect"
-#define LITERAL_ERROR "Literal-Error"
-#define VARIABLE_ERROR "Variable-Error"
-
-#define CALL_ERROR "Call-Error"
-#define BRACKETS_FUNC_BODY_INFO "Brackets cannot get function body."
-#define PARENTHESES_FUNC_BODY_INFO "Parentheses cannot get function body."
-#define CURLY_FUNC_BODY_INFO "Curly cannot get function body."
-
-#define TYPE_ERROR "Type=Error"
-#define API_NOT_FOUND_INFO(name) ("Object API not found: " #name)
-
-#define API_RUN_ERROR "API-Run-Error"
-#define API_DONOT_GIVE(name) ("Object API don't give: " #name)
-
-#define SIGNAL_EXCEPTION "SIGNAL-Exception"
-#define SIGNAL_INT  "SIGINT;"
-#define SIGNAL_TERM "SIGTERM;"
-#define SIGNAL_U1   "SIGU1;"
-#define SIGNAL_U2   "SIGU2;"
-
-#endif //AFUN_RUNTIME_ERROR_H

+ 0 - 23
include/core/info/token.h

@@ -1,23 +0,0 @@
-#ifndef AFUN_TOKEN_H
-#define AFUN_TOKEN_H
-#include "tool.hpp"
-
-enum af_TokenType {
-    TK_ERROR = -1,
-    TK_PREFIX = 0,  // 前缀
-    TK_LP = 1,
-    TK_LB = 2,
-    TK_LC = 3,
-    TK_RP = 4,
-    TK_RB = 5,
-    TK_RC = 6,
-    TK_ELEMENT_SHORT = 7,
-    TK_ELEMENT_LONG = 8,
-    TK_COMMENT = 9,
-    TK_SPACE = 10,
-    TK_EOF = 11,
-};
-
-typedef enum af_TokenType af_TokenType;
-
-#endif //AFUN_TOKEN_H

+ 21 - 0
include/core/init.hpp

@@ -0,0 +1,21 @@
+#ifndef AFUN_INIT_HPP
+#define AFUN_INIT_HPP
+#include "tool.hpp"
+
+namespace aFuncore {
+    struct InitInfo {
+        const std::string &base_dir;
+
+        bool log_asyn;
+        aFuntool::LogLevel level;
+    };
+
+    extern std::string log_path;
+    extern std::string lang_path;
+    extern std::string varlib_path;
+    extern aFuntool::Logger *aFunCoreLogger;
+
+    bool aFunCoreInit(InitInfo *info);
+}
+
+#endif //AFUN_INIT_HPP

+ 0 - 4
include/tool/file.hpp

@@ -4,10 +4,6 @@
 
 /* 文件处理工具 */
 namespace aFuntool {
-    class FileOpenException : public std::exception {
-        virtual const char *what() {return "File cannot open";}
-    };
-
     AFUN_TOOL_EXPORT int checkFile(const std::string &path);
     AFUN_TOOL_EXPORT time_t getFileMTime(const std::string &path);
     AFUN_TOOL_EXPORT std::string joinPath(const std::string &path, const std::string &name, const std::string &suffix);

+ 0 - 7
include/tool/log.hpp

@@ -20,13 +20,6 @@ namespace aFuntool {
     };
     typedef enum LogLevel LogLevel;
 
-    class LogFatalError : public std::exception {
-        std::string message;
-    public:
-        explicit LogFatalError(const char *msg) {message = msg;}
-        virtual const char *what() {return message.c_str();}
-    };
-
     class LogFactory;
 
     class Logger {

+ 4 - 4
include/tool/macro.hpp

@@ -5,9 +5,9 @@
 
 #ifndef AFUN_MACRO_HPP
 #define AFUN_MACRO_HPP
-#include <stdbool.h>
-#include <inttypes.h>
-#include <stdarg.h>
+#include <iostream>
+#include <cinttypes>
+#include <cstdarg>
 #include "base.h"
 
 #ifndef __bool_true_false_are_defined
@@ -21,7 +21,7 @@
 
 namespace aFuntool {
     typedef uint32_t FileLine;  // 文件行号
-    typedef std::string &FilePath;  // 文件路径
+    typedef std::string FilePath;  // 文件路径
     typedef const std::string &ConstFilePath;  // 文件路径
 }
 

+ 1 - 1
include/tool/md5.hpp

@@ -17,7 +17,7 @@ namespace aFuntool {
     AFUN_TOOL_EXPORT void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int input_len);
 
     template <typename T>
-    T getFileMd5(T &path);
+    T getFileMd5 (T &path);
 }
 
 #endif //AFUN_MD5_HPP

+ 4 - 2
include/tool/mem.hpp

@@ -12,7 +12,9 @@
 
 /* 取代calloc函数 */
 namespace aFuntool {
-    static void *safeFree(void *&ptr) {if (ptr != nullptr) free(ptr); ptr = nullptr; return nullptr;}
+    template <typename T>
+    static void *safeFree(T *&ptr) {if (ptr != nullptr) free((void *)ptr); ptr = nullptr; return nullptr;}
+
     static void *safeCalloc(size_t n, size_t size){
         void *re = calloc(n, size);
         if (re == nullptr)
@@ -20,7 +22,7 @@ namespace aFuntool {
         return re;
     }
 
-    template <class T>
+    template <typename T>
     static void *safeCalloc(size_t n, T &t){
         void *re = calloc(n, sizeof(decltype(*t)));  // 自动推断类型
         if (re == nullptr)

+ 2 - 24
include/tool/regex.hpp

@@ -9,34 +9,12 @@
 namespace aFuntool {
     const int REGEX_ERROR_SIZE = 512;
 
-    class RegexException : public std::exception
-    {
-        std::string message = "Regex Error";
-    public:
-        explicit RegexException(std::string &msg) {
-            this->message = "RegexErrpr: " + msg;
-        }
-
-        explicit RegexException(const char *msg) {
-            this->message = std::string("RegexErrpr: ") + msg;
-        }
-
-        virtual const char *what() {
-            return message.c_str();
-        }
-    };
-
-    struct af_Regex {
-        pcre2_code *re;  // 正则表达式
-        char *pattern;  // 正则表达式的字符串
-    };
-
     class Regex {
         pcre2_code *re;  // 正则表达式
         std::string pattern;  // 正则表达式的字符串
     public:
-        explicit Regex(const std::string &pattern);
-        ~Regex();
+        explicit Regex (const std::string &pattern);
+        ~Regex ();
         int match(const char *subject);
     };
 }

+ 26 - 1
include/tool/tool.hpp

@@ -7,10 +7,35 @@
 #ifndef AFUN_TOOL_HPP
 #define AFUN_TOOL_HPP
 
-#include "mem.hpp"
 #include "macro.hpp"
 #include "aFunToolExport.h"
 
+namespace aFuntool {
+    class FileOpenException : public std::exception {
+        std::string msg;
+    public:
+        explicit FileOpenException(ConstFilePath file) {msg = std::string("File cannot open") + file;}
+        virtual const char *what() {return "File cannot open";}
+    };
+
+    class RegexException : public std::exception
+    {
+        std::string message;
+    public:
+        explicit RegexException(const std::string &msg) { this->message = "Regex Error: " + msg;}
+        virtual const char *what() {return message.c_str();}
+    };
+
+    class LogFatalError : public std::exception {
+        std::string message;
+    public:
+        explicit LogFatalError(const char *msg) {message = msg;}
+        virtual const char *what() {return message.c_str();}
+    };
+}
+
+#include "mem.hpp"
+
 #include "stdio_.hpp"
 #include "exit_.hpp"
 #include "btye.hpp"

+ 1 - 1
src/CMakeLists.txt

@@ -25,7 +25,7 @@ unset(build_include_)
 set(install_include $<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}>)
 
 add_subdirectory(tool)
-#add_subdirectory(core)  # core 依赖 tool
+add_subdirectory(core)  # core 依赖 tool
 #add_subdirectory(runtime)  # runtime 依赖 core
 
 # source在子目录中被使用, 为了避免子目录访问到source, 子目录将在此前面被执行

+ 113 - 0
src/core/code.cpp

@@ -0,0 +1,113 @@
+#include "code.hpp"
+#include "init.hpp"
+using namespace aFuncore;
+using namespace aFuntool;
+
+Code::Code(FileLine line, ConstFilePath file){
+    this->type = code_start;
+    this->file = file;
+    this->line = line;
+}
+
+aFuncore::Code::Code(const std::string &element, FileLine line, ConstFilePath file, char prefix){
+    this->type=code_element;
+    this->perfix = prefix;
+    this->file = file;
+    this->line = line;
+
+    if (!isCharUTF8(element)) {
+        errorLog(aFunCoreLogger, "Element not utf-8");
+        this->element = nullptr;
+    } else
+        this->element = strCopy(element.c_str());
+}
+
+Code::Code(BlockType block_type, Code *son, FileLine line, ConstFilePath file, char prefix){
+    this->type=code_block;
+    this->perfix = prefix;
+    this->file = file;
+    this->line = line;
+
+    this->block_type = block_type;
+    this->son = son;
+
+    for (Code *tmp = son; tmp != nullptr; tmp = tmp->next)
+        tmp->father = this;
+}
+
+Code::~Code(){
+    if (type == code_element)
+        safeFree(element);
+}
+
+Code *Code::connect(Code *code){
+    Code *tmp = this;
+    while (tmp->next != nullptr)
+        tmp = tmp->next;
+
+    if (code->type == code_start) {
+        errorLog(aFunCoreLogger, "Code connect with `start`");
+        return tmp;
+    }
+
+    tmp->next = code;
+    code->prev = tmp;
+    while (code->next != nullptr)
+        code = code->next;
+    return code;
+}
+
+void Code::destruct(){
+    if (this->type != code_start) {
+        errorLog(aFunCoreLogger, "Code delete did not with `start`");
+        return;
+    }
+
+    Code *tmp = this;
+    while (tmp->next != nullptr || tmp->father != nullptr) {
+        if (tmp->type == code_element || tmp->son == nullptr)
+            delete tmp;
+        else {
+            tmp = tmp->son;
+            tmp->father->son = nullptr;
+            continue;
+        }
+
+        if (tmp->next == nullptr)
+            tmp = tmp->father;
+        else
+            tmp = tmp->next;
+
+    }
+    delete tmp;
+}
+
+void Code::display(){
+    printf_stdout(0, "%c[father: %p] type=%d %p", perfix == NUL ? '=' : perfix, father, type, this);
+    if (type == code_element)
+        printf_stdout(0, "element: %s\n", element);
+    else
+        printf_stdout(0, "block: %c son: %p\n", block_type, son);
+}
+
+void Code::displayAll(){
+    if (this->type != code_start) {
+        errorLog(aFunCoreLogger, "Code dsplay all did not with `start`");
+        return;
+    }
+
+    Code *tmp = this;
+    while (tmp->next != nullptr || tmp->father != nullptr) {
+        tmp->display();
+        if (tmp->type == code_block && tmp->son != nullptr){
+            tmp = tmp->son;
+            continue;
+        }
+
+        if (tmp->next == nullptr)
+            tmp = tmp->father->next;
+        else
+            tmp = tmp->next;
+    }
+    tmp->display();
+}

+ 66 - 0
src/core/init.cpp

@@ -0,0 +1,66 @@
+#include <clocale>
+#include "init.hpp"
+using namespace aFuncore;
+using namespace aFuntool;
+
+namespace aFuncore {
+    std::string log_path;
+    std::string lang_path;
+    std::string varlib_path;
+    aFuntool::Logger *aFunCoreLogger;
+};
+
+bool aFuncore::aFunCoreInit(aFuncore::InitInfo *info) {
+    if (info == nullptr) {
+        static InitInfo info_default = {.base_dir=".",
+                                        .log_asyn=true,
+                                        .level=log_info};
+        info = &info_default;
+    }
+
+    getEndian();
+    if (setlocale(LC_ALL, "") == nullptr)
+        return false;
+    if (info->base_dir.empty())
+        return false;
+
+    log_path = info->base_dir + SEP + aFunLogDir + SEP;
+    lang_path = info->base_dir + SEP + aFunLangDir + SEP;
+    varlib_path = info->base_dir + SEP + aFunVarLibDir + SEP;
+
+    std::string log = log_path + "aFunlang";
+    bool re = log_factory.initLogSystem(log, info->log_asyn);
+    if (re == 0)
+        return false;
+
+    static aFuntool::Logger logger {"aFunlang-core", info->level};
+    aFuncore::aFunCoreLogger = &logger;
+
+    debugLog(aFunCoreLogger, "aFunCore log path: %s", log_path.c_str());
+    debugLog(aFunCoreLogger, "aFunCore var.lib path: %s", varlib_path.c_str());
+    debugLog(aFunCoreLogger, "aFunCore lang path: %s", lang_path.c_str());
+
+    char LANG_path[218] = {0};
+    snprintf(LANG_path, 218, "%sLANG", lang_path.c_str());
+
+    FILE *LANG_file = fileOpen(LANG_path, "r");
+    if (LANG_file != nullptr) {
+        char LANG[100] = {0};
+        fgets(LANG, 100, LANG_file);
+        if (LANG[strlen(LANG) - 1] == '\n')
+            LANG[strlen(LANG) - 1] = NUL;  // 去除`\n`
+        debugLog(aFunCoreLogger, "language = %s", LANG);
+
+        char LANG_lib[218] = {0};
+        std::string tmp = std::string("%s") + SHARED_PREFIX + "%s" + SHARED_SUFFIX;
+        snprintf(LANG_lib, 218, tmp.c_str(), lang_path.c_str(), LANG);
+        if (HT_initaFunGetText(LANG_lib) == 0)
+            debugLog(aFunCoreLogger, "aFunCore lang init success: %s", LANG_lib);
+        else
+            debugLog(aFunCoreLogger, "aFunCore lang init failed: %s", LANG_lib);
+        fileClose(LANG_file);
+    } else
+        HT_initaFunGetText(nullptr);
+    debugLog(aFunCoreLogger, "aFunCore init success");
+    return true;
+}

+ 1 - 1
src/tool/file.cpp

@@ -133,7 +133,7 @@ std::string aFuntool::getFilePathName(const std::string &path){
 std::string aFuntool::getFilePath(const std::string &path, int dep){
     std::string::size_type point = path.size();
     for (int i = 0; i < dep; i++) {
-        auto tmp = path.rfind(SEP_CH, point);
+        auto tmp = path.rfind(SEP_CH, point - 1);
         if (tmp == std::string::npos)
             break;
         point = tmp;

+ 4 - 5
src/tool/log.cpp

@@ -109,10 +109,9 @@ int aFuntool::LogFactory::initLogSystem(ConstFilePath path, bool is_asyn){
     uintmax_t csv_size = getFileSize(csv_path);
     bool csv_head_write = (checkFile(csv_path) == 0);  // 文件不存在时才写入头部
 
-    log = fileOpen(log_path, (char *)"a");
+    log = fileOpen(log_path, "a");
     if (log == nullptr) {
         perror("ERROR: ");
-        printf("log_path = %s\n", log_path);
         pthread_mutex_unlock(&mutex);
         return 0;
     }
@@ -266,13 +265,13 @@ void aFuntool::LogFactory::writeConsole(LogLevel level,
                                         const char *ti, time_t t,
                                         const char *file, int line, const char *func,
                                         const char *info) {
-#define FORMAT_SHORT "\r* %s[%d] %s %ld (%s:%d) : %s \n"  // 显示到终端, 添加\r回车符确保顶行显示
+#define FORMAT_SHORT "\r* %s[%s] %d %s %ld (%s:%d) : %s \n"  // 显示到终端, 添加\r回车符确保顶行显示
 #define STD_BUF_SIZE (strlen(info) + 1024)
     if (level < log_warning) {
-        printf_stdout(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], tid, ti, t, file, line, info);
+        printf_stdout(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], id, tid, ti, t, file, line, info);
         fflush(stdout);
     } else {
-        printf_stderr(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], tid, ti, t, file, line, info);
+        printf_stderr(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], id, tid, ti, t, file, line, info);
         fflush(stderr);
     }
 #undef FORMAT_SHORT

+ 1 - 1
src/tool/md5.cpp

@@ -199,7 +199,7 @@ T aFuntool::getFileMd5(T &path) {
     unsigned char md5_value[MD5_SIZE];
 
     if ((fd = fileOpen(path, "rb")) == nullptr)
-        throw aFuntool::FileOpenException();
+        throw FileOpenException(path);
 
     char *md5str = calloc(MD5_STRING, char);
     MD5_CTX *md5 = MD5Init();

+ 3 - 1
test/src/CMakeLists.txt

@@ -5,7 +5,7 @@ foreach(src IN LISTS src_list)
     cmake_path(GET src STEM file_name)
     add_executable(${file_name})
     target_sources(${file_name} PRIVATE ${src})
-    target_link_libraries(${file_name} PUBLIC tool-static)  # 链接静态库 (导出所有符号)
+    target_link_libraries(${file_name} PUBLIC core-static)  # 链接静态库 (导出所有符号)
     set_target_properties(${file_name}
                           PROPERTIES OUTPUT_NAME "test_${file_name}")
     target_compile_definitions(${file_name} PRIVATE IN_CTEST)
@@ -25,3 +25,5 @@ add_new_test(tool_exit COMMAND "$<TARGET_FILE:tool_exit>")
 add_new_test(tool_hash COMMAND "$<TARGET_FILE:tool_hash>")
 add_new_test(tool_utf COMMAND "$<TARGET_FILE:tool_utf>")
 set_test_label(tool tool_mem tool_byte tool_dlc tool_regex tool_md5 tool_utf)
+
+add_new_test(core_init COMMAND "$<TARGET_FILE:core_init>")

+ 22 - 0
test/src/core_init.cpp

@@ -0,0 +1,22 @@
+#include "init.hpp"
+using namespace aFuncore;
+using namespace aFuntool;
+
+int main() {
+    std::string base_path = getExedir(1);
+    if (base_path.empty()) {
+        printf_stderr(0, "aFunlang init error.");
+        aFunExit(EXIT_FAILURE);
+    }
+
+    aFuncore::InitInfo info = {.base_dir=base_path,
+                               .log_asyn=true,
+                               .level=log_debug,
+    };
+
+    if (!aFunCoreInit(&info)) {
+        printf_stderr(0, "aFunlang init error.");
+        aFunExit(EXIT_FAILURE);
+    }
+    return 0;
+}

+ 3 - 0
test/src/tool_logger.cpp

@@ -10,5 +10,8 @@ int main(int argc, char **argv){
 
     setlocale(LC_ALL, "");
     log_factory.initLogSystem(base_path + SEP + "aFunlog");
+
+    static auto logger = Logger("Test", aFuntool::log_info);
+    infoLog(&logger, "Test logger");
     aFunExit(0);
 }