refactor: centralized header copy script replaces per-module cp

- 新增 release/copy_headers.sh:统一管理公共头文件复制
- 从所有模块 makefile 中移除独立的 @cp 行
- release/src/public/makefile:all 目标依赖 headers(自动调用脚本)
- release/inc/.gitignore:仅 myBase.h 纳入版本管理
- 新增模块时只需在 copy_headers.sh 末尾追加一行 copy_module

新增模块流程:
1. 创建 src/public/<module>/inc/<header.h>
2. 在 release/copy_headers.sh 中追加 copy_module "<module>" "<header.h>"
3. make 时自动复制到 release/inc/
This commit is contained in:
ypc 2026-07-07 17:38:44 +08:00
parent 9d12019961
commit 7dd7572f46
23 changed files with 60 additions and 8687 deletions

51
release/copy_headers.sh Executable file
View File

@ -0,0 +1,51 @@
#!/bin/bash
# ================================================================
# copy_headers.sh — 公共头文件复制到 release/inc/
#
# 用法:
# release/copy_headers.sh # 从工程根目录调用
# make headers # 通过 makefile 调用
#
# 新增模块时,在本脚本末尾追加一行:
# copy_module "模块名" "头文件名"
# ================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
SRC_DIR="$ROOT_DIR/src"
DST_DIR="$ROOT_DIR/release/inc"
echo "=== copying public headers to release/inc/ ==="
copy_module()
{
local module="$1"
local header="$2"
local src="$SRC_DIR/public/$module/inc/$header"
if [ -f "$src" ]
then
cp -f "$src" "$DST_DIR/"
echo " [$module] $header"
else
echo " [WARN] $src not found, skip"
fi
}
# ================================================================
# 公共库模块(按顺序添加)
# ================================================================
copy_module "liblist" "list.h"
copy_module "libfunc" "myFunc.h"
copy_module "liblog" "myLog.h"
copy_module "libmd5" "myMd5.h"
copy_module "libcJSON" "cJSON.h"
copy_module "libmy_xxhash" "xxhash.h"
copy_module "libtask" "myTask.h"
copy_module "libxml" "myXml.h"
copy_module "libxml" "tinyxml2.h"
copy_module "libcmd" "myCmd.h"
copy_module "libdatacenter" "myDatacenter.h"
echo "=== done ==="

5
release/inc/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# release/inc/ 目录下仅 myBase.h 纳入版本管理
# 其他头文件由 release/copy_headers.sh 在编译前生成
*
!myBase.h
!.gitignore

View File

@ -1,306 +0,0 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 19
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* Limits the length of circular references can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_CIRCULAR_LIMIT
#define CJSON_CIRCULAR_LIMIT 10000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/array that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
* The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
* The input pointer json cannot point to a read-only address area, such as a string constant,
* but should point to a readable and writable address area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
#define cJSON_SetBoolValue(object, boolValue) ( \
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
cJSON_Invalid\
)
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,203 +0,0 @@
/**
* @file list.h
* @brief Linux C/C++
* @details struct list_head 宿 list_entry 宿
* O(1) O(n)
* C++ 使 new/class/typeof
*/
#ifndef _LIST_H_
#define _LIST_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* ---- 链表节点 ---- */
struct list_head
{
struct list_head *next;
struct list_head *prev;
};
/* ---- 初始化 ---- */
#define LIST_HEAD_INIT(n) { &(n), &(n) }
#define LIST_HEAD(n) struct list_head n = LIST_HEAD_INIT(n)
/**
* @brief
*/
static inline void INIT_LIST_HEAD(struct list_head *h)
{
h->next = h;
h->prev = h;
}
/* ---- 内部辅助:在 prev 和 next 之间插入 node ---- */
static inline void __list_add(struct list_head *node,
struct list_head *prev,
struct list_head *next)
{
next->prev = node;
node->next = next;
node->prev = prev;
prev->next = node;
}
/* ---- 内部辅助:移除 prev 和 next 之间的节点 ---- */
static inline void __list_del(struct list_head *prev,
struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/* ---- 添加操作 ---- */
/** 头插法:插入到 head 之后(作为第一个元素) */
static inline void list_add(struct list_head *node, struct list_head *head)
{
__list_add(node, head, head->next);
}
/** 尾插法:插入到 head 之前(作为最后一个元素) */
static inline void list_add_tail(struct list_head *node, struct list_head *head)
{
__list_add(node, head->prev, head);
}
/* ---- 删除操作 ---- */
/** 从链表移除节点(不释放内存) */
static inline void list_del(struct list_head *e)
{
__list_del(e->prev, e->next);
}
/** 移除并重新初始化节点(安全删除,防止悬空指针) */
static inline void list_del_init(struct list_head *e)
{
__list_del(e->prev, e->next);
INIT_LIST_HEAD(e);
}
/* ---- 移动操作 ---- */
/** 将节点移动到新链表头部 */
static inline void list_move(struct list_head *l, struct list_head *h)
{
__list_del(l->prev, l->next);
list_add(l, h);
}
/** 将节点移动到新链表尾部 */
static inline void list_move_tail(struct list_head *l, struct list_head *h)
{
__list_del(l->prev, l->next);
list_add_tail(l, h);
}
/* ---- 替换操作 ---- */
/** 用 node 替换 old */
static inline void list_replace(struct list_head *old, struct list_head *node)
{
node->next = old->next;
node->next->prev = node;
node->prev = old->prev;
node->prev->next = node;
}
/** 替换后初始化被替换节点 */
static inline void list_replace_init(struct list_head *old,
struct list_head *node)
{
list_replace(old, node);
INIT_LIST_HEAD(old);
}
/* ---- 判断操作 ---- */
/** 判断链表是否为空 */
static inline int list_empty(const struct list_head *h)
{
return h->next == h;
}
/** 判断节点是否已链入链表 */
static inline int list_is_linked(const struct list_head *e)
{
return e->next != e;
}
/* ---- 节点 ↔ 宿主指针转换 ---- */
/** 从链表节点指针取回宿主结构体指针 */
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
/** 获取第一个宿主元素 */
#define list_first_entry(h, type, member) \
list_entry((h)->next, type, member)
/** 获取最后一个宿主元素 */
#define list_last_entry(h, type, member) \
list_entry((h)->prev, type, member)
/** 安全获取第一个元素(链表空返回 NULL */
#define list_first_entry_or_null(h, type, member) \
(list_empty(h) ? NULL : list_first_entry(h, type, member))
/* ---- 遍历操作 ---- */
/** 遍历链表节点(仅获取 struct list_head 指针) */
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/** 安全遍历节点(可在遍历中删除 pos */
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/** 遍历宿主元素 */
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, __typeof__(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, __typeof__(*pos), member))
/** 安全遍历宿主元素(可在遍历中删除 pos */
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, __typeof__(*pos), member), \
n = list_entry(pos->member.next, __typeof__(*pos), member); \
&pos->member != (head); \
pos = n, \
n = list_entry(n->member.next, __typeof__(*n), member))
/* ---- 拼接操作 ---- */
/** 将 src 链表拼接到 dst 头部src 被清空 */
static inline void list_splice_init(struct list_head *src,
struct list_head *dst)
{
if (!list_empty(src))
{
struct list_head *f = src->next;
struct list_head *l = src->prev;
struct list_head *a = dst->next;
f->prev = dst;
dst->next = f;
l->next = a;
a->prev = l;
INIT_LIST_HEAD(src);
}
}
#ifdef __cplusplus
}
#endif
#endif /* _LIST_H_ */

