Prechádzať zdrojové kódy

refactor & feat: aFuntool封装C版本库

SongZihuan 3 rokov pred
rodič
commit
36b67a71ef
52 zmenil súbory, kde vykonal 743 pridanie a 209 odobranie
  1. 11 7
      cmake/aFunHeader.cmake
  2. 2 2
      include/tool/aFuntool.h
  3. 27 8
      include/tool/byte.h
  4. 9 1
      include/tool/byte.template.h
  5. 10 1
      include/tool/directory.h
  6. 9 1
      include/tool/dlc.h
  7. 8 0
      include/tool/dlc.inline.h
  8. 8 0
      include/tool/dlc.template.h
  9. 16 3
      include/tool/encoding.h
  10. 9 0
      include/tool/encoding.inline.h
  11. 19 6
      include/tool/file.h
  12. 9 1
      include/tool/hash.h
  13. 16 8
      include/tool/log.h
  14. 10 1
      include/tool/log.inline.h
  15. 0 8
      include/tool/macro.h
  16. 14 6
      include/tool/md5.h
  17. 1 1
      include/tool/mem.h
  18. 8 0
      include/tool/mem.template.h
  19. 20 2
      include/tool/path.h
  20. 16 4
      include/tool/str.h
  21. 11 2
      include/tool/tool-exception.h
  22. 8 0
      include/tool/tool-exception.inline.h
  23. 11 0
      include/tool/tool-exit.h
  24. 11 2
      include/tool/tool-logger.h
  25. 10 1
      include/tool/tool-logger.inline.h
  26. 32 0
      include/tool/tool-macro.h
  27. 10 1
      include/tool/tool-regex.h
  28. 9 0
      include/tool/tool-regex.inline.h
  29. 48 17
      include/tool/tool-stdio.h
  30. 64 1
      include/tool/tool-stdio.inline.h
  31. 17 2
      include/tool/tool-time.h
  32. 0 22
      include/tool/tool-type.h
  33. 41 0
      include/tool/tool.h
  34. 23 13
      src/tool/CMakeLists.txt
  35. 11 6
      src/tool/byte.cpp
  36. 8 2
      src/tool/dlc.cpp
  37. 8 2
      src/tool/encoding.cpp
  38. 7 1
      src/tool/exception.cpp
  39. 8 1
      src/tool/exit.cpp
  40. 11 2
      src/tool/file.cpp
  41. 7 1
      src/tool/hash.cpp
  42. 17 7
      src/tool/log.cpp
  43. 8 2
      src/tool/md5.cpp
  44. 7 1
      src/tool/regex.cpp
  45. 73 55
      src/tool/stdio.cpp
  46. 8 2
      src/tool/string.cpp
  47. 7 1
      src/tool/time.cpp
  48. 7 1
      src/tool/tool-logger.cpp
  49. 26 4
      test/src/CMakeLists.txt
  50. 1 0
      test/src/run-code.cpp
  51. 6 0
      test/src/tool-c-hash.c
  52. 6 0
      test/src/tool-c-stdio.c

+ 11 - 7
cmake/aFunHeader.cmake

@@ -13,16 +13,20 @@ generate_export_header(rt-shared
                        EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/aFunlangExport.h"  # 导出的位置
                        BASE_NAME "AFUN_LANG")
 
-target_compile_definitions(tool-static PUBLIC AFUN_TOOL_STATIC_DEFINE=1)  # 静态库需要定义 AFUN_TOOL_STATIC_DEFINE
-target_compile_definitions(core-static PUBLIC AFUN_CORE_STATIC_DEFINE=1)
-target_compile_definitions(rt-static PUBLIC AFUN_LANG_STATIC_DEFINE=1)
+target_compile_definitions(tool-static PUBLIC AFUN_TOOL_STATIC_DEFINE)  # 静态库需要定义 AFUN_TOOL_STATIC_DEFINE
+target_compile_definitions(tool-static-c PUBLIC AFUN_TOOL_STATIC_DEFINE)
+target_compile_definitions(tool-shared-c PRIVATE tool_shared_EXPORTS)
 
