Files
scc/runtime/libcore/include/core_str.h
zzy 186602a301 feat(core): rename string and stream functions for clarity
- Rename `cstring_push` to `cstring_append_ch` and `cstring_push_cstr` to `cstring_append_cstr` for consistent naming with new `cstring_append` function
- Update all callers in lexer and tests to use new function names
- Rename stream `destroy` method to `drop` for consistency with resource management conventions
- Fix potential overflow in string capacity calculation by adjusting growth logic
2025-12-09 18:04:53 +08:00

179 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef __SMCC_CORE_STR_H__
#define __SMCC_CORE_STR_H__
#include "core_impl.h"
#include "core_log.h"
#include "core_type.h"
/**
* @brief 动态字符串结构体
* @attention 创建的字符串对象需要使用 cstring_free 释放
*/
typedef struct cstring {
usize size; /**< 字符串当前大小(包括结尾的'\0'*/
usize cap; /**< 分配的容量 */
char *data; /**< 实际存储数据的指针 */
} cstring_t;
/**
* @brief 创建一个新的空动态字符串对象
*
* @return cstring_t 初始化后的对象
*/
static inline cstring_t cstring_new(void) {
return (cstring_t){.data = null, .size = 0, .cap = 0};
}
/**
* @brief 从 C 风格字符串创建一个动态字符串副本
*
* @param s 输入的 C 风格字符串
* @return cstring_t 新建对象,包含输入字符串的副本
*/
static inline cstring_t cstring_from_cstr(const char *s) {
if (s == null) {
return cstring_new();
}
usize len = 0;
const char *p = s;
while (*p++)
len++;
char *data = (char *)smcc_malloc(len + 1);
Assert(data != null);
smcc_memcpy(data, s, len);
data[len] = '\0';
return (cstring_t){.size = len + 1, .cap = len + 1, .data = data};
}
/**
* @brief 释放动态字符串占用的内存资源
*
* @param str 要被释放的字符串指针
*/
static inline void cstring_free(cstring_t *str) {
if (str == null) {
return;
}
if (str->cap != 0 && str->data != null) {
smcc_free(str->data);
str->data = null;
}
str->size = 0;
str->cap = 0;
}
/**
* @brief 向动态字符串末尾追加一段 C 风格字符串
*
* @param str 目标动态字符串指针
* @param data 要追加的 C 字符串指针
* @param len 要追加的 C 字符串长度
*/
static inline void cstring_append_cstr(cstring_t *str, const char *data,
usize len) {
if (str == null || data == null || len == 0) {
return;
}
if (str->cap == 0) {
// add '\0' to str
str->size = 1;
}
// 如果需要扩容
if (str->size + len > str->cap) {
usize new_cap = str->cap;
while (new_cap < str->size + len) {
if (new_cap == 0) {
new_cap = str->size + len;
break;
} else {
new_cap *= 2;
}
// FIXME 处理溢出情况
}
char *new_data = (char *)smcc_realloc(str->data, new_cap);
Assert(new_data != null);
str->data = new_data;
str->cap = new_cap;
}
smcc_memcpy(str->data + str->size - 1, data, len);
str->size += len;
str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性
}
/**
* @brief 向动态字符串末尾追加另一个动态字符串
*
* @param str 目标动态字符串指针
* @param other 要追加的动态字符串指针
*/
static inline void cstring_append(cstring_t *str, const cstring_t *other) {
cstring_append_cstr(str, other->data, other->size - 1);
}
/**
* @brief 向动态字符串末尾追加一个字符
*
* @param str 目标动态字符串指针
* @param ch 要追加的字符
*/
static inline void cstring_append_ch(cstring_t *str, char ch) {
cstring_append_cstr(str, &ch, 1);
}
/**
* @brief 获取动态字符串的实际内容长度 不包括结尾的'\0'
*
* @param str 动态字符串指针
* @return usize 字符串实际长度
*/
static inline usize cstring_len(const cstring_t *str) {
return str ? str->size - 1 : 0;
}
/**
* @brief 判断动态字符串是否为空
*
* @param str 动态字符串指针
* @return cbool
*/
static inline cbool cstring_is_empty(const cstring_t *str) {
return str == null || str->size == 0;
}
/**
* @brief 清空动态字符串内容但保留已分配的内存空间
*
* @param str 动态字符串指针
*/
static inline void cstring_clear(cstring_t *str) {
if (str) {
str->size = 1;
if (str->data) {
str->data[0] = '\0';
}
}
}
/**
* @brief 将动态字符串转换为 C 风格字符串
*
* @param str 动态字符串指针
* @return char* 返回指向内部缓冲区的 C 风格字符串指针
*/
static inline char *cstring_as_cstr(const cstring_t *str) {
if (str == null || str->data == null) {
return "";
}
return str->data;
}
#endif /* __SMCC_CORE_STR_H__ */