View File

@ -1,77 +0,0 @@
/**
* @file myCmd.h
* @brief C
* @details // linenoise
* `__attribute__((constructor))`
*/
#ifndef _MY_CMD_H_
#define _MY_CMD_H_
#include "myBase.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
const char *name;
void (*func)(int argc, char *argv[]);
const char *desc;
void (*complete)(const char *buf, char ***completions, int *ncomp);
} stru_cmd;
/** 注册命令 */
void cmd_manager_add_command(const char *name, void (*func)(int argc, char *argv[]),
const char *desc, void (*complete)(const char *, char ***, int *));
/** 获取所有已注册命令列表 */
stru_cmd *cmd_manager_get_commands(unsigned int *out_count);
/** 打印帮助信息 */
void cmd_help(int argc, char *argv[]);
/** 按名称查找命令 */
stru_cmd *cmd_find(const char *name);
/** Tab 自动补全回调 */
void cmd_complete(const char *buf, char ***completions, int *ncomp);
/** 子命令补全 */
void cmd_sub_complete(const char *buf, char ***completions, int *ncomp,
const char **subs, int sub_count);
/** 行编辑交互式输入 */
char *linenoise(const char *prompt);
/** 释放 linenoise 返回的内存 */
void linenoiseFree(void *ptr);
/** 添加历史记录 */
int linenoiseHistoryAdd(const char *line);
/** 释放所有历史 */
void linenoiseHistoryFree(void);
/** 设置自动补全回调 */
void lineniseSetCompletionCallback(void (*cb)(const char *, char ***, int *));
/** 注册命令宏(无补全) */
#define CMD_REGISTER(cmd_name, func_ptr, cmd_desc) \
__attribute__((constructor)) static void register_##func_ptr(void) \
{ \
cmd_manager_add_command(cmd_name, func_ptr, cmd_desc, NULL); \
}
/** 注册命令宏(带补全) */
#define CMD_REGISTER_C(cmd_name, func_ptr, cmd_desc, complete) \
__attribute__((constructor)) static void register_##func_ptr(void) \
{ \
cmd_manager_add_command(cmd_name, func_ptr, cmd_desc, complete); \
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,558 +0,0 @@
/**
* @file myDatacenter.h
* @brief C
* @details // + + +
* libmy_xxhash O(1)
* libxml C
* RTU libdatacenter v1 + v2
*/
#ifndef _MY_DATACENTER_H_
#define _MY_DATACENTER_H_
#include <stdint.h>
#include <stddef.h>
#include "xxhash.h"
#ifdef __cplusplus
extern "C"
{
#endif
/* ===== 地址/描述/模块/错误信息最大长度 ===== */
#define DC_SADDR_MAX_LEN 128
#define DC_DESC_MAX_LEN 256
#define DC_UNIT_MAX_LEN 32
#define DC_MODULE_MAX_LEN 64
#define DC_ERR_MSG_MAX_LEN 256
/* ===== 容量限制 ===== */
#define DC_MAX_CALLBACKS 16
#define DC_MAX_LINK_SADDRS 32
#define DC_MAX_DATA_ZONES 8
#define DC_MAX_PENDING 64
/** datacenter 自身模块标识 */
#define MODULE_DATACENTER "datacenter"
/* ===== 控制类型枚举 ===== */
typedef enum
{
DC_CTRL_NONE = 0, /**< 无控制 */
DC_CTRL_DIRECT = 1, /**< 直控(直接执行,无需选择-确认) */
DC_CTRL_SBO = 2 /**< 选控Select-Before-Operate 两阶段) */
} dc_ctrl_type_t;
/* ===== 控制步骤枚举 ===== */
typedef enum
{
DC_STEP_READY = 0, /**< 就绪/空闲 */
DC_STEP_SELECT = 1, /**< 选择SBO 第一步:锁住信号并暂存选择值) */
DC_STEP_DIRECT = 2, /**< 执行SBO 第二步确认写入,直控直接执行) */
DC_STEP_CANCEL = 3 /**< 取消(回退到 READY */
} dc_ctrl_step_t;
/* ===== 错误码枚举 ===== */
typedef enum
{
DC_OK = 0, /**< 成功 */
DC_ERR_PARAM = -1, /**< 参数错误NULL/越界) */
DC_ERR_NOTFOUND = -2, /**< 信号不存在 */
DC_ERR_TYPE = -3, /**< 数据类型不匹配 */
DC_ERR_STEP = -4, /**< SBO 步骤错误 */
DC_ERR_VAL = -5, /**< 值校验失败(越界/未变化) */
DC_ERR_TIMEOUT = -6, /**< 异步请求超时 */
DC_ERR_BUSY = -7, /**< 忙 */
DC_ERR_MEM = -8, /**< 内存不足 */
DC_ERR_FULL = -9, /**< 请求队列已满 */
DC_ERR_LOCKED = -10, /**< 已锁定 */
DC_ERR_EXISTS = -11, /**< 信号已存在(重复注册) */
DC_ERR_CANCEL = -12 /**< 异步请求已取消 */
} dc_error_t;
/* ===== 控制上下文 ===== */
typedef struct
{
uint8_t step; /**< 当前控制步骤dc_ctrl_step_t */
uint8_t type; /**< 控制类型dc_ctrl_type_t */
uint8_t data_type; /**< 数据类型DATA_TYPE_* */
uint8_t reserved; /**< 保留 */
void *p_data; /**< SELECT 时暂存选择值DIRECT 时用于返校比对 */
} dc_ctrl_t;
/* ===== 信号参数元数据min/max/step/unit ===== */
typedef struct
{
float min; /**< 最小值 */
float max; /**< 最大值 */
float step; /**< 步长 */
char unit[DC_UNIT_MAX_LEN]; /**< 单位(如 "kV", "A", "Hz" */
} dc_param_meta_t;
/* ===== 回调函数类型 ===== */
/**
* @brief out 100ms
* @param saddr
* @param data_type
* @param p_new
* @param p_old
*/
typedef void (*dc_out_change_cb_t)(const char *saddr, uint8_t data_type,
const void *p_new, const void *p_old);
/**
* @brief yk/ao/param
* @param saddr
* @param step
* @param data_type
* @param zone param 使 0
* @param p_data
*/
typedef void (*dc_signal_change_cb_t)(const char *saddr, dc_ctrl_step_t step,
uint8_t data_type, uint8_t zone,
const void *p_data);
/** @brief 事件队列消费回调 */
typedef void (*dc_queue_pop_cb_t)(void *p_data);
/**
* @brief A
* @param req_id ID
* @param result DC_OK / DC_ERR_*
* @param err
* @param arg
*/
typedef void (*dc_async_result_cb_t)(uint32_t req_id, int result,
const char *err, void *arg);
/**
* @brief datacenter B执行实际操作
* @param req_id ID
* @param saddr
* @param step
* @param data_type
* @param zone
* @param p_data
* @param ctx
* @return 0 dc_set_result -1
*/
typedef int (*dc_async_exec_cb_t)(uint32_t req_id, const char *saddr,
dc_ctrl_step_t step, uint8_t data_type,
uint8_t zone, const void *p_data, void *ctx);
/* ===== 内部数据结构(对调用方透明,通过 API 访问) ===== */
/** 回调条目 */
typedef struct
{
char module_id[DC_MODULE_MAX_LEN];
dc_out_change_cb_t out_cb;
dc_signal_change_cb_t ctrl_cb;
} dc_cb_entry_t;
/** 信号节点 */
typedef struct
{
uint32_t id;
XXH128_hash_t hash;
char saddr[DC_SADDR_MAX_LEN];
char desc[DC_DESC_MAX_LEN];
uint8_t data_type;
uint8_t ctrl_type;
void **vec_p_data;
int vec_p_data_count;
void *p_last_data;
char link_saddr[DC_SADDR_MAX_LEN];
char **link_saddrs;
int link_count;
dc_param_meta_t param;
dc_cb_entry_t cb_list[DC_MAX_CALLBACKS];
int cb_count;
char last_caller_module[DC_MODULE_MAX_LEN];
dc_async_exec_cb_t exec_cb;
void *module_ctx;
} dc_signal_t;
/* ==================================================================
*
* ================================================================== */
/**
* @brief
* @param cfg_dir param.xml
* @return DC_OK <0
*/
int dc_init(const char *cfg_dir);
/** @brief 清理数据中心,释放所有信号和队列资源 */
void dc_cleanup(void);
/**
* @brief 100ms
* @details out + + +
*/
void dc_run_100ms(void);
/**
* @brief 1000ms
* @details self_param.xml
*/
void dc_run_1000ms(void);
/* ==================================================================
* Out /
* ================================================================== */
/**
* @brief
* @param saddr
* @param desc
* @param data_type DATA_TYPE_*
* @param p_data
* @param module_id
* @return DC_OK DC_ERR_EXISTS
*/
int dc_signal_out(const char *saddr, const char *desc, uint8_t data_type,
void *p_data, const char *module_id);
/**
* @brief
* @param cb 100ms
*/
int dc_signal_out_with_callback(const char *saddr, const char *desc,
uint8_t data_type, void *p_data,
dc_out_change_cb_t cb, const char *module_id);
/**
* @brief out
* @param p_data out
*/
int dc_signal_out_link_with_callback(const char *saddr, void **p_data,
dc_out_change_cb_t cb, const char *module_id);
/**
* @brief 100ms
* @param module_id
*/
int dc_set_out_signal_val(const char *saddr, const void *set_data,
const char *module_id);
/* ==================================================================
* In out
* ================================================================== */
/**
* @brief
* @param link_saddr out
* @param p_data out
*/
int dc_signal_in(const char *saddr, const char *desc,
const char *link_saddr, void **p_data, const char *module_id);
/**
* @brief out
*/
int dc_signal_in_with_callback(const char *saddr, const char *desc,
const char *link_saddr, void **p_data,
dc_out_change_cb_t cb, const char *module_id);
/* ==================================================================
* YK
* ================================================================== */
/**
* @brief
* @param ctrl_type DC_CTRL_DIRECT / DC_CTRL_SBO
* @param cb
*/
int dc_signal_yk(const char *saddr, const char *desc,
uint8_t data_type, uint8_t ctrl_type, void *p_data,
dc_signal_change_cb_t cb, const char *module_id);
/** @brief 链接已有 YK 信号,获取数据指针并注册回调 */
int dc_signal_yk_link_with_callback(const char *saddr, void **p_data,
dc_signal_change_cb_t cb, const char *module_id);
/**
* @brief YK SBO SELECTDIRECT/CANCEL
* @param step
* @param ctrl type/data_type/p_data step
* @param p_data
*/
int dc_signal_yk_set_status(const char *saddr, dc_ctrl_step_t step,
dc_ctrl_t *ctrl, const void *p_data,
const char *module_id);
/**
* @brief YK
* @param result_cb
* @param timeout_ms 0 使
* @param request_id ID
*/
int dc_yk_exec_async(const char *saddr, dc_ctrl_step_t step,
const dc_ctrl_t *ctrl, const void *p_data,
const char *module_id,
dc_async_result_cb_t result_cb, void *user_arg,
uint32_t timeout_ms, uint32_t *request_id);
/** @brief 设置 YK 异步执行结果模块B回调 */
int dc_yk_set_result(uint32_t request_id, int result_code, const char *err_msg);
/** @brief 取消 YK 异步请求 */
int dc_yk_cancel_async(uint32_t request_id);
/** @brief 注册 YK 异步执行回调模块B初始化时调用 */
int dc_yk_register_exec_cb(const char *saddr, dc_async_exec_cb_t exec_cb,
void *module_ctx);
/* ==================================================================
* AO
* ================================================================== */
/**
* @brief AO
* @param ctrl_type
* @param cb
*/
int dc_signal_ao(const char *saddr, const char *desc,
uint8_t data_type, uint8_t ctrl_type, void *p_data,
dc_signal_change_cb_t cb, const char *module_id);
/** @brief 链接已有 AO 信号 */
int dc_signal_ao_link_with_callback(const char *saddr, void **p_data,
dc_signal_change_cb_t cb, const char *module_id);
/**
* @brief AO SBO +
* @details DIRECT ctrl->step READY
*/
int dc_signal_ao_set_val(const char *saddr, dc_ctrl_step_t step,
dc_ctrl_t *ctrl, const void *p_data,
const char *module_id);
/** @brief AO 无校验设置(跳过 SBO 流程和值校验,用于初始化恢复) */
int dc_signal_ao_set_val_without_check(const char *saddr, uint8_t data_type,
const void *p_data, const char *module_id);
/** @brief AO 异步执行 */
int dc_ao_exec_async(const char *saddr, dc_ctrl_step_t step,
const dc_ctrl_t *ctrl, const void *p_data,
const char *module_id,
dc_async_result_cb_t result_cb, void *user_arg,
uint32_t timeout_ms, uint32_t *request_id);
/** @brief 设置 AO 异步执行结果 */
int dc_ao_set_result(uint32_t request_id, int result_code, const char *err_msg);
/** @brief 取消 AO 异步请求 */
int dc_ao_cancel_async(uint32_t request_id);
/** @brief 注册 AO 异步执行回调 */
int dc_ao_register_exec_cb(const char *saddr, dc_async_exec_cb_t exec_cb,
void *module_ctx);
/* ==================================================================
* Param /
* ================================================================== */
/**
* @brief
* @param p_data zone
* @param num_zones
*/
int dc_signal_param(const char *saddr, const char *desc,
uint8_t data_type, uint8_t ctrl_type,
void **p_data, int num_zones,
dc_signal_change_cb_t cb, const char *module_id);
/** @brief 链接已有参数信号 */
int dc_signal_param_link_with_callback(const char *saddr, void **p_data,
int num_zones,
dc_signal_change_cb_t cb,
const char *module_id);
/**
* @brief Param SBO + zone
* @param setting_zone 0-based
*/
int dc_signal_param_set_val(const char *saddr, dc_ctrl_step_t step,
dc_ctrl_t *ctrl, uint8_t setting_zone,
const void *p_data, const char *module_id);
/** @brief Param 无校验设置 */
int dc_signal_param_set_val_without_check(const char *saddr, uint8_t data_type,
uint8_t setting_zone,
const void *p_data,
const char *module_id);
/** @brief Param 异步执行 */
int dc_param_exec_async(const char *saddr, dc_ctrl_step_t step,
const dc_ctrl_t *ctrl, uint8_t setting_zone,
const void *p_data, const char *module_id,
dc_async_result_cb_t result_cb, void *user_arg,
uint32_t timeout_ms, uint32_t *request_id);
/** @brief 设置 Param 异步执行结果 */
int dc_param_set_result(uint32_t request_id, int result_code,
const char *err_msg);
/** @brief 取消 Param 异步请求 */
int dc_param_cancel_async(uint32_t request_id);
/** @brief 注册 Param 异步执行回调 */
int dc_param_register_exec_cb(const char *saddr, dc_async_exec_cb_t exec_cb,
void *module_ctx);
/* ==================================================================
*
* ================================================================== */
/** @brief 查询 out 信号信息 */
int dc_get_out_signal_info(const char *saddr, char *desc, int desc_len,
uint8_t *data_type, void **p_data);
/** @brief 查询 in 信号信息 */
int dc_get_in_signal_info(const char *saddr, char *desc, int desc_len,
uint8_t *data_type, void **p_data);
/** @brief 查询 AO 信号信息(含参数元数据) */
int dc_get_ao_signal_info(const char *saddr, char *desc, int desc_len,
uint8_t *data_type, dc_param_meta_t *p_meta,
uint8_t *ctrl_type, void **p_data);
/**
* @brief Param
* @param p_data_array
* @param p_count
*/
int dc_get_param_signal_info(const char *saddr, char *desc, int desc_len,
uint8_t *data_type, dc_param_meta_t *p_meta,
uint8_t *ctrl_type,
void **p_data_array, int *p_count);
/** @brief 查询 YK 信号信息 */
int dc_get_yk_signal_info(const char *saddr, char *desc, int desc_len,
uint8_t *data_type, uint8_t *ctrl_type, void **p_data);
/** @brief 获取信号值的字符串表示 */
int dc_get_signal_val(const void *p_data, uint8_t data_type,
char *buf, int buf_len);
/**
* @brief
* @param type_str "out"/"in"/"yk"/"ao"/"param"
* @return
*/
int dc_get_signal_count(const char *type_str);
/**
* @brief ID
* @param type_str "out"/"in"/"yk"/"ao"/"param"
* @param id ID
* @param saddr/saddr_len
* @param desc/desc_len
* @param data_type_str/type_str_len
* @param ctrl_type
* @param link_str/link_len
*/
int dc_get_signal_info_by_id(const char *type_str, uint32_t id,
char *saddr, int saddr_len,
char *desc, int desc_len,
char *data_type_str, int type_str_len,
uint8_t *ctrl_type,
char *link_str, int link_len);
/* ==================================================================
* //
* ================================================================== */
/** @brief SOE 事件入队 */
int dc_event_queue_push(void *p_soe);
/** @brief 注册 SOE 事件消费回调(支持多消费者) */
int dc_event_register_queue_pop(dc_queue_pop_cb_t cb);
/** @brief 扰动数据入队 */
int dc_disturb_dd_queue_push(void *p_dd);
/** @brief 注册扰动数据消费回调 */
int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb_t cb);
/** @brief 故障数据入队 */
int dc_fault_queue_push(void *p_fault);
/** @brief 注册故障数据消费回调 */
int dc_fault_register_queue_pop(dc_queue_pop_cb_t cb);
/* ==================================================================
*
* ================================================================== */
/** @brief 数据类型 ID → 名称(如 35 → "uint32_t" */
const char *dc_get_type_name(uint8_t data_type);
/** @brief 名称 → 数据类型 ID如 "float" → 38 */
uint8_t dc_get_type_id_by_name(const char *name);
/** @brief 获取数据类型的字节长度 */
uint8_t dc_get_type_len(uint8_t data_type);
/** @brief 根据类型分配并清零内存 */
void *dc_create_data(uint8_t data_type);
/** @brief 根据类型释放内存 */
void dc_destroy_data(void *p_data, uint8_t data_type);
/** @brief 类型感知的值复制 */
int dc_copy_val(void *dst, const void *src, uint8_t data_type);
/** @brief 类型感知的值比较0 = 相等,-1 = 不等) */
int dc_compare_val(const void *p1, const void *p2, uint8_t data_type);
/** @brief 字符串 → 值(如 "3.14" → 3.14f */
int dc_set_val_from_str(void *p_data, uint8_t data_type, const char *str);
/* ==================================================================
*
* ================================================================== */
/** @brief 查询参数配置是否有未保存的变更0=无1=有) */
int dc_param_cfg_changed(void);
/** @brief 获取当前异步请求 pending 数量 */
int dc_async_pending_count(void);
/** @brief 设置全局默认异步超时时间(毫秒) */
void dc_async_set_default_timeout(uint32_t timeout_ms);
/** @brief 设置 YK 遥控默认异步超时0=使用全局默认) */
void dc_async_set_timeout_yk(uint32_t timeout_ms);
/** @brief 设置 AO 调节默认异步超时0=使用全局默认) */
void dc_async_set_timeout_ao(uint32_t timeout_ms);
/** @brief 设置 Param 定值默认异步超时0=使用全局默认) */
void dc_async_set_timeout_param(uint32_t timeout_ms);
/* ==================================================================
*
* ================================================================== */
/**
* @brief out XML
* @param path
* @return DC_OK <0
*/
int dc_save_out_signals_xml(const char *path);
#ifdef __cplusplus
}
#endif
#endif /* _MY_DATACENTER_H_ */

