refactor(pprocessor): rename macro table type and update function names
- Change `scc_macro_table_t` to `scc_pp_macro_table_t` for consistency - Rename `scc_pp_macro_create` to `scc_pp_macro_new` for naming convention - Remove unused `scc_pp_compress_whitespace` function - Update macro table function names: `scc_pp_find_macro` → `scc_pp_macro_table_get`, `scc_pp_remove_macro` → `scc_pp_macro_table_remove` - Add new `scc_pp_macro_table_set` function for setting macros - Update all function signatures to use new type name - Remove commented-out whitespace compression code from implementation
This commit is contained in:
@@ -22,7 +22,7 @@ typedef struct scc_macro {
|
|||||||
|
|
||||||
typedef struct scc_macro_table {
|
typedef struct scc_macro_table {
|
||||||
scc_hashtable_t table; // 宏定义表
|
scc_hashtable_t table; // 宏定义表
|
||||||
} scc_macro_table_t;
|
} scc_pp_macro_table_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建宏对象
|
* @brief 创建宏对象
|
||||||
@@ -30,8 +30,8 @@ typedef struct scc_macro_table {
|
|||||||
* @param type 宏类型
|
* @param type 宏类型
|
||||||
* @return 创建的宏对象指针,失败返回NULL
|
* @return 创建的宏对象指针,失败返回NULL
|
||||||
*/
|
*/
|
||||||
scc_pp_macro_t *scc_pp_macro_create(const scc_cstring_t *name,
|
scc_pp_macro_t *scc_pp_macro_new(const scc_cstring_t *name,
|
||||||
scc_pp_macro_type_t type);
|
scc_pp_macro_type_t type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 销毁宏对象
|
* @brief 销毁宏对象
|
||||||
@@ -39,13 +39,6 @@ scc_pp_macro_t *scc_pp_macro_create(const scc_cstring_t *name,
|
|||||||
*/
|
*/
|
||||||
void scc_pp_macro_drop(scc_pp_macro_t *macro);
|
void scc_pp_macro_drop(scc_pp_macro_t *macro);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 压缩空白字符
|
|
||||||
* @param tokens token列表
|
|
||||||
* @return 压缩后的字符串
|
|
||||||
*/
|
|
||||||
scc_cstring_t scc_pp_compress_whitespace(const scc_pp_macro_list_t *tokens);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 添加对象宏
|
* @brief 添加对象宏
|
||||||
* @param pp 预处理器实例
|
* @param pp 预处理器实例
|
||||||
@@ -53,7 +46,8 @@ scc_cstring_t scc_pp_compress_whitespace(const scc_pp_macro_list_t *tokens);
|
|||||||
* @param replacement 替换文本列表
|
* @param replacement 替换文本列表
|
||||||
* @return 成功返回true,失败返回false
|
* @return 成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
cbool scc_pp_add_object_macro(scc_macro_table_t *pp, const scc_cstring_t *name,
|
cbool scc_pp_add_object_macro(scc_pp_macro_table_t *pp,
|
||||||
|
const scc_cstring_t *name,
|
||||||
const scc_pp_macro_list_t *replacement);
|
const scc_pp_macro_list_t *replacement);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,10 +58,19 @@ cbool scc_pp_add_object_macro(scc_macro_table_t *pp, const scc_cstring_t *name,
|
|||||||
* @param replacement 替换文本列表
|
* @param replacement 替换文本列表
|
||||||
* @return 成功返回true,失败返回false
|
* @return 成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
cbool scc_pp_add_function_macro(scc_macro_table_t *pp,
|
cbool scc_pp_add_function_macro(scc_pp_macro_table_t *pp,
|
||||||
const scc_cstring_t *name,
|
const scc_cstring_t *name,
|
||||||
const scc_pp_macro_list_t *params,
|
const scc_pp_macro_list_t *params,
|
||||||
const scc_pp_macro_list_t *replacement);
|
const scc_pp_macro_list_t *replacement);
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param pp
|
||||||
|
* @param macro
|
||||||
|
* @return scc_pp_macro_t*
|
||||||
|
*/
|
||||||
|
scc_pp_macro_t *scc_pp_macro_table_set(scc_pp_macro_table_t *pp,
|
||||||
|
scc_pp_macro_t *macro);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 查找宏定义
|
* @brief 查找宏定义
|
||||||
@@ -75,7 +78,8 @@ cbool scc_pp_add_function_macro(scc_macro_table_t *pp,
|
|||||||
* @param name 宏名称
|
* @param name 宏名称
|
||||||
* @return 找到的宏对象指针,未找到返回NULL
|
* @return 找到的宏对象指针,未找到返回NULL
|
||||||
*/
|
*/
|
||||||
scc_pp_macro_t *scc_pp_find_macro(scc_macro_table_t *pp, scc_cstring_t *name);
|
scc_pp_macro_t *scc_pp_macro_table_get(scc_pp_macro_table_t *pp,
|
||||||
|
scc_cstring_t *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 从预处理器中删除宏
|
* @brief 从预处理器中删除宏
|
||||||
@@ -83,8 +87,9 @@ scc_pp_macro_t *scc_pp_find_macro(scc_macro_table_t *pp, scc_cstring_t *name);
|
|||||||
* @param name 宏名称
|
* @param name 宏名称
|
||||||
* @return 成功删除返回true,未找到返回false
|
* @return 成功删除返回true,未找到返回false
|
||||||
*/
|
*/
|
||||||
cbool scc_pp_remove_macro(scc_macro_table_t *pp, const scc_cstring_t *name);
|
cbool scc_pp_macro_table_remove(scc_pp_macro_table_t *pp,
|
||||||
|
const scc_cstring_t *name);
|
||||||
|
|
||||||
void scc_pp_marco_table_init(scc_macro_table_t *macros);
|
void scc_pp_marco_table_init(scc_pp_macro_table_t *macros);
|
||||||
void scc_pp_macro_table_drop(scc_macro_table_t *macros);
|
void scc_pp_macro_table_drop(scc_pp_macro_table_t *macros);
|
||||||
#endif /* __SCC_PP_MACRO_H__ */
|
#endif /* __SCC_PP_MACRO_H__ */
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
#include <libcore.h>
|
#include <libcore.h>
|
||||||
#include <pp_macro.h>
|
#include <pp_macro.h>
|
||||||
void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
||||||
scc_macro_table_t *macros);
|
scc_pp_macro_table_t *macros);
|
||||||
cbool scc_pp_expand_macro(scc_probe_stream_t *stream, scc_macro_table_t *macros,
|
cbool scc_pp_expand_macro(scc_probe_stream_t *stream,
|
||||||
|
scc_pp_macro_table_t *macros,
|
||||||
|
scc_pp_macro_table_t *expand_stack,
|
||||||
scc_probe_stream_t **out_stream, int depth);
|
scc_probe_stream_t **out_stream, int depth);
|
||||||
|
|
||||||
#endif /* __SCC_PP_PARSE_H__ */
|
#endif /* __SCC_PP_PARSE_H__ */
|
||||||
|
|||||||
@@ -5,21 +5,21 @@
|
|||||||
/// https://cppreference.cn/w/c/preprocessor
|
/// https://cppreference.cn/w/c/preprocessor
|
||||||
#define SCC_PP_INST_TOKEN \
|
#define SCC_PP_INST_TOKEN \
|
||||||
X(define , SCC_PP_STD, SCC_PP_TOK_DEFINE ) \
|
X(define , SCC_PP_STD, SCC_PP_TOK_DEFINE ) \
|
||||||
X(undef , SCC_PP_STD, SCC_PP_TOK_UNDEF ) \
|
X(elif , SCC_PP_STD, SCC_PP_TOK_UNDEF ) \
|
||||||
X(include , SCC_PP_STD, SCC_PP_TOK_INCLUDE ) \
|
X(elifdef , SCC_PP_STD, SCC_PP_TOK_INCLUDE ) \
|
||||||
X(if , SCC_PP_STD, SCC_PP_TOK_IF ) \
|
X(elifndef , SCC_PP_STD, SCC_PP_TOK_IF ) \
|
||||||
X(ifdef , SCC_PP_STD, SCC_PP_TOK_IFDEF ) \
|
X(else , SCC_PP_STD, SCC_PP_TOK_IFDEF ) \
|
||||||
X(ifndef , SCC_PP_STD, SCC_PP_TOK_IFNDEF ) \
|
X(embed , SCC_PP_STD, SCC_PP_TOK_IFNDEF ) \
|
||||||
X(else , SCC_PP_STD, SCC_PP_TOK_ELSE ) \
|
X(endif , SCC_PP_STD, SCC_PP_TOK_ELSE ) \
|
||||||
X(elif , SCC_PP_STD, SCC_PP_TOK_ELIF ) \
|
X(error , SCC_PP_STD, SCC_PP_TOK_ELIF ) \
|
||||||
X(elifdef , SCC_PP_STD, SCC_PP_TOK_ELIFDEF ) \
|
X(if , SCC_PP_STD, SCC_PP_TOK_ELIFDEF ) \
|
||||||
X(elifndef , SCC_PP_C23, SCC_PP_TOK_ELIFNDEF ) \
|
X(ifdef , SCC_PP_C23, SCC_PP_TOK_ELIFNDEF ) \
|
||||||
X(endif , SCC_PP_STD, SCC_PP_TOK_ENDIF ) \
|
X(ifndef , SCC_PP_STD, SCC_PP_TOK_ENDIF ) \
|
||||||
X(line , SCC_PP_STD, SCC_PP_TOK_LINE ) \
|
X(include , SCC_PP_STD, SCC_PP_TOK_LINE ) \
|
||||||
X(embed , SCC_PP_C23, SCC_PP_TOK_EMBED ) \
|
X(line , SCC_PP_C23, SCC_PP_TOK_EMBED ) \
|
||||||
X(error , SCC_PP_STD, SCC_PP_TOK_ERROR ) \
|
X(pragma , SCC_PP_STD, SCC_PP_TOK_ERROR ) \
|
||||||
X(warning , SCC_PP_C23, SCC_PP_TOK_WARNING ) \
|
X(undef , SCC_PP_C23, SCC_PP_TOK_WARNING ) \
|
||||||
X(pragma , SCC_PP_STD, SCC_PP_TOK_PRAMA ) \
|
X(warning , SCC_PP_STD, SCC_PP_TOK_PRAMA ) \
|
||||||
// END
|
// END
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ typedef struct if_stack_item {
|
|||||||
typedef struct scc_pproc {
|
typedef struct scc_pproc {
|
||||||
scc_probe_stream_t *stream; // 输出流
|
scc_probe_stream_t *stream; // 输出流
|
||||||
scc_strpool_t strpool; // 字符串池
|
scc_strpool_t strpool; // 字符串池
|
||||||
scc_macro_table_t macro_table;
|
scc_pp_macro_table_t macro_table;
|
||||||
SCC_VEC(if_stack_item_t) if_stack; // 条件编译栈
|
SCC_VEC(if_stack_item_t) if_stack; // 条件编译栈
|
||||||
} scc_pproc_t;
|
} scc_pproc_t;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <pp_macro.h>
|
#include <pp_macro.h>
|
||||||
|
|
||||||
// 创建宏对象
|
// 创建宏对象
|
||||||
scc_pp_macro_t *scc_pp_macro_create(const scc_cstring_t *name,
|
scc_pp_macro_t *scc_pp_macro_new(const scc_cstring_t *name,
|
||||||
scc_pp_macro_type_t type) {
|
scc_pp_macro_type_t type) {
|
||||||
scc_pp_macro_t *macro = scc_malloc(sizeof(scc_pp_macro_t));
|
scc_pp_macro_t *macro = scc_malloc(sizeof(scc_pp_macro_t));
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
LOG_ERROR("Failed to allocate memory for macro");
|
LOG_ERROR("Failed to allocate memory for macro");
|
||||||
@@ -39,66 +39,17 @@ void scc_pp_macro_drop(scc_pp_macro_t *macro) {
|
|||||||
scc_free(macro);
|
scc_free(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 压缩空白字符
|
|
||||||
// scc_cstring_t scc_pp_compress_whitespace(const scc_pp_macro_list_t *tokens) {
|
|
||||||
// scc_cstring_t combined = scc_cstring_new();
|
|
||||||
// cbool last_was_space = false;
|
|
||||||
|
|
||||||
// for (usize i = 0; i < tokens->size; ++i) {
|
|
||||||
// scc_cstring_t *token = &scc_vec_at(*tokens, i);
|
|
||||||
// const char *str = scc_cstring_as_cstr(token);
|
|
||||||
// usize len = scc_cstring_len(token);
|
|
||||||
|
|
||||||
// for (usize j = 0; j < len; ++j) {
|
|
||||||
// char ch = str[j];
|
|
||||||
// if (ch == ' ' || ch == '\t') {
|
|
||||||
// if (!last_was_space && !scc_cstring_is_empty(&combined)) {
|
|
||||||
// scc_cstring_append_ch(&combined, ' ');
|
|
||||||
// last_was_space = true;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// scc_cstring_append_ch(&combined, ch);
|
|
||||||
// last_was_space = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 在 token 之间添加一个空格(除非已经是空格)
|
|
||||||
// if (i + 1 < tokens->size && !last_was_space &&
|
|
||||||
// !scc_cstring_is_empty(&combined)) {
|
|
||||||
// scc_cstring_append_ch(&combined, ' ');
|
|
||||||
// last_was_space = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 去除尾随空格
|
|
||||||
// while (!scc_cstring_is_empty(&combined) &&
|
|
||||||
// (combined.data[combined.size - 1] == ' ' ||
|
|
||||||
// combined.data[combined.size - 1] == '\t')) {
|
|
||||||
// combined.size--;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return combined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 添加对象宏
|
// 添加对象宏
|
||||||
cbool scc_pp_add_object_macro(scc_macro_table_t *macros,
|
cbool scc_pp_add_object_macro(scc_pp_macro_table_t *macros,
|
||||||
const scc_cstring_t *name,
|
const scc_cstring_t *name,
|
||||||
const scc_pp_macro_list_t *replacement) {
|
const scc_pp_macro_list_t *replacement) {
|
||||||
if (!macros || !name || !replacement)
|
if (!macros || !name || !replacement)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
scc_pp_macro_t *macro = scc_pp_macro_create(name, SCC_PP_MACRO_OBJECT);
|
scc_pp_macro_t *macro = scc_pp_macro_new(name, SCC_PP_MACRO_OBJECT);
|
||||||
if (!macro)
|
if (!macro)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// if (replacement->size > 0) {
|
|
||||||
// scc_cstring_t combined = scc_pp_compress_whitespace(replacement);
|
|
||||||
// scc_vec_push(macro->replaces, combined);
|
|
||||||
// // 释放原始 tokens
|
|
||||||
// for (usize i = 0; i < replacement->size; ++i) {
|
|
||||||
// scc_cstring_free(&scc_vec_at(*replacement, i));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
macro->replaces = *replacement;
|
macro->replaces = *replacement;
|
||||||
|
|
||||||
// 检查是否已存在同名宏
|
// 检查是否已存在同名宏
|
||||||
@@ -113,14 +64,14 @@ cbool scc_pp_add_object_macro(scc_macro_table_t *macros,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加函数宏
|
// 添加函数宏
|
||||||
cbool scc_pp_add_function_macro(scc_macro_table_t *macros,
|
cbool scc_pp_add_function_macro(scc_pp_macro_table_t *macros,
|
||||||
const scc_cstring_t *name,
|
const scc_cstring_t *name,
|
||||||
const scc_pp_macro_list_t *params,
|
const scc_pp_macro_list_t *params,
|
||||||
const scc_pp_macro_list_t *replacement) {
|
const scc_pp_macro_list_t *replacement) {
|
||||||
if (!macros || !name || !params || !replacement)
|
if (!macros || !name || !params || !replacement)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
scc_pp_macro_t *macro = scc_pp_macro_create(name, SCC_PP_MACRO_FUNCTION);
|
scc_pp_macro_t *macro = scc_pp_macro_new(name, SCC_PP_MACRO_FUNCTION);
|
||||||
if (!macro)
|
if (!macro)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -128,17 +79,6 @@ cbool scc_pp_add_function_macro(scc_macro_table_t *macros,
|
|||||||
macro->params = *params;
|
macro->params = *params;
|
||||||
macro->replaces = *replacement;
|
macro->replaces = *replacement;
|
||||||
|
|
||||||
// if (replacement->size > 0) {
|
|
||||||
// // 函数宏直接存储替换文本
|
|
||||||
// scc_cstring_t combined = scc_pp_compress_whitespace(replacement);
|
|
||||||
// scc_vec_push(macro->replaces, combined);
|
|
||||||
|
|
||||||
// // 释放原始 tokens
|
|
||||||
// for (usize i = 0; i < replacement->size; ++i) {
|
|
||||||
// scc_cstring_free(&scc_vec_at(*replacement, i));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 检查是否已存在同名宏
|
// 检查是否已存在同名宏
|
||||||
scc_pp_macro_t *existing = scc_hashtable_get(¯os->table, ¯o->name);
|
scc_pp_macro_t *existing = scc_hashtable_get(¯os->table, ¯o->name);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
@@ -150,13 +90,23 @@ cbool scc_pp_add_function_macro(scc_macro_table_t *macros,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// marco_table
|
||||||
|
|
||||||
|
scc_pp_macro_t *scc_pp_macro_table_set(scc_pp_macro_table_t *pp,
|
||||||
|
scc_pp_macro_t *macro) {
|
||||||
|
Assert(pp != null && macro != null);
|
||||||
|
return scc_hashtable_set(&pp->table, ¯o->name, macro);
|
||||||
|
}
|
||||||
|
|
||||||
// 查找宏定义
|
// 查找宏定义
|
||||||
scc_pp_macro_t *scc_pp_find_macro(scc_macro_table_t *pp, scc_cstring_t *name) {
|
scc_pp_macro_t *scc_pp_macro_table_get(scc_pp_macro_table_t *pp,
|
||||||
|
scc_cstring_t *name) {
|
||||||
return scc_hashtable_get(&pp->table, name);
|
return scc_hashtable_get(&pp->table, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从预处理器中删除宏
|
// 从预处理器中删除宏
|
||||||
cbool scc_pp_remove_macro(scc_macro_table_t *pp, const scc_cstring_t *name) {
|
cbool scc_pp_macro_table_remove(scc_pp_macro_table_t *pp,
|
||||||
|
const scc_cstring_t *name) {
|
||||||
if (!pp || !name)
|
if (!pp || !name)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -169,8 +119,6 @@ cbool scc_pp_remove_macro(scc_macro_table_t *pp, const scc_cstring_t *name) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// marco_table
|
|
||||||
|
|
||||||
static u32 hash_func(const void *key) {
|
static u32 hash_func(const void *key) {
|
||||||
const scc_cstring_t *string = (const scc_cstring_t *)key;
|
const scc_cstring_t *string = (const scc_cstring_t *)key;
|
||||||
return scc_strhash32(scc_cstring_as_cstr(string));
|
return scc_strhash32(scc_cstring_as_cstr(string));
|
||||||
@@ -186,7 +134,7 @@ static int hash_cmp(const void *key1, const void *key2) {
|
|||||||
return scc_strcmp(scc_cstring_as_cstr(str1), scc_cstring_as_cstr(str2));
|
return scc_strcmp(scc_cstring_as_cstr(str1), scc_cstring_as_cstr(str2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void scc_pp_marco_table_init(scc_macro_table_t *macros) {
|
void scc_pp_marco_table_init(scc_pp_macro_table_t *macros) {
|
||||||
Assert(macros != null);
|
Assert(macros != null);
|
||||||
macros->table.hash_func = hash_func;
|
macros->table.hash_func = hash_func;
|
||||||
macros->table.key_cmp = hash_cmp;
|
macros->table.key_cmp = hash_cmp;
|
||||||
@@ -200,7 +148,7 @@ static int macro_free(const void *key, void *value, void *context) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scc_pp_macro_table_drop(scc_macro_table_t *macros) {
|
void scc_pp_macro_table_drop(scc_pp_macro_table_t *macros) {
|
||||||
Assert(macros != null);
|
Assert(macros != null);
|
||||||
scc_hashtable_foreach(¯os->table, macro_free, null);
|
scc_hashtable_foreach(¯os->table, macro_free, null);
|
||||||
scc_hashtable_drop(¯os->table);
|
scc_hashtable_drop(¯os->table);
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ static cbool safe_skip_backspace_if_endline(scc_probe_stream_t *stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
||||||
scc_macro_table_t *macros) {
|
scc_pp_macro_table_t *macros) {
|
||||||
Assert(stream != null);
|
Assert(stream != null);
|
||||||
|
|
||||||
scc_probe_stream_reset(stream);
|
scc_probe_stream_reset(stream);
|
||||||
@@ -264,7 +264,7 @@ void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
|||||||
case SCC_PP_TOK_UNDEF: {
|
case SCC_PP_TOK_UNDEF: {
|
||||||
if (scc_lex_parse_identifier(stream, pos, &name)) {
|
if (scc_lex_parse_identifier(stream, pos, &name)) {
|
||||||
// TODO ret value
|
// TODO ret value
|
||||||
scc_pp_remove_macro(macros, &name);
|
scc_pp_macro_table_remove(macros, &name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,6 @@ void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
|||||||
case SCC_PP_TOK_WARNING:
|
case SCC_PP_TOK_WARNING:
|
||||||
case SCC_PP_TOK_PRAMA:
|
case SCC_PP_TOK_PRAMA:
|
||||||
// 暂时跳过这一行
|
// 暂时跳过这一行
|
||||||
TODO();
|
|
||||||
scc_lex_parse_skip_line(stream, pos);
|
scc_lex_parse_skip_line(stream, pos);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -390,11 +389,14 @@ cbool scc_pp_expand_function_macro(scc_pp_macro_t *macro,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbool scc_pp_expand_macro(scc_probe_stream_t *stream, scc_macro_table_t *macros,
|
cbool scc_pp_expand_macro(scc_probe_stream_t *stream,
|
||||||
|
scc_pp_macro_table_t *macros,
|
||||||
|
scc_pp_macro_table_t *expand_stack,
|
||||||
scc_probe_stream_t **out_stream, int depth) {
|
scc_probe_stream_t **out_stream, int depth) {
|
||||||
// TODO self position and it maybe is a stack on #include ?
|
// TODO self position and it maybe is a stack on #include ?
|
||||||
// 递归扫描
|
// 递归扫描
|
||||||
if (depth <= 0) {
|
if (depth <= 0) {
|
||||||
|
*out_stream = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Assert(stream != null && macros != null && out_stream != null);
|
Assert(stream != null && macros != null && out_stream != null);
|
||||||
@@ -406,9 +408,11 @@ cbool scc_pp_expand_macro(scc_probe_stream_t *stream, scc_macro_table_t *macros,
|
|||||||
ret = scc_lex_parse_identifier(stream, &pos, &identifier);
|
ret = scc_lex_parse_identifier(stream, &pos, &identifier);
|
||||||
Assert(ret == true);
|
Assert(ret == true);
|
||||||
|
|
||||||
scc_pp_macro_t *macro = scc_pp_find_macro(macros, &identifier);
|
scc_pp_macro_t *macro = scc_pp_macro_table_get(macros, &identifier);
|
||||||
if (macro == null) {
|
// 1. 不是宏,直接输出标识符
|
||||||
// 不是宏,直接输出标识符
|
// 2. 检查到重复展开跳过
|
||||||
|
if (macro == null ||
|
||||||
|
scc_pp_macro_table_get(expand_stack, ¯o->name) != null) {
|
||||||
*out_stream =
|
*out_stream =
|
||||||
scc_mem_probe_stream_new(scc_cstring_as_cstr(&identifier),
|
scc_mem_probe_stream_new(scc_cstring_as_cstr(&identifier),
|
||||||
scc_cstring_len(&identifier), false);
|
scc_cstring_len(&identifier), false);
|
||||||
@@ -436,15 +440,24 @@ cbool scc_pp_expand_macro(scc_probe_stream_t *stream, scc_macro_table_t *macros,
|
|||||||
Assert(ret == true);
|
Assert(ret == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 已经展开的将被标记并入栈
|
||||||
|
scc_pp_macro_table_set(expand_stack,
|
||||||
|
scc_pp_macro_new(¯o->name, macro->type));
|
||||||
|
|
||||||
|
// 将展开内容变换成stream
|
||||||
scc_probe_stream_t *tmp_stream = scc_mem_probe_stream_new(
|
scc_probe_stream_t *tmp_stream = scc_mem_probe_stream_new(
|
||||||
scc_cstring_as_cstr(&tmp_buff), scc_cstring_len(&tmp_buff), false);
|
scc_cstring_as_cstr(&tmp_buff), scc_cstring_len(&tmp_buff), false);
|
||||||
|
|
||||||
int ch;
|
int ch;
|
||||||
scc_cstring_t real_buff = scc_cstring_new();
|
scc_cstring_t real_buff = scc_cstring_new();
|
||||||
|
|
||||||
while ((ch = scc_probe_stream_peek(tmp_stream)) != scc_stream_eof) {
|
while ((ch = scc_probe_stream_peek(tmp_stream)) != scc_stream_eof) {
|
||||||
if (scc_lex_parse_is_identifier_prefix(ch)) {
|
if (scc_lex_parse_is_identifier_prefix(ch)) {
|
||||||
|
// 递归检查
|
||||||
scc_probe_stream_t *tmp_out_stream;
|
scc_probe_stream_t *tmp_out_stream;
|
||||||
scc_pp_expand_macro(tmp_stream, macros, &tmp_out_stream, depth - 1);
|
if (scc_pp_expand_macro(tmp_stream, macros, expand_stack,
|
||||||
|
&tmp_out_stream, depth - 1) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// scc_cstring_append_cstr();
|
// scc_cstring_append_cstr();
|
||||||
Assert(tmp_out_stream != null);
|
Assert(tmp_out_stream != null);
|
||||||
while (scc_probe_stream_peek(tmp_out_stream) != scc_stream_eof) {
|
while (scc_probe_stream_peek(tmp_out_stream) != scc_stream_eof) {
|
||||||
@@ -462,6 +475,9 @@ cbool scc_pp_expand_macro(scc_probe_stream_t *stream, scc_macro_table_t *macros,
|
|||||||
scc_probe_stream_drop(tmp_stream);
|
scc_probe_stream_drop(tmp_stream);
|
||||||
*out_stream = scc_mem_probe_stream_new(scc_cstring_as_cstr(&real_buff),
|
*out_stream = scc_mem_probe_stream_new(scc_cstring_as_cstr(&real_buff),
|
||||||
scc_cstring_len(&real_buff), false);
|
scc_cstring_len(&real_buff), false);
|
||||||
|
|
||||||
|
// 已经展开的将被标记并出栈
|
||||||
|
scc_pp_macro_table_remove(expand_stack, ¯o->name);
|
||||||
return true;
|
return true;
|
||||||
ERR:
|
ERR:
|
||||||
*out_stream = null;
|
*out_stream = null;
|
||||||
|
|||||||
@@ -30,9 +30,23 @@ RETRY:
|
|||||||
&stream->self->macro_table);
|
&stream->self->macro_table);
|
||||||
goto RETRY;
|
goto RETRY;
|
||||||
} else if (scc_lex_parse_is_identifier_prefix(ch)) {
|
} else if (scc_lex_parse_is_identifier_prefix(ch)) {
|
||||||
scc_pp_expand_macro(stream->input, &stream->self->macro_table,
|
scc_pp_macro_table_t tmp_table;
|
||||||
&stream->tmp_stream, MAX_MACRO_EXPANSION_DEPTH);
|
scc_pp_marco_table_init(&tmp_table);
|
||||||
|
cbool ret = scc_pp_expand_macro(
|
||||||
|
stream->input, &stream->self->macro_table, &tmp_table,
|
||||||
|
&stream->tmp_stream, MAX_MACRO_EXPANSION_DEPTH);
|
||||||
|
scc_pp_macro_table_drop(&tmp_table);
|
||||||
|
if (ret == false) {
|
||||||
|
LOG_ERROR("macro_expand_error");
|
||||||
|
}
|
||||||
goto READ_BUF;
|
goto READ_BUF;
|
||||||
|
} else if (scc_probe_stream_next(stream->input) == '/') {
|
||||||
|
ch = scc_probe_stream_peek(stream->input);
|
||||||
|
if (ch == '/') {
|
||||||
|
scc_lex_parse_skip_line(stream->input, &stream->pos);
|
||||||
|
} else if (ch == '*') {
|
||||||
|
scc_lex_parse_skip_block_comment(stream->input, &stream->pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 非标识符字符,直接消费并返回
|
// 非标识符字符,直接消费并返回
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ static scc_probe_stream_t *from_file_stream(FILE *fp) {
|
|||||||
|
|
||||||
scc_mem_probe_stream_t *mem_stream = malloc(sizeof(scc_mem_probe_stream_t));
|
scc_mem_probe_stream_t *mem_stream = malloc(sizeof(scc_mem_probe_stream_t));
|
||||||
scc_probe_stream_t *stream =
|
scc_probe_stream_t *stream =
|
||||||
scc_mem_probe_stream_init(mem_stream, buffer, fsize, true);
|
scc_mem_probe_stream_init(mem_stream, buffer, read_ret, true);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,32 +38,50 @@ static void test_file(const char *name) {
|
|||||||
assert(fexpect != NULL);
|
assert(fexpect != NULL);
|
||||||
|
|
||||||
scc_pproc_t pp;
|
scc_pproc_t pp;
|
||||||
scc_mem_probe_stream_t stream;
|
|
||||||
scc_probe_stream_t *output_stream =
|
scc_probe_stream_t *output_stream =
|
||||||
scc_pproc_init(&pp, from_file_stream(fsrc));
|
scc_pproc_init(&pp, from_file_stream(fsrc));
|
||||||
scc_probe_stream_t *expect_stream = from_file_stream(fexpect);
|
scc_probe_stream_t *expect_stream = from_file_stream(fexpect);
|
||||||
|
|
||||||
|
fclose(fsrc);
|
||||||
|
fclose(fexpect);
|
||||||
|
|
||||||
TEST_CASE(src_fname);
|
TEST_CASE(src_fname);
|
||||||
while (1) {
|
#define BUFFER_LEN 4096
|
||||||
int output_ch = scc_probe_stream_consume(output_stream);
|
int ch;
|
||||||
int expect_ch = scc_probe_stream_consume(expect_stream);
|
char expect_buffer[BUFFER_LEN];
|
||||||
TEST_CHECK(output_ch == expect_ch);
|
char output_buffer[BUFFER_LEN];
|
||||||
TEST_MSG("output: %c %x, expect: %c %x", output_ch, output_ch,
|
usize size_produced = 0, size_expected = 0;
|
||||||
expect_ch, expect_ch);
|
for (usize i = 0; i < BUFFER_LEN; ++i) {
|
||||||
if (output_ch != expect_ch) {
|
ch = scc_probe_stream_consume(expect_stream);
|
||||||
break;
|
if (ch != scc_stream_eof) {
|
||||||
}
|
expect_buffer[i] = (char)ch;
|
||||||
if (output_ch == scc_stream_eof) {
|
} else {
|
||||||
|
size_expected = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (usize i = 0; i < BUFFER_LEN; ++i) {
|
||||||
|
ch = scc_probe_stream_consume(output_stream);
|
||||||
|
if (ch != scc_stream_eof) {
|
||||||
|
output_buffer[i] = (char)ch;
|
||||||
|
} else {
|
||||||
|
size_produced = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEST_CHECK(size_produced == size_expected &&
|
||||||
|
memcmp(output_buffer, expect_buffer, size_produced) == 0);
|
||||||
|
TEST_DUMP("Expected:", expect_buffer, size_expected);
|
||||||
|
TEST_DUMP("Produced:", output_buffer, size_produced);
|
||||||
|
|
||||||
scc_pproc_drop(&pp);
|
scc_pproc_drop(&pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_basic(void) {
|
static void test_basic(void) {
|
||||||
char name[32];
|
char name[32];
|
||||||
for (int i = 1; i <= 22; ++i) {
|
for (int i = 1; i <= 22; ++i) {
|
||||||
// snprintf(name, sizeof(name), "%02d", i);
|
snprintf(name, sizeof(name), "%02d", i);
|
||||||
// test_file(name);
|
test_file(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,43 @@ static void test_define_nested_macros(void) {
|
|||||||
"((1 + 1) + 1)\n");
|
"((1 + 1) + 1)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hard_test_define_func_macros(void) {
|
||||||
|
TEST_CASE("func_macros_hard with pp_01");
|
||||||
|
CHECK_PP_OUTPUT_EXACT("#define hash_hash # ## #\n"
|
||||||
|
"#define mkstr(a) # a\n"
|
||||||
|
"#define in_between(a) mkstr(a)\n"
|
||||||
|
"#define join(c, d) in_between(c hash_hash d)\n"
|
||||||
|
"char p[] = join(x, y);\n",
|
||||||
|
"char p[] = \"x ## y\";\n");
|
||||||
|
|
||||||
|
TEST_CASE("func_macros_hard with recursive define");
|
||||||
|
CHECK_PP_OUTPUT_EXACT("#define M1(x) M2(x + 1)\n"
|
||||||
|
"#define M2(x) M1(x * 2)\n"
|
||||||
|
"M1(5)\n",
|
||||||
|
"M1(5 + 1 * 2)\n");
|
||||||
|
CHECK_PP_OUTPUT_EXACT("#define A B\n"
|
||||||
|
"#define B C\n"
|
||||||
|
"#define C 1\n"
|
||||||
|
"A\n",
|
||||||
|
"1\n");
|
||||||
|
|
||||||
|
TEST_CASE("func_macros_hard with self recursive call");
|
||||||
|
CHECK_PP_OUTPUT_EXACT("#define M(x) x\n"
|
||||||
|
"M(M(10))\n",
|
||||||
|
"10\n");
|
||||||
|
CHECK_PP_OUTPUT_EXACT("#define M(x) M(x)\n"
|
||||||
|
"#define N(x) x\n"
|
||||||
|
"N(M(1))\n",
|
||||||
|
"M(1)\n");
|
||||||
|
|
||||||
|
TEST_CASE("func_macros_hard with define by macro");
|
||||||
|
CHECK_PP_OUTPUT_EXACT("#define M1(x) M1(x + 1)\n"
|
||||||
|
"#define M2 M1\n"
|
||||||
|
"#define M3(x) x\n"
|
||||||
|
"M3(M3(M2)(0))\n",
|
||||||
|
"M1(0 + 1)\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void test_conditional_compilation(void) {
|
static void test_conditional_compilation(void) {
|
||||||
TEST_CASE("conditional compilation");
|
TEST_CASE("conditional compilation");
|
||||||
CHECK_PP_OUTPUT_EXACT("#if 1\ntrue\n#endif\n", "true\n");
|
CHECK_PP_OUTPUT_EXACT("#if 1\ntrue\n#endif\n", "true\n");
|
||||||
@@ -140,5 +177,6 @@ TEST_LIST = {
|
|||||||
TEST_LIST_CASE(test_define_stringify_operator),
|
TEST_LIST_CASE(test_define_stringify_operator),
|
||||||
TEST_LIST_CASE(test_define_concat_operator),
|
TEST_LIST_CASE(test_define_concat_operator),
|
||||||
TEST_LIST_CASE(test_define_nested_macros),
|
TEST_LIST_CASE(test_define_nested_macros),
|
||||||
|
TEST_LIST_CASE(hard_test_define_func_macros),
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user