-set_property(TARGET tool-shared core-shared rt-shared
+target_compile_definitions(core-static PUBLIC AFUN_CORE_STATIC_DEFINE)
+
+target_compile_definitions(rt-static PUBLIC AFUN_LANG_STATIC_DEFINE)
+
+set_property(TARGET tool-shared tool-shared-c core-shared rt-shared
              PROPERTY C_VISIBILITY_PRESET "hidden")
-set_property(TARGET tool-shared core-shared rt-shared
+set_property(TARGET tool-shared tool-shared-c core-shared rt-shared
              PROPERTY VISIBILITY_INLINES_HIDDEN TRUE)
 
-set_property(TARGET tool-static core-static rt-static
+set_property(TARGET tool-static tool-static-c core-static rt-static
              PROPERTY C_VISIBILITY_PRESET "default")
-set_property(TARGET tool-static core-static rt-static
+set_property(TARGET tool-static tool-static-c core-static rt-static
              PROPERTY VISIBILITY_INLINES_HIDDEN FALSE)

+ 2 - 2
include/tool/aFuntool.h

@@ -7,9 +7,9 @@
 #ifndef AFUN_AFUNTOOL_H
 #define AFUN_AFUNTOOL_H
 
-#include "macro.h"
+#include "tool-macro.h"
 
-#include "tool-type.h"
+#include "tool.h"
 #include "aFunToolExport.h"
 
 #include "tool-exception.h"

+ 27 - 8
include/tool/byte.h

@@ -1,33 +1,52 @@
 #ifndef AFUN_BYTE_H
 #define AFUN_BYTE_H
+#include "aFunToolExport.h"
+
+#ifdef __cplusplus
 #include <cstdio>  // NOLINT
 #include <iostream>
-#include "aFunToolExport.h"
+#else
+#include <stdio.h>
+#endif
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     enum EndianType {
         little_endian = 0,
         big_endian
     };
 
-    AFUN_TOOL_EXPORT extern enum EndianType endian;
-    AFUN_TOOL_EXPORT extern enum EndianType save_as;
+    AFUN_TOOL_C_EXPORT_VAR enum EndianType endian;
+    AFUN_TOOL_C_EXPORT_VAR enum EndianType save_as;
 
-    AFUN_TOOL_EXPORT void getEndian();
+    AFUN_TOOL_C_EXPORT_FUNC void getEndian();
 
+#ifdef __cplusplus
     template <typename T>
-    bool byteWriteInt(FILE *file, T num);;
+    bool byteWriteInt(FILE *file, T num);
+#endif
+
+    AFUN_TOOL_C_EXPORT_FUNC bool byteWriteStr(FILE *file, const char *str);
 
-    AFUN_TOOL_EXPORT bool byteWriteStr(FILE *file, const char *str);
+#ifdef __cplusplus
     AFUN_TOOL_EXPORT bool byteWriteStr(FILE *file, const std::string &str);
+#endif
 
+#ifdef __cplusplus
     template <typename T>
     bool byteReadInt(FILE *file, T *num);
+#endif
 
-    AFUN_TOOL_EXPORT bool byteReadStr(FILE *file, std::string &str);
-    AFUN_TOOL_EXPORT bool byteReadStr(FILE *file, char *&str);
+AFUN_TOOL_EXPORT bool byteReadStr(FILE *file, char **str);
+#ifdef __cplusplus
+    AFUN_TOOL_C_EXPORT_FUNC bool byteReadStr(FILE *file, std::string &str);
+#endif
 
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "byte.template.h"
 

+ 9 - 1
include/tool/byte.template.h

@@ -1,9 +1,13 @@
 #ifndef AFUN_BYTE_TEMPLATE_H
 #define AFUN_BYTE_TEMPLATE_H
+#ifdef __cplusplus
 
 #include "byte.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     /**
      * 写入一个整数
      * @tparam T 整数类型
@@ -53,6 +57,10 @@ namespace aFuntool {
 
         return re == 1;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
-#endif //AFUN_BYTE_TEMPLATE_H
+#endif  // __cplusplus
+#endif // AFUN_BYTE_TEMPLATE_H

+ 10 - 1
include/tool/directory.h

@@ -1,10 +1,14 @@
 #ifndef AFUN_DIRECTORY_H
 #define AFUN_DIRECTORY_H
+#ifdef __cplusplus
+#include <iostream>
 #include "aFunToolExport.h"
-#include "iostream"
 
 /* 文件处理工具 */
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     AFUN_TOOL_EXPORT std::string joinPath(const std::string &path, const std::string &name, const std::string &suffix);
     AFUN_TOOL_EXPORT std::string getFileName(const std::string &path);
     AFUN_TOOL_EXPORT std::string getFilePathName(const std::string &path);
@@ -13,5 +17,10 @@ namespace aFuntool {
     AFUN_TOOL_EXPORT std::string fileNameToVar(const std::string &name);
     AFUN_TOOL_EXPORT std::string findPath(const std::string &path, const std::string &env);
     AFUN_TOOL_EXPORT std::string getExePath();
+
+#ifndef AFUN_TOOL_C
 }
+#endif
+
+#endif
 #endif //AFUN_DIRECTORY_H

+ 9 - 1
include/tool/dlc.h

@@ -1,8 +1,10 @@
 #ifndef AFUN_DLC_H
 #define AFUN_DLC_H
+#ifdef __cplusplus
+
 #include <iostream>
 #include "aFunToolExport.h"
-#include "macro.h"
+#include "tool-macro.h"
 #include "dlfcn.h"  // CMake 处理 dlfcn.h 的位置
 
 /* 动态库工具(dlc): 处理动态库的使用 */
@@ -21,7 +23,10 @@
  * dlcExit: 释放所有动态库
  */
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     class DlcHandle;
 
     template <typename SYMBOL>
@@ -96,9 +101,12 @@ namespace aFuntool {
         AFUN_STATIC Handle *dlc;
     };
 
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "dlc.inline.h"
 #include "dlc.template.h"
 
+#endif
 #endif //AFUN_DLC_H

+ 8 - 0
include/tool/dlc.inline.h

@@ -1,9 +1,13 @@
 #ifndef AFUN_DLC_INLINE_H
 #define AFUN_DLC_INLINE_H
+#ifdef __cplusplus
 
 #include "dlc.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     template<typename SYMBOL>
     DlcSymbol<SYMBOL> DlcHandle::getSymbol(const std::string &name){
         return handle_ != nullptr ? handle_->getSymbol<SYMBOL>(name) : DlcSymbol<SYMBOL>();
@@ -67,6 +71,10 @@ namespace aFuntool {
     bool DlcHandle::Handle::isOpen() const {
         return handle_ != nullptr;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_DLC_INLINE_H

+ 8 - 0
include/tool/dlc.template.h

@@ -4,10 +4,14 @@
 
 #ifndef AFUN_DLC_TEMPLATE_H
 #define AFUN_DLC_TEMPLATE_H
+#ifdef __cplusplus
 
 #include "dlc.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     /**
      * 符号句柄
      * 注意: 不适用符号后需要 delete
@@ -63,6 +67,10 @@ namespace aFuntool {
         SYMBOL *symbol_ = nullptr;
         DlcHandle::Handle *handle_ = nullptr;
     };
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_DLC_TEMPLATE_H

+ 16 - 3
include/tool/encoding.h

@@ -1,13 +1,26 @@
 #ifndef AFUN_ENCODING_H
 #define AFUN_ENCODING_H
-#include <iostream>
 #include "aFunToolExport.h"
-#include "macro.h"
+#include "tool-macro.h"
+
+#ifdef __cplusplus
+#include <iostream>
+#else
+#include <stdio.h>
+#endif
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    AFUN_TOOL_EXPORT bool isCharUTF8(const char *str);
+#endif
+
+    AFUN_TOOL_C_EXPORT_FUNC bool isCharUTF8(const char *str);
+#ifdef __cplusplus
     AFUN_INLINE bool isCharUTF8(const std::string &str);
+#endif
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "encoding.inline.h"
 

+ 9 - 0
include/tool/encoding.inline.h

@@ -1,11 +1,20 @@
 #ifndef AFUN_ENCODING_INLINE_H
 #define AFUN_ENCODING_INLINE_H
+#ifdef __cplusplus
+
 #include "encoding.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     bool isCharUTF8(const std::string &str) {
         return isCharUTF8(str.c_str());
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_ENCODING_INLINE_H

+ 19 - 6
include/tool/file.h

@@ -1,16 +1,29 @@
 #ifndef AFUN_FILE_H
 #define AFUN_FILE_H
-#include "iostream"
 #include "aFunToolExport.h"
 
+#ifdef __cplusplus
+#include <iostream>
+#else
+#include <stdio.h>
+#endif
+
 /* 文件处理工具 */
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    AFUN_TOOL_EXPORT int checkFile(const std::string &path);
-    AFUN_TOOL_EXPORT time_t getFileMTime(const std::string &path);
-    AFUN_TOOL_EXPORT uintmax_t getFileSize(const std::string &path);
+#endif
+
+#ifdef __cplusplus
+    AFUN_TOOL_C_EXPORT_FUNC int checkFile(const std::string &path);
+    AFUN_TOOL_C_EXPORT_FUNC time_t getFileMTime(const std::string &path);
+    AFUN_TOOL_C_EXPORT_FUNC uintmax_t getFileSize(const std::string &path);
     AFUN_TOOL_EXPORT FILE *fileOpen(const std::string &path_, const char *mode_);
-    AFUN_TOOL_EXPORT FILE *fileOpen(const char *path_, const char *mode_);
-    AFUN_TOOL_EXPORT int fileClose(FILE *file);
+#endif
+    AFUN_TOOL_C_EXPORT_FUNC FILE *fileOpen(const char *path_, const char *mode_);
+    AFUN_TOOL_C_EXPORT_FUNC int fileClose(FILE *file);
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif //AFUN_FILE_H

+ 9 - 1
include/tool/hash.h

@@ -3,10 +3,18 @@
 #include "aFunToolExport.h"
 
 /* 哈希工具 */
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     typedef long int time33_t;
-    AFUN_TOOL_EXPORT time33_t time33(const char *str);
+    AFUN_TOOL_C_EXPORT_FUNC time33_t time33(const char *str);
+#ifdef __cplusplus
     AFUN_TOOL_EXPORT time33_t time33(const std::string &str);
+#endif
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif //AFUN_HASH_H

+ 16 - 8
include/tool/log.h

@@ -1,19 +1,22 @@
 #ifndef AFUN_LOG_H
 #define AFUN_LOG_H
+#ifdef __cplusplus
 
 #include <iostream>
 #include "aFunToolExport.h"
-#include "macro.h"
+#include "tool-macro.h"
 
-#include "tool-type.h"
-#include "thread"
-#include "mutex"
-#include "condition_variable"
+#include "tool.h"
+#include <thread>
+#include <mutex>
+#include <condition_variable>
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-#ifndef __pid_t_defined
+#endif
+
+#ifdef _MSC_VER
     typedef int pid_t;
-#define __pid_t_defined
 #endif
 
     enum LogLevel {
@@ -51,7 +54,7 @@ namespace aFuntool {
     class AFUN_TOOL_EXPORT LogFactory {
     public:
         Logger sys_log = Logger(*this, "SYSTEM");
-        LogFactory(const aFuntool::FilePath &path, bool is_async) noexcept(false);
+        LogFactory(const FilePath &path, bool is_async) noexcept(false);
         ~LogFactory();
         LogFactory(const LogFactory &)=delete;
         LogFactory &operator=(const LogFactory &)=delete;
@@ -98,7 +101,10 @@ namespace aFuntool {
         LogFactory &factor;
         std::mutex &mutex;
     };
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "log.inline.h"
 
@@ -156,4 +162,6 @@ namespace aFuntool {
 #endif
 
 #endif
+
+#endif  // __cplusplus
 #endif //AFUN_LOG_H

+ 10 - 1
include/tool/log.inline.h

@@ -1,12 +1,21 @@
 #ifndef AFUN_LOG_INLINE_H
 #define AFUN_LOG_INLINE_H
+#ifdef __cplusplus
+
 #include "log.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    aFuntool::Logger::Logger(LogFactory &factor, std::string id, LogLevel level, bool exit) noexcept
+#endif
+
+    Logger::Logger(LogFactory &factor, std::string id, LogLevel level, bool exit) noexcept
         : factor_{factor}, id_{std::move(id)}, level_{level}, exit_{exit} {
 
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_LOG_INLINE_H

+ 0 - 8
include/tool/macro.h

@@ -1,8 +0,0 @@
-#ifndef AFUN_MACRO_H
-#define AFUN_MACRO_H
-
-#define AFUN_STATIC [[maybe_unused]] static
-#define AFUN_INLINE [[maybe_unused]] inline
-#define AFUN_NULL ((void)0)
-
-#endif //AFUN_MACRO_H

+ 14 - 6
include/tool/md5.h

@@ -1,24 +1,32 @@
 #ifndef AFUN_MD5_H
 #define AFUN_MD5_H
 #include "aFunToolExport.h"
-#include "macro.h"
+#include "tool-macro.h"
 
 /* md5计算工具 */
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     AFUN_STATIC const size_t READ_DATA_SIZE = 1024;
     AFUN_STATIC const size_t MD5_SIZE = 16;
-    AFUN_STATIC const size_t MD5_STR_LEN = MD5_SIZE * 2;
-    AFUN_STATIC const size_t MD5_STRING = MD5_STR_LEN + 1;
+    AFUN_STATIC const size_t MD5_STR_LEN = 16 * 2;
+    AFUN_STATIC const size_t MD5_STRING = (16 * 2) + 1;
 
     typedef struct MD5_CTX MD5_CTX;
 
-    AFUN_TOOL_EXPORT MD5_CTX *MD5Init();
-    AFUN_TOOL_EXPORT void MD5Final(MD5_CTX *context, unsigned char digest[16]);
-    AFUN_TOOL_EXPORT void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int input_len);
+    AFUN_TOOL_C_EXPORT_FUNC MD5_CTX *MD5Init();
+    AFUN_TOOL_C_EXPORT_FUNC void MD5Final(MD5_CTX *context, unsigned char digest[16]);
+    AFUN_TOOL_C_EXPORT_FUNC void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int input_len);
 
+#ifdef __cplusplus
     template <typename T>
     T getFileMd5 (T &path) noexcept(false) ;
+#endif
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif //AFUN_MD5_H

+ 1 - 1
include/tool/mem.h

@@ -8,4 +8,4 @@
 
 #include "mem.template.h"
 
-#endif  // AFUN_MEM_H
+#endif  // AFUN_MEM_H

+ 8 - 0
include/tool/mem.template.h

@@ -1,5 +1,6 @@
 #ifndef AFUN_MEM_TEMPLATE_H
 #define AFUN_MEM_TEMPLATE_H
+#ifdef __cplusplus
 
 #include <cstdlib>
 #include "log.h"
@@ -7,7 +8,10 @@
 #include "tool-logger.h"
 
 /* 取代calloc函数 */
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     template <typename T = void *>
     T *safeFree(T *ptr) {if (ptr != nullptr) free((void *)ptr); return nullptr;}
 
@@ -34,6 +38,10 @@ namespace aFuntool {
         }
         return re;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_MEM_TEMPLATE_H

+ 20 - 2
include/tool/path.h

@@ -1,26 +1,41 @@
 #ifndef AFUN_PATH_H
 #define AFUN_PATH_H
-#include "macro.h"
-#include "tool-type.h"
+#include "tool-macro.h"
+#include "tool.h"
 
 /* 路径工具 */
 #ifdef AFUN_WIN32_NO_CYGWIN
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     AFUN_STATIC const char *SEP = "\\";
     AFUN_STATIC const char SEP_CH = '\\';
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #else
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     AFUN_STATIC const char *SEP = "/";
     AFUN_STATIC const char SEP_CH = '/';
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     AFUN_STATIC const char *SHARED_PREFIX = AFUN_SHARE_PREFIX;
     AFUN_STATIC const char *SHARED_SUFFIX = AFUN_SHARE_SUFFIX;
 
@@ -28,6 +43,9 @@ namespace aFuntool {
     AFUN_STATIC const char *STATIC_SUFFIX = AFUN_STATIC_SUFFIX;
 
     AFUN_STATIC const char *EXE_SUFFIX = AFUN_EXE_SUFFIX;
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif //AFUN_PATH_H

+ 16 - 4
include/tool/str.h

@@ -1,15 +1,27 @@
 #ifndef AFUN_STR_H
 #define AFUN_STR_H
+#include "aFunToolExport.h"
+
+#ifdef __cplusplus
 #include <cwchar>
 #include <cstring>
-#include "aFunToolExport.h"
+#else
+#include <wchar.h>
+#include <string.h>
+#endif
 
 /* 字符串工具 */
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    AFUN_TOOL_EXPORT char *charToStr(char ch);
-    AFUN_TOOL_EXPORT char *strCopy(const char *str);
-    AFUN_TOOL_EXPORT char *strJoin(const char *first, const char *second, bool free_first, bool free_last);
+#endif
+
+    AFUN_TOOL_C_EXPORT_FUNC char *charToStr(char ch);
+    AFUN_TOOL_C_EXPORT_FUNC char *strCopy(const char *str);
+    AFUN_TOOL_C_EXPORT_FUNC char *strJoin(const char *first, const char *second, bool free_first, bool free_last);
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif //AFUN_STR_H

+ 11 - 2
include/tool/tool-exception.h

@@ -1,10 +1,15 @@
 #ifndef AFUN_TOOL_EXCEPTION_H
 #define AFUN_TOOL_EXCEPTION_H
+#ifdef __cplusplus
+
 #include "aFunToolExport.h"
-#include "macro.h"
-#include "tool-type.h"
+#include "tool-macro.h"
+#include "tool.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     class AFUN_TOOL_EXPORT aFunException : public std::exception {
         std::string message;
     public:
@@ -39,8 +44,12 @@ namespace aFuntool {
         AFUN_INLINE explicit Exit(int exit_code_);
         AFUN_INLINE int getExitCode() const;
     };
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "tool-exception.inline.h"
 
+#endif
 #endif //AFUN_TOOL_EXCEPTION_H

+ 8 - 0
include/tool/tool-exception.inline.h

@@ -1,9 +1,13 @@
 #ifndef AFUN_TOOL_EXCEPTION_INLINE_H
 #define AFUN_TOOL_EXCEPTION_INLINE_H
+#ifdef __cplusplus
 
 #include "tool-exception.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     aFunException::aFunException(std::string msg) : message{std::move(msg)} {
 
     }
@@ -35,6 +39,10 @@ namespace aFuntool {
     int Exit::getExitCode() const {
         return exit_code;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_TOOL_EXCEPTION_INLINE_H

+ 11 - 0
include/tool/tool-exit.h

@@ -1,17 +1,28 @@
 #ifndef AFUN_EXIT_H
 #define AFUN_EXIT_H
+#ifdef __cplusplus
+
 #include <functional>
 #include "aFunToolExport.h"
+#include "tool-macro.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     typedef std::function<void(void *)> aFunExitFunc;
 
     AFUN_TOOL_EXPORT void aFunExit(int exit_code) noexcept(false);
     [[noreturn]] AFUN_TOOL_EXPORT void aFunExitReal(int exit_code);
     AFUN_TOOL_EXPORT bool aFunTryExitPseudo();
     AFUN_TOOL_EXPORT void aFunExitPseudo();
+
     AFUN_TOOL_EXPORT bool aFunAtExitTry(aFunExitFunc func, void *data);
     AFUN_TOOL_EXPORT void aFunAtExit(aFunExitFunc func, void *data);
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_EXIT_H

+ 11 - 2
include/tool/tool-logger.h

@@ -1,15 +1,24 @@
 #ifndef AFUN_TOOL_LOGGER_H
 #define AFUN_TOOL_LOGGER_H
+#ifdef __cplusplus
+
 #include "aFunToolExport.h"
-#include "macro.h"
+#include "tool-macro.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     class Logger;
     extern AFUN_TOOL_EXPORT class Logger *aFunSysLogger;
 
-    AFUN_STATIC void setSysLogger(aFuntool::Logger *log);
+    AFUN_STATIC void setSysLogger(Logger *log);
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "tool-logger.inline.h"
 
+#endif
 #endif //AFUN_TOOL_LOGGER_H

+ 10 - 1
include/tool/tool-logger.inline.h

@@ -1,11 +1,20 @@
 #ifndef AFUN_TOOL_LOGGER_INLINE_H
 #define AFUN_TOOL_LOGGER_INLINE_H
+#ifdef __cplusplus
+
 #include "tool-logger.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    void setSysLogger(aFuntool::Logger *log) {
+#endif
+
+    void setSysLogger(Logger *log) {
         aFunSysLogger = log;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_TOOL_LOGGER_INLINE_H

+ 32 - 0
include/tool/tool-macro.h

@@ -0,0 +1,32 @@
+#ifndef AFUN_TOOL_MACRO_H
+#define AFUN_TOOL_MACRO_H
+
+#ifdef __cplusplus
+#define AFUN_STATIC [[maybe_unused]] static
+#define AFUN_INLINE [[maybe_unused]] inline
+#else
+#ifdef _MSC_VER
+#define AFUN_STATIC static
+#define AFUN_INLINE inline
+#else
+#define AFUN_STATIC __attribute__((unused)) static
+#define AFUN_INLINE __attribute__((unused)) inline
+#endif
+#endif
+
+#define AFUN_NULL ((void)0)
+
+#ifdef __cplusplus
+#ifdef AFUN_TOOL_C
+#define AFUN_TOOL_C_EXPORT_FUNC extern "C"
+#define AFUN_TOOL_C_EXPORT_VAR  extern "C"
+#else
+#define AFUN_TOOL_C_EXPORT_FUNC AFUN_TOOL_EXPORT
+#define AFUN_TOOL_C_EXPORT_VAR AFUN_TOOL_EXPORT extern
+#endif
+#else
+#define AFUN_TOOL_C_EXPORT_FUNC AFUN_TOOL_EXPORT
+#define AFUN_TOOL_C_EXPORT_VAR AFUN_TOOL_EXPORT extern
+#endif
+
+#endif //AFUN_TOOL_MACRO_H

+ 10 - 1
include/tool/tool-regex.h

@@ -1,10 +1,15 @@
 #ifndef AFUN_TOOL_REGEX
 #define AFUN_TOOL_REGEX
+#ifdef __cplusplus
+
 #define PCRE2_CODE_UNIT_WIDTH 8
 #include "pcre2.h"
-#include "macro.h"
+#include "tool-macro.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     class AFUN_TOOL_EXPORT Regex {  // 整个对象都是inline的, 不需要Export符号
         std::string pattern;  // 正则表达式的字符串
         pcre2_code *re;  // 正则表达式
@@ -18,8 +23,12 @@ namespace aFuntool {
 
         [[nodiscard]] bool match(const std::string &subject) const;
     };
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #include "tool-regex.inline.h"
 
+#endif
 #endif //AFUN_TOOL_REGEX

+ 9 - 0
include/tool/tool-regex.inline.h

@@ -1,8 +1,13 @@
 #ifndef AFUN_TOOL_REGEX_INLINE_H
 #define AFUN_TOOL_REGEX_INLINE_H
+#ifdef __cplusplus
+
 #include "tool-regex.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     Regex::Regex(const Regex &regex) noexcept: Regex(regex.pattern) {
 
     }
@@ -15,6 +20,10 @@ namespace aFuntool {
         if (re != nullptr)
             pcre2_code_free(re);
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
+#endif
 #endif //AFUN_TOOL_REGEX_INLINE_H

+ 48 - 17
include/tool/tool-stdio.h

@@ -1,18 +1,29 @@
 #ifndef AFUN_STDIO_H
 #define AFUN_STDIO_H
+#include "aFunToolExport.h"
+#include "tool-macro.h"
+#include "tool.h"
+
+#ifdef __cplusplus
 #include <cstdio>
 #include <cinttypes>
-#include "aFunToolExport.h"
-#include "macro.h"
-#include "tool-type.h"
+#else
+#include <stdio.h>
+#include <inttypes.h>
+#endif
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    AFUN_TOOL_EXPORT int fgets_stdin(char **dest, int len);
-    AFUN_TOOL_EXPORT bool checkStdin();
-    AFUN_TOOL_EXPORT bool fclear_stdin();
+#endif
+
+    AFUN_TOOL_C_EXPORT_FUNC int fgets_stdin(char **dest, int len);
+    AFUN_TOOL_C_EXPORT_FUNC bool checkStdin();
+    AFUN_TOOL_C_EXPORT_FUNC bool fclear_stdin();
     AFUN_STATIC bool clear_ferror(FILE *file);
     AFUN_STATIC bool clear_stdin();
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #ifdef AFUN_WIN32_NO_CYGWIN
 
@@ -23,34 +34,43 @@ namespace aFuntool {
 #include <io.h>
 #include <Windows.h>
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    AFUN_TOOL_EXPORT void stdio_signal_init(bool signal);
-    AFUN_TOOL_EXPORT bool stdio_check_signal();
+#endif
+
+    AFUN_TOOL_C_EXPORT_FUNC void stdio_signal_init(bool signal);
+    AFUN_TOOL_C_EXPORT_FUNC bool stdio_check_signal();
 
-    AFUN_TOOL_EXPORT int convertMultiByte(char **dest, const char *str, UINT from, UINT to);  // win32 特有函数
-    AFUN_TOOL_EXPORT int convertWideByte(wchar_t **dest, const char *str, UINT from);  // win32 特有函数
-    AFUN_TOOL_EXPORT int convertFromWideByte(char **dest, const wchar_t *str, UINT to);
+    AFUN_TOOL_C_EXPORT_FUNC int convertMultiByte(char **dest, const char *str, UINT from, UINT to);  // win32 特有函数
+    AFUN_TOOL_C_EXPORT_FUNC int convertWideByte(wchar_t **dest, const char *str, UINT from);  // win32 特有函数
+    AFUN_TOOL_C_EXPORT_FUNC int convertFromWideByte(char **dest, const wchar_t *str, UINT to);
 
-    AFUN_TOOL_EXPORT int fgetc_stdin();
-    AFUN_TOOL_EXPORT char *fgets_stdin_(char *buf, size_t len);
-    AFUN_TOOL_EXPORT int fungetc_stdin(int ch);
+    AFUN_TOOL_C_EXPORT_FUNC int fgetc_stdin();
+    AFUN_TOOL_C_EXPORT_FUNC char *fgets_stdin_(char *buf, size_t len);
+    AFUN_TOOL_C_EXPORT_FUNC int fungetc_stdin(int ch);
 
-    AFUN_TOOL_EXPORT int fputs_std_(const char *str, FILE *std);
+    AFUN_TOOL_C_EXPORT_FUNC int fputs_std_(const char *str, FILE *std);
     AFUN_STATIC int fputs_stdout(const char *str);
     AFUN_STATIC int fputs_stderr(const char *str);
 
-    AFUN_TOOL_EXPORT size_t vprintf_std_(FILE *std, size_t buf_len, const char *format, va_list ap);
+    AFUN_TOOL_C_EXPORT_FUNC size_t vprintf_std_(FILE *std, size_t buf_len, const char *format, va_list ap);
 
     AFUN_STATIC size_t vprintf_stderr(size_t buf_len, const char *format, va_list ap);
     AFUN_STATIC size_t vprintf_stdout(size_t buf_len, const char *format, va_list ap);
 
     AFUN_STATIC size_t printf_stdout(size_t buf_len, const char *format, ...);
     AFUN_STATIC size_t printf_stderr(size_t buf_len, const char *format, ...);
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #else
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     AFUN_STATIC int fgetc_stdin();
     AFUN_STATIC int fgets_stdin_(char *buf, int len, FILE *file);
     AFUN_STATIC int fungetc_stdin(char ch);
@@ -63,16 +83,23 @@ namespace aFuntool {
 
     AFUN_STATIC size_t printf_stdout(size_t, const char *format, ...);
     AFUN_STATIC size_t printf_stderr(size_t, const char *format, ...);
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif
 
+#ifdef __cplusplus
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     class OutStream {
         typedef size_t PrintFunction(size_t, const char *, ...);
         PrintFunction *func;
     public:
-        AFUN_INLINE explicit OutStream(PrintFunction *func_);
+        AFUN_INLINE explicit OutStream(PrintFunction *func_) noexcept;
         AFUN_INLINE OutStream &operator<<(char a);
         AFUN_INLINE OutStream &operator<<(signed char a);
         AFUN_INLINE OutStream &operator<<(short a);
@@ -94,7 +121,11 @@ namespace aFuntool {
 
     AFUN_TOOL_EXPORT extern OutStream cout;
     AFUN_TOOL_EXPORT extern OutStream cerr;
+
+#ifndef AFUN_TOOL_C
 }
+#endif
+#endif  // __cplusplus
 
 #include "tool-stdio.inline.h"
 

+ 64 - 1
include/tool/tool-stdio.inline.h

@@ -3,7 +3,10 @@
 
 #include "tool-stdio.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     bool clear_ferror(FILE *file) {
         return ferror(file) && (clearerr(file), ferror(file));
     }
@@ -12,10 +15,16 @@ namespace aFuntool {
         return (ferror(stdin) || feof(stdin)) &&
                (clearerr(stdin), (ferror(stdin) || feof(stdin)));
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #ifdef AFUN_WIN32_NO_CYGWIN
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     int fputs_stdout(const char *str) {
         return fputs_std_(str, stdout);
     }
@@ -46,9 +55,20 @@ namespace aFuntool {
         va_end(ap);
         return re;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
+
 #else
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
+#ifndef __cplusplus
+#define nullptr NULL
+#endif
+
     int fgetc_stdin(){
         return fgetc(stdout);
     }
@@ -69,6 +89,7 @@ namespace aFuntool {
         return fputs(str, stderr);
     }
 
+#ifdef __cplusplus
     int vprintf_stdout(size_t, const char *format, va_list ap){
         return vfprintf(stdout, format, ap);
     }
@@ -92,12 +113,50 @@ namespace aFuntool {
         va_end(ap);
         return re;
     }
+
+#else  // C 不允许省略形参名
+    int vprintf_stdout(size_t _, const char *format, va_list ap){
+        (void)_;  // 确保参数被使用
+        return vfprintf(stdout, format, ap);
+    }
+
+    int vprintf_stderr(size_t _, const char *format, va_list ap){
+        (void)_;  // 确保参数被使用
+        return vfprintf(stderr, format, ap);
+    }
+
+    size_t printf_stdout(size_t _, const char *format, ...) {
+        (void)_;  // 确保参数被使用
+        va_list ap;
+        va_start(ap, format);
+        size_t re = vfprintf(stdout, format, ap);
+        va_end(ap);
+        return re;
+    }
+
+    size_t printf_stderr(size_t _, const char *format, ...) {
+        (void)_;  // 确保参数被使用
+        va_list ap;
+        va_start(ap, format);
+        size_t re = vfprintf(stderr, format, ap);
+        va_end(ap);
+        return re;
+    }
+
+#endif
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #endif
 
+#ifdef __cplusplus
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    OutStream::OutStream(PrintFunction *func_) : func {func_} {
+#endif
+
+    OutStream::OutStream(PrintFunction *func_) noexcept : func {func_} {
 
     }
 
@@ -185,6 +244,10 @@ namespace aFuntool {
         func(0, "%lf", a);
         return *this;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
+#endif  // __cplusplus
 
 #endif //AFUN_STDIO_INLINE_H

+ 17 - 2
include/tool/tool-time.h

@@ -2,10 +2,25 @@
 #define AFUN_TIME_H
 #include "aFunToolExport.h"
 
+#if __cplusplus
+#include <ctime>
+#else
+#include "time.h"
+#endif
+
 /* 时间工具 */
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    AFUN_TOOL_EXPORT void safeSleep(double ms);
-    AFUN_TOOL_EXPORT char *getTime(time_t *t, const char *format);
+#endif
+
+    AFUN_TOOL_C_EXPORT_FUNC void safeSleep(double ms);
+    AFUN_TOOL_C_EXPORT_FUNC char *getTime(time_t *t, const char *format);
+
+#ifdef __cplusplus
     AFUN_TOOL_EXPORT std::string getTime(time_t *t, const std::string &format);
+#endif
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 #endif //AFUN_TIME_H

+ 0 - 22
include/tool/tool-type.h

@@ -1,22 +0,0 @@
-/*
- * 文件名: macro.h
- * 目标: 定义公共宏 和 公共头文件
- */
-
-#ifndef AFUN_TOOL_TYPE_H
-#define AFUN_TOOL_TYPE_H
-#include <iostream>
-#include <cinttypes>
-#include <cstdarg>
-#include "macro.h"
-
-namespace aFuntool {
-    AFUN_STATIC const char NUL = 0;
-
-    typedef uint32_t FileLine;  // 文件行号
-    typedef std::string FilePath;  // 文件路径
-}
-
-#include "mem.h"
-
-#endif //AFUN_TOOL_TYPE_H

+ 41 - 0
include/tool/tool.h

@@ -0,0 +1,41 @@
+/*
+ * 文件名: macro.h
+ * 目标: 定义公共宏 和 公共头文件
+ */
+
+#ifndef AFUN_TOOL_H
+#define AFUN_TOOL_H
+#include "tool-macro.h"
+
+#ifdef __cplusplus
+#include <iostream>
+#include <cinttypes>
+#include <cstdarg>
+#else
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#endif
+
+#ifndef AFUN_TOOL_C
+namespace aFuntool {
+#endif
+
+#ifndef __cplusplus
+    #include "stdbool.h"
+#endif
+
+    AFUN_STATIC const char NUL = 0;
+    typedef uint32_t FileLine;  // 文件行号
+
+#ifdef __cplusplus
+    typedef std::string FilePath;  // 文件路径
+#endif
+
+#ifndef AFUN_TOOL_C
+}
+#endif
+
+#include "mem.h"  // 该定义需要放到下面
+
+#endif //AFUN_TOOL_H

+ 23 - 13
src/tool/CMakeLists.txt

@@ -25,9 +25,19 @@ endforeach()
 
 add_library(tool-shared SHARED "")
 add_library(tool-static STATIC "")
+add_library(tool-shared-c SHARED "")
+add_library(tool-static-c STATIC "")
 
 # 基础宏定义
-set(definitions)
+set(definitions
+        SYSTEM_NAME="${CMAKE_SYSTEM_NAME}"
+        COMPILER_CXX_ID="${CMAKE_CXX_COMPILER_ID}"
+        COMPILER_C_ID="${CMAKE_C_COMPILER_ID}"
+        AFUN_SHARE_PREFIX="${CMAKE_SHARED_LIBRARY_PREFIX}"
+        AFUN_SHARE_SUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}"
+        AFUN_STATIC_PREFIX="${CMAKE_STATIC_LIBRARY_PREFIX}"
+        AFUN_STATIC_SUFFIX="${CMAKE_STATIC_LIBRARY_SUFFIX}"
+        AFUN_EXE_SUFFIX="${CMAKE_EXECUTABLE_SUFFIX}")
 if (WIN32 OR CYGWIN)
     list(APPEND definitions AFUN_WIN32)
 endif()
@@ -41,27 +51,27 @@ if (CMAKE_BUILD_TYPE STREQUAL Debug)
     list(APPEND definitions AFUN_DEBUG)
 endif()
 
-foreach(tgt tool-shared tool-static)
+foreach(tgt tool-shared tool-static tool-shared-c tool-static-c)
     target_sources(${tgt} PRIVATE ${source} ${private_h} PUBLIC ${public_h_build} ${public_h_install})
     target_include_directories(${tgt} PUBLIC ${build_include} ${install_include})
-    target_compile_definitions(${tgt}
-            PUBLIC
-                ${definitions}
-                SYSTEM_NAME="${CMAKE_SYSTEM_NAME}"
-                COMPILER_CXX_ID="${CMAKE_CXX_COMPILER_ID}"
-                COMPILER_C_ID="${CMAKE_C_COMPILER_ID}"
-                AFUN_SHARE_PREFIX="${CMAKE_SHARED_LIBRARY_PREFIX}"
-                AFUN_SHARE_SUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}"
-                AFUN_STATIC_PREFIX="${CMAKE_STATIC_LIBRARY_PREFIX}"
-                AFUN_STATIC_SUFFIX="${CMAKE_STATIC_LIBRARY_SUFFIX}"
-                AFUN_EXE_SUFFIX="${CMAKE_EXECUTABLE_SUFFIX}")
+    target_compile_definitions(${tgt} PUBLIC ${definitions})
     set_target_properties(${tgt} PROPERTIES PUBLIC_HEADER "${public_h_build}")
     target_link_libraries(${tgt} PUBLIC ${dlfcn_lib} PCRE2::8BIT Threads::Threads)
     define_FILENAME(${tgt})
 endforeach()
 
+foreach(tgt tool-shared tool-static)
+    target_compile_definitions(${tgt} PUBLIC ${definitions})
+endforeach()
+
+foreach(tgt tool-shared-c tool-static-c)
+    target_compile_definitions(${tgt} PUBLIC ${definitions} AFUN_TOOL_C)
+endforeach()
+
 set_target_properties(tool-shared PROPERTIES OUTPUT_NAME "aFuntool")
 set_target_properties(tool-static PROPERTIES OUTPUT_NAME "aFuntool-s")
+set_target_properties(tool-shared-c PROPERTIES OUTPUT_NAME "aFuntool-c")
+set_target_properties(tool-static-c PROPERTIES OUTPUT_NAME "aFuntool-sc")
 
 #install(TARGETS tool-shared tool-static
 #        EXPORT aFunlang

+ 11 - 6
src/tool/byte.cpp

@@ -2,10 +2,13 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
-#include "tool-type.h"
+#include "tool.h"
 #include "byte.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     enum EndianType endian = little_endian;
     enum EndianType save_as = little_endian;  // 默认以小端序存储
 
@@ -50,18 +53,18 @@ namespace aFuntool {
     /**
      * 读取一个C风格字符串
      */
-    bool byteReadStr(FILE *file, char *&str){
+    bool byteReadStr(FILE *file, char **str){
         uint16_t len;
         if (!byteReadInt<uint16_t>(file, &len))
             return false;
 
         if (len == 0) {
-            str = nullptr;
+            *str = nullptr;
             return true;
         }
 
-        str = safeCalloc<char>(len + 1);
-        return fread(str, sizeof(char), len, file) == len;
+        *str = safeCalloc<char>(len + 1);
+        return fread(*str, sizeof(char), len, file) == len;
     }
 
     /**
@@ -84,4 +87,6 @@ namespace aFuntool {
         return ret == len;
     }
 
-}
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 8 - 2
src/tool/dlc.cpp

@@ -1,7 +1,10 @@
-#include "tool-type.h"
+#include "tool.h"
 #include "dlc.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     DlcHandle::Handle *DlcHandle::dlc = nullptr;
 
     /**
@@ -72,4 +75,7 @@ namespace aFuntool {
             dlc = next;
         }
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 8 - 2
src/tool/encoding.cpp

@@ -1,7 +1,10 @@
-#include "tool-type.h"
+#include "tool.h"
 #include "encoding.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     /**
      * 检查给定字符串是否utf-8编码
      * @param str 字符串
@@ -36,4 +39,7 @@ namespace aFuntool {
 
         return true;
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 7 - 1
src/tool/exception.cpp

@@ -1,7 +1,13 @@
 #include "tool-exception.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     const char *aFunException::what() const noexcept {
         return message.c_str();
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 8 - 1
src/tool/exit.cpp

@@ -4,7 +4,10 @@
 #include "tool-exit.h"
 #include "tool-exception.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     class ExitManager {
     public:
         ExitManager() noexcept : exit_mutex{},  data{} {
@@ -77,6 +80,7 @@ namespace aFuntool {
         exit(exit_code);
     }
 
+
     /**
      * 尝试执行退出函数
      */
@@ -109,4 +113,7 @@ namespace aFuntool {
     void aFunAtExit(aFunExitFunc func, void *data){
         manager.pushExitData(std::move(func), data);
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 11 - 2
src/tool/file.cpp

@@ -1,4 +1,5 @@
-#include "tool-type.h"
+#include <cstring>
+#include "tool.h"
 #include "file.h"
 #include "tool-stdio.h"
 
@@ -7,8 +8,10 @@
 #pragma warning(disable : 5105)  // 关闭 5105 的警告输出 (Windows.h中使用)
 #endif
 #include <Windows.h>
+#include <sys/stat.h>
 #else
 #include <unistd.h>
+#include <sys/stat.h>
 #endif
 
 #ifndef S_ISREG
@@ -19,7 +22,10 @@
 #define	S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
 #endif
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
 #ifdef AFUN_WIN32_NO_CYGWIN
     typedef struct _stat64 aFun_stat;
     typedef wchar_t aFun_path;
@@ -127,4 +133,7 @@ namespace aFuntool {
     int fileClose(FILE *file) {
         return fclose(file);
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 7 - 1
src/tool/hash.cpp

@@ -3,10 +3,13 @@
  * 目标: 关于哈希表的实用函数
  */
 
-#include "tool-type.h"
+#include "tool.h"
 #include "hash.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     time33_t time33(const char *str){
         unsigned int hash = 5381;
         while (*str)
@@ -20,4 +23,7 @@ namespace aFuntool {
             hash += (hash << 5) + ch;
         return (hash & 0x7FFFFFFF);  // NOLINT
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif

+ 17 - 7
src/tool/log.cpp

@@ -14,7 +14,7 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstdarg>
-#include "tool-type.h"
+#include "tool.h"
 #include "log.h"
 #include "tool-exception.h"
 #include "log-macro.h"
@@ -38,7 +38,10 @@
 #define getpid() static_cast<long>(getpid())
 #endif
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     typedef struct LogNode LogNode;
     struct LogNode {  // 日志信息记录节点
         LogLevel level = log_info;
@@ -56,7 +59,7 @@ namespace aFuntool {
 
     void staticAnsyWritrLog(LogFactory::ansyData *data);
 
-    LogFactory::LogFactory(const aFuntool::FilePath &path, bool is_async) noexcept(false)
+    LogFactory::LogFactory(const FilePath &path, bool is_async) noexcept(false)
         : sys_log{*this, "SYSTEM", log_info}{
         std::unique_lock<std::mutex> ul{mutex_};
 
@@ -81,7 +84,7 @@ namespace aFuntool {
         if (csv_ == nullptr)
             throw FileOpenException(csv_path);
 
-#define CSV_FORMAT "%s,%s,%d,%d,%s,%lld,%s,%d,%s,%s\n"
+#define CSV_FORMAT "%s,%s,%lld,%lld,%s,%lld,%s,%d,%s,%s\n"
 #define CSV_TITLE  "Level,Logger,PID,TID,Data,Timestamp,File,Line,Function,Log\n"
         if (csv_head_write) {
             fprintf(csv_, CSV_TITLE);  // 设置 cvs 标题
@@ -166,14 +169,18 @@ namespace aFuntool {
                               const char *ti, time_t t,
                               const char *file, int line, const char *func,
                               const char *info){
-#define FORMAT "%s/[%s] %d %d {%s %lld} (%s:%d at %s) : '%s' \n"
+#define FORMAT "%s/[%s] %lld %lld {%s %lld} (%s:%d at %s) : '%s' \n"
         /* 写入文件日志 */
         if (log_ != nullptr) {
-            fprintf(log_, FORMAT, LogLevelName[level], id, pid_, tid, ti, static_cast<long long>(t), file, line, func, info);
+            fprintf(log_, FORMAT, LogLevelName[level], id,
+                    static_cast<long long>(pid_), static_cast<long long>(tid), ti,
+                    static_cast<long long>(t), file, line, func, info);
             fflush(log_);
         }
         if (csv_ != nullptr) {
-            fprintf(csv_, CSV_FORMAT, LogLevelName[level], id, pid_, tid, ti, static_cast<long long>(t), file, line, func, info);
+            fprintf(csv_, CSV_FORMAT, LogLevelName[level], id,
+                    static_cast<long long>(pid_), static_cast<long long>(tid), ti,
+                    static_cast<long long>(t), file, line, func, info);
             fflush(csv_);
         }
 
@@ -420,4 +427,7 @@ namespace aFuntool {
 #endif
         return 0;
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 8 - 2
src/tool/md5.cpp

@@ -6,13 +6,16 @@
 #include <cstdio>
 #include <cstring>
 
-#include "tool-type.h"
+#include "tool.h"
 #include "md5.h"
 #include "file.h"
 #include "tool-exception.h"
 #include "__md5.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     struct MD5_CTX {
         unsigned int count[2];
         unsigned int state[4];
@@ -223,4 +226,7 @@ namespace aFuntool {
 
     template AFUN_TOOL_EXPORT char *getFileMd5(char *&path);
     template AFUN_TOOL_EXPORT std::string getFileMd5(std::string &path);
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 7 - 1
src/tool/regex.cpp

@@ -3,7 +3,10 @@
 #include "encoding.h"
 #include "string"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     Regex::Regex(std::string pattern_) noexcept(false): pattern{std::move(pattern_)}, re{nullptr} {
         int error_code;
         size_t error_offset;
@@ -66,4 +69,7 @@ namespace aFuntool {
         pcre2_match_data_free(match_data);
         return result;
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 73 - 55
src/tool/stdio.cpp

@@ -5,7 +5,7 @@
  */
 
 #include <cstdio>
-#include "tool-type.h"
+#include "tool.h"
 #include "tool-stdio.h"
 #include "mutex"
 
@@ -16,10 +16,16 @@
  * 实际上, khbit只能代表有内容输入而无法确定内容是否已经输入到缓冲区中
  */
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     OutStream cout{printf_stdout};
     OutStream cerr{printf_stderr};
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #ifdef AFUN_WIN32_NO_CYGWIN
 #include <cstring>
@@ -29,14 +35,17 @@ namespace aFuntool {
 // 获取CodePage, 并将内存中utf-8字符串转换为对应编码输出
 // cygwin环境下, 终端默认为uft-8
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
-    const int BUFF_SIZE = 40960;
-    char buffer[BUFF_SIZE + 1] = "";
-    size_t index = 0;
-    size_t next = 0;
-    size_t end = 0;
-    volatile sig_atomic_t ctrl_c = 0;
-    std::mutex buffer_mutex;  // 只有 export 的函数统一处理该互斥锁
+#endif
+
+    AFUN_STATIC const int BUFF_SIZE = 40960;
+    AFUN_STATIC char buffer[BUFF_SIZE + 1] = "";
+    AFUN_STATIC size_t buffer_index = 0;
+    AFUN_STATIC size_t buffer_next = 0;
+    AFUN_STATIC size_t buffer_end = 0;
+    AFUN_STATIC volatile sig_atomic_t ctrl_c = 0;
+    AFUN_STATIC std::mutex buffer_mutex;  // 只有 export 的函数统一处理该互斥锁
 
     int setCursorPosition(HANDLE std_o, CONSOLE_SCREEN_BUFFER_INFO *info_, SHORT x_){
         CONSOLE_SCREEN_BUFFER_INFO info;
@@ -73,43 +82,43 @@ namespace aFuntool {
         CONSOLE_SCREEN_BUFFER_INFO info;
         if (!GetConsoleScreenBufferInfo(std_o, &info))
             return 0;
-        if (setCursorPosition(std_o, &info, (SHORT) (end - next)) == -1)
+        if (setCursorPosition(std_o, &info, (SHORT) (buffer_end - buffer_next)) == -1)
             return 0;
-        next = end;
+        buffer_next = buffer_end;
         return 1;
     }
 
     int moveBuffer(){
-        if (index == 0)
+        if (buffer_index == 0)
             return 0;
-        memmove(buffer, buffer + index, BUFF_SIZE - index);
-        end = end - index;
-        next = next - index;
-        index = 0;
-        memset(buffer + end, 0, BUFF_SIZE - end);
+        memmove(buffer, buffer + buffer_index, BUFF_SIZE - buffer_index);
+        buffer_end = buffer_end - buffer_index;
+        buffer_next = buffer_next - buffer_index;
+        buffer_index = 0;
+        memset(buffer + buffer_end, 0, BUFF_SIZE - buffer_end);
         return 1;
     }
 
     int backChar(HANDLE std_o){
-        if (index != next) {  // 删除一个字符
+        if (buffer_index != buffer_next) {  // 删除一个字符
             if (setCursorPosition(std_o, nullptr, -1) == -1)  // 先一定位置在-1
                 return 0;
 
             CONSOLE_SCREEN_BUFFER_INFO info;
             if (!GetConsoleScreenBufferInfo(std_o, &info))
                 return 0;
-            memmove(buffer + next - 1, buffer + next, end - next + 1);
+            memmove(buffer + buffer_next - 1, buffer + buffer_next, buffer_end - buffer_next + 1);
 
             SetConsoleCursorPosition(std_o, info.dwCursorPosition);
-            for (size_t n = next - 1; n < end; n++)
+            for (size_t n = buffer_next - 1; n < buffer_end; n++)
                 fputc(' ', stdout);
 
             SetConsoleCursorPosition(std_o, info.dwCursorPosition);
-            fputs(buffer + next - 1, stdout);
+            fputs(buffer + buffer_next - 1, stdout);
 
             SetConsoleCursorPosition(std_o, info.dwCursorPosition);
-            next--;
-            end--;
+            buffer_next--;
+            buffer_end--;
         }
         return 1;
     }
@@ -117,9 +126,9 @@ namespace aFuntool {
     int enterChar(HANDLE std_o){
         if (!nextToEnd(std_o))
             return 0;
-        buffer[end] = '\n';
-        end++;
-        next++;
+        buffer[buffer_end] = '\n';
+        buffer_end++;
+        buffer_next++;
         fputc('\n', stdout);
         return 1;
     }
@@ -133,25 +142,25 @@ namespace aFuntool {
     int newChar(HANDLE std_i, char ch){
         if (ch == 0)
             return 1;
-        if (end == BUFF_SIZE && !moveBuffer())  // 对比 end 而不是 next
+        if (buffer_end == BUFF_SIZE && !moveBuffer())  // 对比 end 而不是 next
             return 0;
 
-        if (next != end) {  // insert 模式
+        if (buffer_next != buffer_end) {  // insert 模式
             CONSOLE_SCREEN_BUFFER_INFO info;
             if (!GetConsoleScreenBufferInfo(std_i, &info))
                 return 0;
-            memmove(buffer + next + 1, buffer + next, end - next);
-            buffer[next] = ch;
-            fputs(buffer + next, stdout);
+            memmove(buffer + buffer_next + 1, buffer + buffer_next, buffer_end - buffer_next);
+            buffer[buffer_next] = ch;
+            fputs(buffer + buffer_next, stdout);
             if (setCursorPosition(std_i, &info, 1) == -1)
                 return 0;
         } else {
-            buffer[next] = ch;
+            buffer[buffer_next] = ch;
             fputc(ch, stdout);
         }
 
-        next++;
-        end++;
+        buffer_next++;
+        buffer_end++;
         return 1;
     }
 
@@ -195,15 +204,15 @@ namespace aFuntool {
                     CONSOLE_SCREEN_BUFFER_INFO info;
                     if (!GetConsoleScreenBufferInfo(std_o, &info))
                         return -1;
-                    if (next > index) {
-                        next--;
+                    if (buffer_next > buffer_index) {
+                        buffer_next--;
                         if (setCursorPosition(std_o, nullptr, -1) == -1)
                             return 0;
                     }
                     return 0;
                 } else if (record.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT) {  // 右
-                    if (next < end) {
-                        next++;
+                    if (buffer_next < buffer_end) {
+                        buffer_next++;
                         if (setCursorPosition(std_o, nullptr, 1) == -1)
                             return 0;
                     }
@@ -220,7 +229,7 @@ namespace aFuntool {
     }
 
     int fcheck_stdin(HANDLE std_i, HANDLE std_o){
-        if (end == index || end == 0 || buffer[end - 1] != '\n')
+        if (buffer_end == buffer_index || buffer_end == 0 || buffer[buffer_end - 1] != '\n')
             return checkNewInput(std_i, std_o);
         return 1;
     }
@@ -241,8 +250,8 @@ namespace aFuntool {
                 return EOF;
         }
 
-        re = (unsigned char) buffer[index];
-        index++;
+        re = (unsigned char) buffer[buffer_index];
+        buffer_index++;
         return re;
     }
 
@@ -265,10 +274,10 @@ namespace aFuntool {
 
         {
             size_t len_ = len - 1;
-            if (end - index < len_)
-                len_ = end - index;
-            memcpy(buf, buffer + index, len_);
-            index += len_;
+            if (buffer_end - buffer_index < len_)
+                len_ = buffer_end - buffer_index;
+            memcpy(buf, buffer + buffer_index, len_);
+            buffer_index += len_;
             nextToEnd(std_o);
             buf[len_] = '\0';  // 最后一位
         }
@@ -288,9 +297,9 @@ namespace aFuntool {
 
         std::unique_lock<std::mutex> ul{buffer_mutex};
         nextToEnd(std_o);
-        index = 0;
-        end = 0;
-        next = 0;
+        buffer_index = 0;
+        buffer_end = 0;
+        buffer_next = 0;
         memset(buffer, 0, BUFF_SIZE);
         return false;
     }
@@ -396,17 +405,17 @@ namespace aFuntool {
             return ungetc(ch, stdin);
 
         std::unique_lock<std::mutex> ul{buffer_mutex};
-        if (ch == 0 || (index == 0 && end == BUFF_SIZE)) {
+        if (ch == 0 || (buffer_index == 0 && buffer_end == BUFF_SIZE)) {
             return 0;
         }
 
-        if (index != 0) {
-            index--;
-            buffer[index] = static_cast<char>(ch);
-        } else if (end != BUFF_SIZE) {  // index == 0;
-            memmove(buffer, buffer + 1, end);  // 往回移动
-            end++;
-            next++;
+        if (buffer_index != 0) {
+            buffer_index--;
+            buffer[buffer_index] = static_cast<char>(ch);
+        } else if (buffer_end != BUFF_SIZE) {  // index == 0;
+            memmove(buffer, buffer + 1, buffer_end);  // 往回移动
+            buffer_end++;
+            buffer_next++;
             buffer[0] = static_cast<char>(ch);
         }
 
@@ -462,13 +471,19 @@ namespace aFuntool {
         safeFree(buf);
         return re;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 
 #else
 #include <unistd.h>
 #include <fcntl.h>
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     std::mutex fcntl_mutex;  // 只有 export 的函数统一处理该互斥锁
     
     // 用于Linux平台的IO函数
@@ -526,5 +541,8 @@ namespace aFuntool {
         fcntl(STDIN_FILENO, F_SETFL, oldf);
         return !ferror(stdin) && !feof(stdin);
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif
 #endif

+ 8 - 2
src/tool/string.cpp

@@ -5,13 +5,16 @@
 
 #include <cstdlib>
 #include <cstring>
-#include "tool-type.h"
+#include "tool.h"
 #include "str.h"
 
 #define NEW_STR(size) safeCalloc<char>((size) + 1)
 #define STR_LEN(p) (((p) == NULL) ? 0 : strlen((p)))
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     char *charToStr(char ch){
         if (ch == NUL)
             return nullptr;
@@ -73,4 +76,7 @@ namespace aFuntool {
         }
         return new_str;
     }
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 7 - 1
src/tool/time.cpp

@@ -4,12 +4,15 @@
  */
 
 #include <ctime>
-#include "tool-type.h"
+#include "tool.h"
 #include "tool-time.h"
 #include "tool-stdio.h"
 #include "str.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     /**
      * 等待指定的秒数(ms) 支持小数
      */
@@ -87,4 +90,7 @@ namespace aFuntool {
         safeFree(tmp_ch);
         return ret;
     }
+
+#ifndef AFUN_TOOL_C
 }
+#endif

+ 7 - 1
src/tool/tool-logger.cpp

@@ -1,5 +1,11 @@
 #include "tool-logger.h"
 
+#ifndef AFUN_TOOL_C
 namespace aFuntool {
+#endif
+
     Logger *aFunSysLogger = nullptr;
-}
+
+#ifndef AFUN_TOOL_C
+}
+#endif

+ 26 - 4
test/src/CMakeLists.txt

@@ -1,6 +1,5 @@
 file(GLOB src_list RELATIVE ${CMAKE_CURRENT_LIST_DIR}
      ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
-
 foreach(src IN LISTS src_list)
     cmake_path(GET src STEM file_name)
     add_executable(${file_name})
@@ -12,20 +11,40 @@ foreach(src IN LISTS src_list)
     define_FILENAME(${file_name})
     unset(file_name)
 endforeach()
+unset(src_list)
+
+file(GLOB src_list RELATIVE ${CMAKE_CURRENT_LIST_DIR}
+        ${CMAKE_CURRENT_LIST_DIR}/*.c)
+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-c)  # 链接静态库 (导出所有符号)
+    set_target_properties(${file_name}
+            PROPERTIES OUTPUT_NAME "test-${file_name}")
+    target_compile_definitions(${file_name} PRIVATE IN_CTEST)
+    define_FILENAME(${file_name})
+    unset(file_name)
+endforeach()
+unset(src_list)
 
 # tool 相关测试
 file(MD5 "${CMAKE_CURRENT_LIST_DIR}/../share/md5.txt" TOOL_MD5_ANS)
-add_new_test(tool-byte COMMAND "$<TARGET_FILE:tool-byte>")
 add_new_test(tool-mem COMMAND "$<TARGET_FILE:tool-mem>")
+add_new_test(tool-byte COMMAND "$<TARGET_FILE:tool-byte>")
 add_new_test(tool-dlc COMMAND "$<TARGET_FILE:tool-byte>" "$<TARGET_FILE:dlc-lib>")
 add_new_test(tool-regex COMMAND "$<TARGET_FILE:tool-regex>")
 add_new_test(tool-md5 COMMAND "$<TARGET_FILE:tool-md5>" "${TOOL_MD5_ANS}" "${CMAKE_CURRENT_LIST_DIR}/../share/md5.txt")
+add_new_test(tool-utf COMMAND "$<TARGET_FILE:tool-utf>")
 add_new_test(tool-logger COMMAND "$<TARGET_FILE:tool-logger>")
 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 tool-logger tool-exit tool-hash)
 
+add_new_test(tool-c-hash COMMAND "$<TARGET_FILE:tool-c-hash>")
+add_new_test(tool-c-stdio COMMAND "$<TARGET_FILE:tool-c-stdio>")
+set_test_label(it tool-c-hash tool-c-stdio)
+
 add_new_test(core-init COMMAND "$<TARGET_FILE:core-init>")
 add_new_test(core-code COMMAND "$<TARGET_FILE:core-code>")
 add_new_test(core-env-var COMMAND "$<TARGET_FILE:core-env-var>")
@@ -33,8 +52,11 @@ add_new_test(core-down-msg COMMAND "$<TARGET_FILE:core-down-msg>")
 add_new_test(core-up-msg COMMAND "$<TARGET_FILE:core-up-msg>")
 add_new_test(core-reader COMMAND "$<TARGET_FILE:core-reader>")
 add_new_test(core-lexical COMMAND "$<TARGET_FILE:core-lexical>")
+set_test_label(core core-init core-code core-env-var core-down-msg core-up-msg core-reader core-lexical)
 
 add_new_test(it-syntactic COMMAND "$<TARGET_FILE:it-syntactic>")
 add_new_test(it-init COMMAND "$<TARGET_FILE:it-init>")
+set_test_label(it it-syntactic it-init)
 
-add_new_test(run-code COMMAND "$<TARGET_FILE:run-code>")
+add_new_test(run-code COMMAND "$<TARGET_FILE:run-code>")
+set_test_label(aFun run-code)

+ 1 - 0
test/src/run-code.cpp

@@ -14,6 +14,7 @@ class Func1 : public Function {
         std::list<ArgCodeList> *acl;
     public:
         CallFunc1(Code &func_code_, const Code::ByteCode *code_, Inter &inter_) : func_code{func_code_}, call_code{code_}, inter{inter_} {
+            (void)call_code;  // 放置 call_code unused
             acl = new std::list<ArgCodeList>;
             if (code_ != nullptr) {
                 ArgCodeList agr1 {code_->getSon()->toNext()};

+ 6 - 0
test/src/tool-c-hash.c

@@ -0,0 +1,6 @@
+#include "aFuntool.h"
+
+int main() {
+    printf("%ld\n", time33("HelloWorld"));
+    return 0;
+}

+ 6 - 0
test/src/tool-c-stdio.c

@@ -0,0 +1,6 @@
+#include "aFuntool.h"
+
+int main() {
+    printf_stdout(0, "Hello, aFun\n");
+    return 0;
+}