View File

@ -1,323 +0,0 @@
/**
* @file myFunc.h
* @brief 65 7
* @details / / / /
* / / IPC
*/
#ifndef _MY_FUNC_H_
#define _MY_FUNC_H_
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief
* @note year: 7bit(0-127+1900), month:4bit(1-12), day:5bit(1-31)
* hour:5bit(0-23), min:6bit(0-59), ms:16bit(0-59999)
*/
typedef struct
{
uint32_t ms : 16; /* 毫秒(实际存储秒*1000+毫秒,范围 0-59999 */
uint32_t min : 6; /* 分钟 0-59 */
uint32_t : 2; /* 保留 */
uint32_t hour: 5; /* 小时 0-23 */
uint32_t : 3; /* 保留 */
uint32_t day : 5; /* 日期 1-31 */
uint32_t week: 3; /* 星期 */
uint32_t month:4; /* 月份 1-12 */
uint32_t : 4; /* 保留 */
uint32_t year: 7; /* 年份偏移(实际值-1900),范围 0-127 */
uint32_t : 1; /* 保留 */
} stru_time_sys;
/**
* @brief Unix +
*/
typedef struct
{
time_t sec; /* Unix 时间戳(秒) */
time_t usec; /* 微秒部分 */
} stru_time_cal;
/**
* @brief IPC
*/
typedef struct
{
int qid; /* 响应队列 ID */
int type; /* 响应类型enum_ipc_resp */
int len; /* 有效数据长度 */
char text[4096]; /* 消息内容 */
} stru_ipc_text;
/**
* @brief IPC
*/
typedef enum
{
IPC_RESP_NONE = 1, /* 无需响应 */
IPC_RESP_ONCE, /* 单次响应 */
IPC_RESP_ALWAYS /* 持续响应 */
} enum_ipc_resp;
/**
* @brief IPC System V
*/
typedef struct
{
long id; /* 消息类型 ID */
stru_ipc_text t; /* 消息载荷 */
} stru_ipc_msg;
/**
* @brief 256 CRC
* @note flag 0xA55AA55AA55AA55A
*/
#pragma pack(1)
typedef struct
{
uint64_t flag; /* 魔数标识 0xA55AA55AA55AA55A */
char ver[16]; /* 版本号 */
char author[16]; /* 作者 */
char modify[32]; /* 修改时间 YYYY-MM-DD HH-MM-SS */
uint16_t crc; /* CRC16 校验 */
char desc[128]; /* 附加描述 */
char bak[54]; /* 对齐填充(总计 256 字节) */
} stru_file_info;
#pragma pack()
/* ================================================================
* CRC16 使 Modbus 0xA001
* ================================================================ */
/** 8 位累加校验和 */
uint8_t func_cal_sum_byte(const uint8_t *d, uint32_t n);
/** 16 位累加校验和 */
uint16_t func_cal_sum_word(const uint8_t *d, uint32_t n);
/** CRC16Modbus 多项式,初始值 0xFFFF */
uint16_t func_cal_crc16(const uint8_t *d, uint32_t n);
/** CRC32标准多项式初始值 0xFFFFFFFF */
uint32_t func_cal_crc32(const uint8_t *d, uint32_t n);
/** 文件 CRC164KB 缓冲区流式计算) */
uint16_t func_cal_file_crc16(const char *path);
/** 文件 CRC324KB 缓冲区流式计算) */
uint32_t func_cal_file_crc32(const char *path);
/* ================================================================
*
* ================================================================ */
/** 单个十六进制字符 → 数值('F'→15 */
uint8_t func_hex_ch(char c);
/** 单个十进制字符 → 数值('9'→9 */
uint8_t func_dec_ch(char c);
/** 十六进制字符串 "FF" → int 255 */
int func_hex2dec(char *s);
/** 十进制字符串 "255" → int 255支持负号 */
int func_dec2dec(char *s);
/**
* @brief
* @param s "0102FF"
* @param dst
* @param len [out]
* @return 0 -1
*/
int func_hex2buf(const char *s, char *dst, int *len);
/**
* @brief int
* @param width 0 width=4 val=255 "0255"
*/
char *func_dec2str(char *buf, int sz, int val, int width);
/** int → 十六进制字符串width=0 时不补零) */
char *func_hex2str(char *buf, int sz, int val, int width);
/** float → 字符串 */
char *func_float2str(char *buf, int sz, float f, int width);
/** 字节数组 → 十六进制字符串(如 {0x01,0xFF} → "01FF" */
char *func_buf2str(char *buf, int sz, const char *src, int n);
/** 字符串按空格分割为 argc/argv */
int func_str2argv(char *s, uint8_t *argc, char *argv[], uint8_t max);
/* ================================================================
*
* ================================================================ */
/** 系统时间 → "YYYY-MM-DD HH:MM:SS.mmm" 格式字符串 */
char *func_time_sys2str(char *buf, int sz, stru_time_sys *t);
/** 字符串 → 系统时间,解析失败返回 -1 */
int func_str2time_sys(const char *s, stru_time_sys *t);
/** 获取当前时间type: 1=stru_time_sys, 2=stru_time_cal */
int func_get_time(void *t, int type);
/** 设置系统时间(需要 root 权限) */
int func_set_time(void *t, int type);
/** 系统时间 → 日历时间 */
void func_time_sys2cal(stru_time_sys *src, stru_time_cal *dst);
/** 日历时间 → 系统时间 */
void func_time_cal2sys(stru_time_cal *src, stru_time_sys *dst);
/* ================================================================
*
* ================================================================ */
/** 判断目录是否存在(返回 1=存在, 0=不存在) */
int func_dir_exist(const char *p);
/** 递归创建目录 */
int func_make_dirs(const char *p);
/** 递归删除目录(含所有内容) */
int func_del_dirs(const char *p);
/** 通过系统命令删除目录rm -rf */
int func_del_dirs_cmd(const char *p);
/** 判断文件是否存在(返回 1=存在, 0=不存在) */
int func_file_exist(const char *p);
/** 获取文件大小(字节),失败返回 0 */
uint32_t func_file_size(const char *p);
/** 读取文件到预分配缓冲区out 返回实际读取字节数 */
int func_read_file(const char *p, char *buf, uint32_t cap, uint32_t *out);
/** 读取文件到动态分配缓冲区(调用者负责 free */
uint8_t *func_read_file_alloc(const char *p, uint32_t *out);
/** 写缓冲区到文件(覆盖模式) */
int func_write_file(const char *p, const char *buf, uint32_t n);
/**
* @brief
* @param check 1= flag CRC0=
*/
int func_read_file_info(const char *p, stru_file_info *info, int check);
/* ================================================================
* /proc
* ================================================================ */
/** 获取当前进程名称 */
int func_proc_self_name(char *buf, uint32_t sz);
/** 通过 PID 获取进程名称 */
int func_proc_name_by_pid(int pid, char *buf, uint32_t sz);
/** 获取当前进程 PID */
int func_proc_pid(void);
/** 通过进程名称获取 PID返回 -1 表示未找到) */
int func_proc_pid_by_name(const char *name);
/** 通过 PID 判断进程是否存在 */
int func_proc_exist_by_pid(int pid);
/** 通过名称判断进程是否存在 */
int func_proc_exist_by_name(const char *name);
/** 通过 PID 获取进程可执行文件路径 */
int func_proc_path_by_pid(int pid, char *buf, uint32_t sz);
/** 获取当前进程可执行文件路径 */
int func_proc_self_path(char *buf, uint32_t sz);
/** 获取当前进程所在目录 */
int func_proc_self_dir(char *buf, uint32_t sz);
/* ================================================================
*
* ================================================================ */
/** 获取工作目录路径(环境变量 WORK_PATH */
int func_get_work_path(char *buf, uint32_t sz);
/** 获取系统配置路径SYS_CFG_PATH */
int func_get_syscfg_path(char *buf, uint32_t sz);
/** 获取应用根路径APP_ROOT_PATH */
int func_get_app_root(char *buf, uint32_t sz);
/** 获取历史数据根路径HIS_ROOT_PATH */
int func_get_his_root(char *buf, uint32_t sz);
/** 获取日志根路径LOG_ROOT_PATH */
int func_get_log_root(char *buf, uint32_t sz);
/** 获取数据库根路径DBC_ROOT_PATH */
int func_get_dbc_root(char *buf, uint32_t sz);
/** 获取脚本路径SHELL_PATH */
int func_get_shell_path(char *buf, uint32_t sz);
/** 获取更新包路径UPDATE_PATH */
int func_get_update_path(char *buf, uint32_t sz);
/** 拼接应用路径APP_ROOT_PATH/app_name */
int func_get_app_path(const char *app, char *buf, uint32_t sz);
/** 拼接应用配置路径APP_ROOT_PATH/app_name/ext */
int func_get_app_cfg(const char *app, const char *ext, char *buf, uint32_t sz);
/** 拼接应用历史路径HIS_ROOT_PATH/app_name */
int func_get_app_his(const char *app, char *buf, uint32_t sz);
/** 拼接应用日志路径LOG_ROOT_PATH/app_name */
int func_get_app_log(const char *app, char *buf, uint32_t sz);
/* ================================================================
* IPC System V
* ================================================================ */
/** 按进程名创建消息队列 */
int func_ipc_create_by_name(char *name, int *qid);
/** 按 PID 创建消息队列 */
int func_ipc_create_by_pid(int pid, int *qid);
/** 按进程名获取消息队列 ID不存在则创建 */
int func_ipc_get_by_name(const char *name, int *qid);
/** 按 PID 获取消息队列 ID不存在则创建 */
int func_ipc_get_by_pid(int pid, int *qid);
/** 发送原始字节到消息队列 */
int func_ipc_send_buf(int qid, uint8_t *tx, uint32_t n);
/** 从消息队列接收原始字节 */
int func_ipc_recv_buf(int qid, uint8_t *rx, uint32_t n);
/** 发送结构体消息 */
int func_ipc_send_msg(int qid, stru_ipc_msg *m);
/** 接收结构体消息 */
int func_ipc_recv_msg(int qid, stru_ipc_msg *m);
/** 删除消息队列 */
int func_ipc_delete(int qid);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,69 +0,0 @@
/**
* @file myLog.h
* @brief C
* @details INFO/ERROR
* log_prt pthread_once init
* ANSI
*/
#ifndef _MY_LOG_H_
#define _MY_LOG_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** 日志级别INFO普通信息白色输出 */
#define LOG_INFO 0
/** 日志级别ERROR错误信息红色输出 */
#define LOG_ERROR 1
/**
* @brief log_prt
* @param dir NULL 使 /tmp/logs
* @return 0
*/
int log_init(const char *dir);
/**
* @brief
* @param level LOG_INFO LOG_ERROR
* @param file __FILE__
* @param func __FUNCTION__
* @param line __LINE__
* @param fmt printf
* @param ...
*/
void log_prt(uint32_t level, const char *file, const char *func,
uint32_t line, const char *fmt, ...);
/** 开启日志文件写入 */
void log_file_on(void);
/** 关闭日志文件写入 */
void log_file_off(void);
/** 开启控制台彩色输出 */
void log_console_on(void);
/** 关闭控制台输出 */
void log_console_off(void);
/** 等待异步队列清空(阻塞直到所有消息写入完成) */
void log_flush(void);
/** 停止工作线程、关闭文件、释放消息池 */
void log_cleanup(void);
/** INFO 级别便捷日志宏 */
#define LOG_I(fmt, ...) log_prt(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
/** ERROR 级别便捷日志宏 */
#define LOG_E(fmt, ...) log_prt(LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,58 +0,0 @@
/**
* @file myMd5.h
* @brief MD5 RFC 1321
* @details 128
* 便 md5_string()
*/
#ifndef _MY_MD5_H_
#define _MY_MD5_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief MD5 + +
*/
typedef struct
{
uint32_t state[4]; /* A, B, C, D 四个 32 位状态寄存器 */
uint32_t count[2]; /* 位计数(低 32 位, 高 32 位) */
unsigned char buf[64]; /* 待处理数据缓冲区64 字节) */
} stru_md5_ctx;
/**
* @brief MD5
* @param ctx A=0x67452301 B=0xefcdab89 C=0x98badcfe D=0x10325476
*/
void md5_start(stru_md5_ctx *ctx);
/**
* @brief
* @param ctx
* @param data
* @param len
*/
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len);
/**
* @brief 16 MD5
* @param ctx
* @param result 16
*/
void md5_final(stru_md5_ctx *ctx, unsigned char result[16]);
/**
* @brief 便 MD5
* @param input '\0'
* @param output 33 '\0'
*/
void md5_string(const char *input, char output[33]);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,236 +0,0 @@
/**
* @file myTask.h
* @brief + + C
* @details SPEC §8
* timerfd + epoll
* + pthread
* + +
*/
#ifndef _MY_TASK_H_
#define _MY_TASK_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* ================================================================
*
* ================================================================ */
/** 定时器回调函数类型 */
typedef void (*timer_func_cb)(void *arg);
/** 不透明句柄类型 */
typedef void *stru_task_timer_t;
typedef void *stru_task_event_t;
typedef void *stru_task_msg_queue_t;
/* ================================================================
*
* ================================================================ */
/** 单次触发(到期后自动停止) */
#define TASK_TIMER_FLAG_ONCE 0x01
/** 周期触发(到期后自动重新计时) */
#define TASK_TIMER_FLAG_PERIODIC 0x02
/* ================================================================
*
* ================================================================ */
/** 永久等待(不超时) */
#define TASK_EVENT_WAIT_FOREVER 0xFFFFFFFF
/** 事件标记等待所有位都置位AND 模式) */
#define TASK_EVENT_FLAG_AND 0x01
/** 事件标记等待任意位置位OR 模式) */
#define TASK_EVENT_FLAG_OR 0x02
/** 事件标记:接收后自动清除已匹配的位 */
#define TASK_EVENT_FLAG_CLEAR 0x04
/* ================================================================
*
* ================================================================ */
/**
* @brief
* @param ms
*/
void task_sleep_ms(uint32_t ms);
/* ================================================================
* API
* ================================================================ */
/**
* @brief
* @param name
* @return NULL
*/
stru_task_event_t task_event_create(const char *name);
/**
* @brief
* @param p_event
* @return 0 -1
*/
int task_event_destroy(stru_task_event_t p_event);
/**
* @brief
* @param p_event
* @param event
* @return 0 -1
*/
int task_event_send(stru_task_event_t p_event, uint32_t event);
/**
* @brief
* @param p_event
* @param set
* @param opt TASK_EVENT_FLAG_AND/OR/CLEAR
* @param timeout_ms TASK_EVENT_WAIT_FOREVER=
* @param recved
* @return 0 -1
*/
int task_event_recv(stru_task_event_t p_event, uint32_t set, uint32_t opt,
uint32_t timeout_ms, uint32_t *recved);
/**
* @brief
* @param p_event
* @param event
* @return 0 -1
*/
int task_event_clear(stru_task_event_t p_event, uint32_t event);
/**
* @brief
* @param p_event
* @return
*/
uint32_t task_event_query(stru_task_event_t p_event);
/* ================================================================
* API
* ================================================================ */
/**
* @brief
* @param name
* @param msg_size
* @param msg_num
* @return NULL
*/
stru_task_msg_queue_t task_msg_queue_create(const char *name,
uint32_t msg_size, uint32_t msg_num);
/**
* @brief
* @param p_queue
* @return 0 -1
*/
int task_msg_queue_destroy(stru_task_msg_queue_t p_queue);
/**
* @brief
* @param p_queue
* @param msg
* @param size <= msg_size
* @return 0 -1
*/
int task_msg_queue_send(stru_task_msg_queue_t p_queue, const void *msg,
uint32_t size);
/**
* @brief
* @param timeout_ms TASK_EVENT_WAIT_FOREVER=
* @return 0 -1
*/
int task_msg_queue_send_timeout(stru_task_msg_queue_t p_queue, const void *msg,
uint32_t size, uint32_t timeout_ms);
/**
* @brief
* @param timeout_ms TASK_EVENT_WAIT_FOREVER=
* @return 0 -1
*/
int task_msg_queue_recv(stru_task_msg_queue_t p_queue, void *msg,
uint32_t size, uint32_t timeout_ms);
/**
* @brief -1
* @return 0 -1
*/
int task_msg_queue_try_recv(stru_task_msg_queue_t p_queue, void *msg,
uint32_t size);
/**
* @brief
*/
uint32_t task_msg_queue_get_count(stru_task_msg_queue_t p_queue);
/**
* @brief
*/
uint32_t task_msg_queue_space(stru_task_msg_queue_t p_queue);
/* ================================================================
* API
* ================================================================ */
/**
* @brief task_timer_start
* @param name
* @param fun_cb
* @param arg
* @param timeout_ms
* @param flags TASK_TIMER_FLAG_ONCE TASK_TIMER_FLAG_PERIODIC
* @return NULL
*/
stru_task_timer_t task_timer_create(const char *name, timer_func_cb fun_cb,
void *arg, uint32_t timeout_ms, int flags);
/**
* @brief
* @return 0 -1
*/
int task_timer_start(stru_task_timer_t p_timer);
/**
* @brief
* @return 0 -1
*/
int task_timer_stop(stru_task_timer_t p_timer);
/**
* @brief
* @param timeout_ms
* @return 0 -1
*/
int task_timer_restart(stru_task_timer_t p_timer, uint32_t timeout_ms);
/**
* @brief
* @return 0 -1
*/
int task_timer_destroy(stru_task_timer_t p_timer);
/**
* @brief
* @return 1=0=
*/
int task_timer_is_active(stru_task_timer_t p_timer);
#ifdef __cplusplus
}
#endif
#endif /* _MY_TASK_H_ */

