#include "hapdconf_parser.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// 释放 ConfigLine 链表
static void free_lines(ConfigLine *head) {
while (head) {
ConfigLine *tmp = head;
head = head->next;
free(tmp);
}
}
// 释放 BssModule 链表
static void free_bss(BssModule *head) {
while (head) {
BssModule *tmp = head;
head = head->next;
free_lines(tmp->lines);
free(tmp);
}
}
// 释放整个 Config 结构
void config_free(Config *config) {
if (!config) return;
ConfigSection *sec = config->sections;
while (sec) {
ConfigSection *tmp = sec;
sec = sec->next;
if (tmp->is_bss_section) {
free_bss(tmp->bss_list);
} else {
free_lines(tmp->lines);
}
free(tmp);
}
free(config);
}
// 创建新的 Config 结构
Config *config_new() {
Config *config = (Config *)malloc(sizeof(Config));
if (!config) return NULL;
config->sections = NULL;
return config;
}
/**
* 打印指定配置节中的 bss_list 链表内容
*
* @param sec 配置节指针
*/
static void print_bss_list(ConfigSection *sec) {
if (!sec || !sec->is_bss_section) {
printf("❌ 无效的配置节或不是 BSS 类型的节\n");
return;
}
BssModule *bss = sec->bss_list;
if (!bss) {
printf("📄 节 [%s] 中没有 bss 模块\n", sec->name);
return;
}
printf("📄 节 [%s] 中的 bss_list 内容:\n", sec->name);
int index = 0;
while (bss) {
printf(" %d. %s\n", index++, bss->name);
bss = bss->next;
}
}
// 查找指定名称的 section
static ConfigSection *find_section(Config *config, const char *section_name) {
for (ConfigSection *sec = config->sections; sec; sec = sec->next) {
if (strcmp(sec->name, section_name) == 0)
return sec;
}
return NULL;
}
// 查找指定名称的 bss
static BssModule *find_bss(ConfigSection *section, const char *bss_name) {
if (!section->is_bss_section) {
printf("❌ find_bss: section 不是 BSS 节\n");
return NULL;
}
printf("🔍 开始查找 bss: '%s'\n", bss_name);
for (BssModule *bss = section->bss_list; bss; bss = bss->next) {
printf(" 比较: '%s' vs '%s' => %d\n", bss->name, bss_name, strcmp(bss->name, bss_name));
// 打印十六进制,用于定位隐藏字符
printf(" bss->name hex: ");
for (int i = 0; i < strlen(bss->name) && i < 32; i++) {
printf("%02X ", (unsigned char)bss->name[i]);
}
printf("\n");
printf(" bss_name hex : ");
for (int i = 0; i < strlen(bss_name) && i < 32; i++) {
printf("%02X ", (unsigned char)bss_name[i]);
}
printf("\n");
if (strcmp(bss->name, bss_name) == 0) {
printf("✅ 找到匹配的 bss: %s\n", bss_name);
return bss;
}
}
printf("find_bss: ❌ 未找到 bss: %s\n", bss_name);
return NULL;
}
// 加载配置文件
Config *config_load(const char *filename) {
FILE *fp = fopen(filename, "r");
if (!fp) return NULL;
Config *config = config_new();
if (!config) {
fclose(fp);
return NULL;
}
ConfigSection *current_section = NULL;
BssModule *current_bss = NULL;
char line[MAX_LINE];
while (fgets(line, sizeof(line), fp)) {
char *trimmed = line;
while (isspace(*trimmed)) trimmed++;
// 跳过空行和非 section 注释行
if (trimmed[0] == '\0' || trimmed[0] == '\n') continue;
if (trimmed[0] == '#' && strncmp(trimmed, "##", 2) != 0) continue;
// 处理节头
if (strncmp(trimmed, "##", 2) == 0) {
char *section_name_start = trimmed + 2;
while (isspace(*section_name_start)) section_name_start++;
char section_name[64] = {0};
int i = 0;
while (*section_name_start && *section_name_start != '\n' && i < 63) {
section_name[i++] = *section_name_start++;
}
// 先查找是否已有该节
ConfigSection *existing = find_section(config, section_name);
if (existing) {
// 如果已存在,就切换 current_section 到它
current_section = existing;
current_bss = NULL;
printf("✅ 节 [%s] 已存在,切换使用\n", section_name);
continue;
}
// 如果不存在,创建新节
ConfigSection *new_sec = (ConfigSection *)malloc(sizeof(ConfigSection));
if (!new_sec) continue;
strncpy(new_sec->name, section_name, sizeof(new_sec->name) - 1);
new_sec->name[sizeof(new_sec->name) - 1] = '\0';
new_sec->is_bss_section = (strcmp(section_name, "BSS configurations") == 0);
new_sec->lines = NULL;
new_sec->next = NULL;
// 插入到 sections 尾部
if (config->sections == NULL) {
config->sections = new_sec;
} else {
ConfigSection *tmp = config->sections;
while (tmp->next) tmp = tmp->next;
tmp->next = new_sec;
}
current_section = new_sec;
current_bss = NULL;
printf("🆕 新建节 [%s]\n", section_name);
} else if (strchr(trimmed, '=')) {
if (!current_section) continue;
char key[128], val[128];
if (sscanf(trimmed, "%127[^=]=%127[^\n]", key, val) != 2)
continue;
ConfigLine *new_line = (ConfigLine *)malloc(sizeof(ConfigLine));
if (!new_line) continue;
strncpy(new_line->line, line, sizeof(new_line->line) - 1);
new_line->line[sizeof(new_line->line) - 1] = '\0';
new_line->next = NULL;
if (current_section->is_bss_section) {
if (strcmp(key, "bss") == 0) {
// 提取并清理 bss 名称
char *val_start = val;
while (isspace(*val_start)) val_start++;
size_t val_len = strlen(val_start);
while (val_len > 0 && isspace((unsigned char)val_start[val_len - 1])) {
val_start[--val_len] = '\0';
}
if (val_len == 0) {
printf("⚠️ bss 值为空,跳过\n");
free(new_line);
continue;
}
BssModule *new_bss = (BssModule *)malloc(sizeof(BssModule));
if (!new_bss) {
free(new_line);
continue;
}
strncpy(new_bss->name, val_start, sizeof(new_bss->name) - 1);
new_bss->name[sizeof(new_bss->name) - 1] = '\0';
printf("解析到 bss: '%s'\n", new_bss->name);
new_bss->lines = new_line;
new_bss->next = NULL;
// 插入到 bss_list 尾部
if (current_section->bss_list == NULL) {
current_section->bss_list = new_bss;
} else {
BssModule *tmp = current_section->bss_list;
while (tmp->next) tmp = tmp->next;
tmp->next = new_bss;
}
current_bss = new_bss;
} else {
if (current_bss) {
// 插入到 bss->lines 尾部
new_line->next = NULL;
if (current_bss->lines == NULL) {
current_bss->lines = new_line;
} else {
ConfigLine *tmp = current_bss->lines;
while (tmp->next) tmp = tmp->next;
tmp->next = new_line;
}
} else {
free(new_line);
}
}
} else {
// 非 BSS section 的普通行插入到 lines 尾部
new_line->next = NULL;
if (current_section->lines == NULL) {
current_section->lines = new_line;
} else {
ConfigLine *tmp = current_section->lines;
while (tmp->next) tmp = tmp->next;
tmp->next = new_line;
}
}
}
}
// ✅ 打印所有 ConfigSection 名字,确认顺序
ConfigSection *sec = config->sections;
printf("📄 所有配置节:\n");
while (sec) {
printf(" - %s\n", sec->name);
sec = sec->next;
}
// ✅ 打印第一个 BSS configurations 的 bss_list
sec = find_section(config, "BSS configurations");
if (sec) {
printf("【调试】加载完成后的 bss_list 内容:\n");
print_bss_list(sec);
}
fclose(fp);
return config;
}
// 保存配置文件
int config_save(Config *config, const char *filename) {
FILE *fp = fopen(filename, "w");
if (!fp) return -1;
for (ConfigSection *sec = config->sections; sec; sec = sec->next) {
if (sec->is_bss_section) {
// 对于 BSS 类型的节,每个 bss 单独写入标题和内容
for (BssModule *bss = sec->bss_list; bss; bss = bss->next) {
// 写入标题
fprintf(fp, "## %s\n", sec->name);
// 写入该 bss 的所有配置行
for (ConfigLine *line = bss->lines; line; line = line->next) {
fprintf(fp, "%s", line->line); // 假设 line->line 已包含换行符
}
}
} else {
// 普通节写入一次标题和所有行
fprintf(fp, "## %s\n", sec->name);
for (ConfigLine *line = sec->lines; line; line = line->next) {
fprintf(fp, "%s", line->line);
}
}
}
fclose(fp);
return 0;
}
// 获取 value
int config_get_value(Config *config, const char *section_name, const char *bss_name, const char *key, char *value, size_t val_size) {
ConfigSection *sec = find_section(config, section_name);
if (!sec) return -1;
if (sec->is_bss_section) {
if (!bss_name) {
printf("❌ BSS 节需要指定 bss_name\n");
return -1;
}
BssModule *bss = find_bss(sec, bss_name);
if (!bss) return -1;
for (ConfigLine *line = bss->lines; line; line = line->next) {
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2)
continue;
if (strcmp(k, key) == 0) {
strncpy(value, v, val_size - 1);
value[val_size - 1] = '\0';
return 0;
}
}
} else {
// 普通节
for (ConfigLine *line = sec->lines; line; line = line->next) {
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2)
continue;
if (strcmp(k, key) == 0) {
strncpy(value, v, val_size - 1);
value[val_size - 1] = '\0';
return 0;
}
}
}
return -1;
}
// 设置 value
int config_set_value(Config *config, const char *section_name, const char *bss_name, const char *key, const char *new_value) {
ConfigSection *sec = find_section(config, section_name);
if (!sec) return -1;
if (sec->is_bss_section) {
if (!bss_name) return -1;
BssModule *bss = find_bss(sec, bss_name);
if (!bss) return -1;
for (ConfigLine *line = bss->lines; line; line = line->next) {
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2)
continue;
if (strcmp(k, key) == 0) {
snprintf(line->line, sizeof(line->line), "%s=%s\n", k, new_value);
return 0;
}
}
// 如果找不到 key,添加新行
ConfigLine *new_line = (ConfigLine *)malloc(sizeof(ConfigLine));
if (!new_line) return -1;
snprintf(new_line->line, sizeof(new_line->line), "%s=%s\n", key, new_value);
new_line->next = bss->lines;
bss->lines = new_line;
} else {
// 普通节
for (ConfigLine *line = sec->lines; line; line = line->next) {
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) != 2)
continue;
if (strcmp(k, key) == 0) {
snprintf(line->line, sizeof(line->line), "%s=%s\n", k, new_value);
return 0;
}
}
// 如果找不到 key,添加新行
ConfigLine *new_line = (ConfigLine *)malloc(sizeof(ConfigLine));
if (!new_line) return -1;
snprintf(new_line->line, sizeof(new_line->line), "%s=%s\n", key, new_value);
new_line->next = sec->lines;
sec->lines = new_line;
}
return 0;
}
// 清空 value
int config_clear_value(Config *config, const char *section, const char *bss, const char *key) {
return config_set_value(config, section, bss, key, "");
}
// 追加 value
int config_add_value(Config *config, const char *section_name, const char *bss_name, const char *key, const char *new_value) {
ConfigSection *sec = find_section(config, section_name);
if (!sec) return -1;
if (sec->is_bss_section) {
if (!bss_name) return -1;
BssModule *bss = find_bss(sec, bss_name);
if (!bss) return -1;
for (ConfigLine *line = bss->lines; line; line = line->next) {
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) == 2 && strcmp(k, key) == 0) {
char new_line[256];
if (strlen(v) == 0) {
snprintf(new_line, sizeof(new_line), "%s=%s\n", key, new_value);
} else {
snprintf(new_line, sizeof(new_line), "%s=%s %s\n", key, v, new_value);
}
strncpy(line->line, new_line, sizeof(line->line) - 1);
line->line[sizeof(line->line) - 1] = '\0';
return 0;
}
}
} else {
for (ConfigLine *line = sec->lines; line; line = line->next) {
char k[128], v[128];
if (sscanf(line->line, "%127[^=]=%127[^\n]", k, v) == 2 && strcmp(k, key) == 0) {
char new_line[256];
if (strlen(v) == 0) {
snprintf(new_line, sizeof(new_line), "%s=%s\n", key, new_value);
} else {
snprintf(new_line, sizeof(new_line), "%s=%s %s\n", key, v, new_value);
}
strncpy(line->line, new_line, sizeof(line->line) - 1);
line->line[sizeof(line->line) - 1] = '\0';
return 0;
}
}
}
return -1;
}
void print_bss_lines(Config *config, const char *bss_name) {
ConfigSection *sec = find_section(config, "BSS configurations");
if (!sec || !sec->is_bss_section) {
printf("printf_bss_lines:❌ 找不到 BSS configurations 节\n");
return;
}
BssModule *bss = find_bss(sec, bss_name);
if (!bss) {
printf("printf_bss_lines: ❌ 找不到 bss: %s\n", bss_name);
return;
}
printf("📄 %s 的配置行如下:\n", bss_name);
for (ConfigLine *line = bss->lines; line; line = line->next) {
printf(" %s\n", line->line);
}
}
按照.h文件的名称对应地更改.c文件里面的名称