View File

@ -1,72 +0,0 @@
/**
* @file myXml.h
* @brief XML C tinyxml2
* @details C XML DOM
* C++ tinyxml2 C
*/
#ifndef _MY_XML_H_
#define _MY_XML_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* 不透明句柄 */
typedef void *myXmlDoc_t;
typedef void *myXmlElem_t;
/* ========== 文档生命周期 ========== */
/** 从文件加载 XML 文档,失败返回 NULL */
myXmlDoc_t myXml_load_file(const char *path);
/** 新建空 XML 文档(含 XML 声明) */
myXmlDoc_t myXml_new_doc(const char *root_name);
/** 释放文档 */
void myXml_free_doc(myXmlDoc_t doc);
/** 获取根元素 */
myXmlElem_t myXml_root_elem(myXmlDoc_t doc);
/** 保存文档到文件 */
int myXml_save_file(myXmlDoc_t doc, const char *path);
/* ========== 元素查询 ========== */
/** 查找第一个匹配名称的子元素 */
myXmlElem_t myXml_first_child(myXmlElem_t parent, const char *name);
/** 查找下一个匹配名称的兄弟元素 */
myXmlElem_t myXml_next_sibling(myXmlElem_t elem, const char *name);
/** 获取字符串属性,不存在返回默认值 */
const char *myXml_attr_str(myXmlElem_t elem, const char *name, const char *def_val);
/** 获取 float 属性,不存在返回默认值 */
float myXml_attr_float(myXmlElem_t elem, const char *name, float def_val);
/** 获取 int 属性,不存在返回默认值 */
int myXml_attr_int(myXmlElem_t elem, const char *name, int def_val);
/* ========== 元素创建 ========== */
/** 为父节点创建子元素 */
myXmlElem_t myXml_new_child(myXmlElem_t parent, const char *name);
/** 设置字符串属性 */
void myXml_set_attr(myXmlElem_t elem, const char *name, const char *value);
/** 设置 int 属性 */
void myXml_set_attr_int(myXmlElem_t elem, const char *name, int value);
/** 设置 float 属性 */
void myXml_set_attr_float(myXmlElem_t elem, const char *name, float value);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,6 @@ OBJS := $(patsubst $(S)/%.c,$(B)/%.o,$(SRCS))
F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)

View File

@ -12,7 +12,6 @@ F := $(CXX_FLAGS) $(I)
.PHONY: all .PHONY: all
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)

View File

@ -12,7 +12,6 @@ F := $(CXX_FLAGS) $(I)
.PHONY: all .PHONY: all
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)

View File

@ -10,7 +10,6 @@ OBJS := $(patsubst $(S)/%.c,$(B)/%.o,$(SRCS))
F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)

View File

@ -3,7 +3,6 @@ DST := $(ROOT_DIR)/release/inc
SRC_H := $(SRC_ROOT_DIR)/public/liblist/inc/list.h SRC_H := $(SRC_ROOT_DIR)/public/liblist/inc/list.h
all: all:
@mkdir -p $(DST) @mkdir -p $(DST)
@cp -f $(SRC_H) $(DST)/ 2>/dev/null && echo "[liblist] copied" || echo "[liblist] skip"
clean: clean:
@rm -f $(DST)/list.h @rm -f $(DST)/list.h
rebuild: clean all rebuild: clean all

View File

@ -10,7 +10,6 @@ OBJS := $(patsubst $(S)/%.c,$(B)/%.o,$(SRCS))
F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/libfunc/inc F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/libfunc/inc
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)

View File

@ -10,7 +10,6 @@ OBJS := $(patsubst $(S)/%.c,$(B)/%.o,$(SRCS))
F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)

View File

@ -10,7 +10,6 @@ OBJS := $(patsubst $(S)/%.c,$(B)/%.o,$(SRCS))
F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc F := $(C_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)

View File

@ -12,7 +12,6 @@ F := $(C_FLAGS) $(I)
.PHONY: all .PHONY: all
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)

View File

@ -12,7 +12,6 @@ F := $(CXX_FLAGS) $(I)
.PHONY: all .PHONY: all
all: all:
@mkdir -p $(ROOT_DIR)/release/inc @mkdir -p $(ROOT_DIR)/release/inc
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
@$(MAKE) $(O) @$(MAKE) $(O)
$(O): $(OBJS) $(O): $(OBJS)

View File

@ -2,7 +2,9 @@ SUBDIRS := ./liblist ./libfunc ./liblog ./libmd5 ./libcJSON ./libmy_xxhash ./lib
define make_subdir define make_subdir
@for d in $(SUBDIRS); do [ -f "$$d/makefile" ] && (cd "$$d" && make -f makefile $1) || true; done @for d in $(SUBDIRS); do [ -f "$$d/makefile" ] && (cd "$$d" && make -f makefile $1) || true; done
endef endef
.PHONY: all clean rebuild ROOT_DIR := $(realpath $(CURDIR)/../../..)
all:; $(call make_subdir,all) .PHONY: all clean rebuild headers
headers:; @cd $(ROOT_DIR) && ./release/copy_headers.sh
all: headers; $(call make_subdir,all)
clean:; $(call make_subdir,clean) clean:; $(call make_subdir,clean)
rebuild: clean all rebuild: clean all