SrcToA2L/Src/Core_Functions.cpp

1068 lines
44 KiB
C++

#include "Config.hpp"
#include "Core_Functions.hpp"
#include "Tool_Functions.hpp"
#include "Global_Variables.hpp"
extern "C"
{
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
}
// 参数解析
void solve_args(int argc, char *argv[])
{
// 文件名指针记录
const char *p_reference_file_name = nullptr;
const char *p_map_file_name = nullptr;
// 遍历命令参数
for (int count = 1; count < argc; count++)
{
// 是指令行
if (argv[count][0] == '-')
{
// -a 字节对齐长度设置
if (!strcmp(argv[count], "-a"))
{
// 错误输入处理
if (count + 1 == argc)
break;
if (argv[count + 1][0] == '-')
continue;
size_t value = 0;
sscanf(argv[count + 1], "%u", &value);
if ((value % 2 == 0 && value != 0) || value == 1)
{
log_printf(LOG_SUCCESS, "Alignment size set to %u.", value);
addr_alignment_size = value;
}
else
log_printf(LOG_FAILURE, "Illegal alignment arg \"%s\", set to default %u.", argv[count + 1], addr_alignment_size);
count++;
continue;
}
// -r 参考A2L输入
if (!strcmp(argv[count], "-r"))
{
// 错误输入处理
if (count + 1 == argc)
break;
if (argv[count + 1][0] == '-')
continue;
// 已经打开了一个参考文件
if (input_reference_A2L_file != nullptr)
log_printf(LOG_WARN, "Only single .a2l reference file supported,last will be use as input.");
// 尝试打开文件
input_reference_A2L_file = fopen(argv[count + 1], "rb");
if (input_reference_A2L_file == nullptr)
log_printf(LOG_FAILURE, "Reference file \"%s\" open failed.", argv[count + 1]);
else
{
log_printf(LOG_SUCCESS, "Reference file \"%s\" open succeed.", argv[count + 1]);
p_reference_file_name = argv[count + 1];
}
count++;
continue;
}
// -m 链接map输入
if (!strcmp(argv[count], "-m"))
{
// 错误输入处理
if (count + 1 == argc)
break;
if (argv[count + 1][0] == '-')
continue;
// 已经打开了一个链接文件
if (input_map_file != nullptr)
log_printf(LOG_WARN, "Only single .map file supported,last will be use as input.");
// 尝试打开文件
input_map_file = fopen(argv[count + 1], "rb");
if (input_map_file == nullptr)
log_printf(LOG_FAILURE, "Map file \"%s\" open failed.", argv[count + 1]);
else
{
log_printf(LOG_SUCCESS, "Map file \"%s\" open succeed.", argv[count + 1]);
p_map_file_name = argv[count + 1];
}
count++;
continue;
}
log_printf(LOG_WARN, "Unknown argument \"%s\".", argv[count]);
continue;
}
// 其余的作为源文件输入
{
// 排查重复文件
bool is_file_duplicated = false;
for (file_node *p_file_node = source_and_header_file_list_head; p_file_node != nullptr; p_file_node = p_file_node->p_next)
{
if (!strcmp(argv[count], p_file_node->file_name_str))
{
is_file_duplicated = true;
log_printf(LOG_WARN, "Source or header file \"%s\" duplicated.", argv[count]);
break;
}
}
if (is_file_duplicated)
continue;
// 检测文件是否存在
FILE *target_file = fopen(argv[count], "rb");
if (target_file == nullptr)
{
log_printf(LOG_FAILURE, "Source or header file \"%s\" open failed.", argv[count]);
continue;
}
// 成功打开文件
static file_node *target_file_node = nullptr;
// 开辟新的空间
if (source_and_header_file_list_head == nullptr)
{
source_and_header_file_list_head = (file_node *)malloc(sizeof(file_node));
target_file_node = source_and_header_file_list_head;
}
else
{
target_file_node->p_next = (file_node *)malloc(sizeof(file_node));
target_file_node = target_file_node->p_next;
}
// 记录文件链表
target_file_node->file_name_str = argv[count];
target_file_node->p_next = nullptr;
// 关闭临时的文件指针
fclose(target_file);
// 日志
log_printf(LOG_SUCCESS, "Source or header file \"%s\" open succeed.", argv[count]);
}
}
// 没有任何文件输入
if (source_and_header_file_list_head == nullptr)
{
log_printf(LOG_FAILURE, "No source or header file input.");
// 退出并返回错误状态
clean_and_exit(-1);
}
// 无链接map文件时
if (input_map_file == nullptr)
log_printf(LOG_WARN, "No .map file input,address will be set to 0x00000000");
// 无参考A2L文件时
if (input_reference_A2L_file == nullptr)
log_printf(LOG_WARN, "No .a2l reference file input,only middleware will be generated.");
// 拼接输出部分字符串
char *output_file_name = nullptr;
if (p_reference_file_name != nullptr)
{
// 分配空间
output_file_name = (char *)malloc(strlen(p_reference_file_name) + strlen(OUTPUT_A2L_PREFIX) + 1);
// 获取路径部分长度和不带路径的文件名起始位置
int path_length = strlen(p_reference_file_name);
const char *file_name_no_dir = p_reference_file_name + path_length - 1;
// 遍历指针没有回到起始位置且没有遇到正反斜杠
while (file_name_no_dir + 1 != p_reference_file_name && *file_name_no_dir != '\\' && *file_name_no_dir != '/')
{
path_length--;
file_name_no_dir--;
}
file_name_no_dir++;
// 开始拼接
for (int count = 0; count < path_length; count++)
output_file_name[count] = p_reference_file_name[count];
sprintf(output_file_name + path_length, "%s%s", OUTPUT_A2L_PREFIX, file_name_no_dir);
}
// 输出工作流
{
printf("\n");
log_printf(LOG_INFO, "Workflow details:");
printf(" ├─Alignment size: %u\n", addr_alignment_size);
printf(" ├─Source or header files:\n");
// 遍历文件链表
file_node *p_file = source_and_header_file_list_head;
while (p_file != nullptr)
{
if (p_file->p_next != nullptr)
printf(" │ ├─%s\n", p_file->file_name_str);
else
printf(" │ └─%s\n", p_file->file_name_str);
p_file = p_file->p_next;
}
printf(" ├─Reference file:\n");
if (p_reference_file_name == nullptr)
printf(" │ └─(NULL)\n");
else
printf(" │ └─%s\n", p_reference_file_name);
printf(" ├─Map file:\n");
if (p_map_file_name == nullptr)
printf(" │ └─(NULL)\n");
else
printf(" │ └─%s\n", p_map_file_name);
printf(" ├─Merged output file:\n");
if (p_reference_file_name == nullptr)
printf(" │ └─(NULL)\n");
else
printf(" │ └─%s\n", output_file_name);
printf(" └─Middleware file:\n");
if (p_reference_file_name == nullptr)
printf(" └─.\\%s\n", OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME);
else
printf(" └─%s%s\n\n", output_file_name, OUTPUT_MIDDLEWARE_SUFFIX);
}
// 打开输出文件
{
// 参考文件存在时
if (p_reference_file_name != nullptr)
{
// 打开合并输出文件
output_target_A2L_file = fopen(output_file_name, "wb");
if (output_target_A2L_file == nullptr)
{
log_printf(LOG_FAILURE, "Merged output file \"%s\" create failed.", output_file_name);
free(output_file_name);
clean_and_exit(-1);
}
else
log_printf(LOG_SUCCESS, "Merged output file \"%s\" create succeed.", output_file_name);
// 打开中间件
char *buff = (char *)malloc(strlen(output_file_name) + strlen(OUTPUT_MIDDLEWARE_SUFFIX) + 1);
sprintf(buff, "%s%s", output_file_name, OUTPUT_MIDDLEWARE_SUFFIX);
output_middleware_file = fopen(buff, "wb+");
if (output_middleware_file == nullptr)
{
log_printf(LOG_FAILURE, "Middleware output file \"%s\" create failed.", buff);
free(output_file_name);
free(buff);
clean_and_exit(-1);
}
else
log_printf(LOG_SUCCESS, "Middleware output file \"%s\" create succeed.", buff);
free(output_file_name);
free(buff);
}
// 不存在时打开默认的中间件输出
else
{
output_middleware_file = fopen(OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME, "wb");
if (output_middleware_file == nullptr)
{
log_printf(LOG_FAILURE, "Middleware output file \"%s\" create failed.", OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME);
clean_and_exit(-1);
}
else
log_printf(LOG_SUCCESS, "Middleware output file \"%s\" create succeed.", OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME);
}
}
}
// 解析宏定义
void solve_defines(void)
{
file_node *target_file_node = source_and_header_file_list_head;
define_node *define_show_begin_node = nullptr;
// 循环处理文件链表
log_printf(LOG_INFO, "Solved definition details:");
while (target_file_node != nullptr)
{
FILE *target_file = nullptr;
target_file = fopen(target_file_node->file_name_str, "rb");
char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'};
// 循环按行解析
while (true)
{
// 跳过空白读行
f_seek_skip_blanks(target_file);
if (f_getline(target_file, segment_buff, sizeof(segment_buff)) == 0)
break;
// 查找到define
if (strstr(segment_buff, "#define") == segment_buff)
{
// 检查是否为数值类型的#define
{
bool illegal_define = false;
char *p_str = segment_buff + strlen("#define");
// 跳过#define后的空格
while (*p_str == ' ')
p_str++;
// 检查第一个非空格段是否为合法段(宏定义名)
while (*p_str != ' ')
{
if (isalnum(*p_str) || *p_str == '_')
p_str++;
else
{
// 不是数字、字母、下划线,是换行符或者别的东西
illegal_define = true;
break;
}
}
// 跳过第二个空格段
while (*p_str == ' ')
p_str++;
// 检查后续的整段内容是否为正十进制数值
if (!isdigit(*p_str) && !(*p_str == '+' && isdigit(*(p_str + 1))))
illegal_define = true;
// 验证合法性
if (illegal_define)
continue;
}
// 分配节点空间
static define_node *target_define_node;
if (define_list_head == nullptr)
{
define_list_head = (define_node *)malloc(sizeof(define_node));
target_define_node = define_list_head;
define_show_begin_node = define_list_head;
}
else
{
target_define_node->p_next = (define_node *)malloc(sizeof(define_node));
target_define_node = target_define_node->p_next;
if (define_show_begin_node == nullptr)
define_show_begin_node = target_define_node;
}
memset(target_define_node->define_str, '\0', sizeof(target_define_node->define_str));
target_define_node->value = 0;
target_define_node->p_next = nullptr;
// 记录信息
sscanf(segment_buff, "%*s%s%u", target_define_node->define_str, &target_define_node->value);
}
}
// 关闭文件
fclose(target_file);
// 日志输出
if (target_file_node->p_next == nullptr)
{
printf(" └─%s\n", target_file_node->file_name_str);
while (true)
{
if (define_show_begin_node == nullptr)
{
printf(" └─(NULL)\n");
break;
}
if (define_show_begin_node->p_next == nullptr)
{
printf(" └─%s -> %u\n", define_show_begin_node->define_str, define_show_begin_node->value);
define_show_begin_node = nullptr;
break;
}
printf(" ├─%s -> %u\n", define_show_begin_node->define_str, define_show_begin_node->value);
define_show_begin_node = define_show_begin_node->p_next;
}
}
else
{
printf(" ├─%s\n", target_file_node->file_name_str);
while (true)
{
if (define_show_begin_node == nullptr)
{
printf(" │ └─(NULL)\n");
break;
}
if (define_show_begin_node->p_next == nullptr)
{
printf(" │ └─%s -> %u\n", define_show_begin_node->define_str, define_show_begin_node->value);
define_show_begin_node = nullptr;
break;
}
printf(" │ ├─%s -> %u\n", define_show_begin_node->define_str, define_show_begin_node->value);
define_show_begin_node = define_show_begin_node->p_next;
}
}
// 更新指针
target_file_node = target_file_node->p_next;
}
}
// 类型解析
void solve_types(void)
{
// 类型名称
const char *type_str[] = {
"TYPE_UNKNOWN",
"STRUCTURE",
"UBYTE",
"UWORD",
"ULONG",
"SBYTE",
"SWORD",
"SLONG",
"FLOAT32_IEEE",
"FLOAT64_IEEE",
};
file_node *target_file_node = source_and_header_file_list_head;
type_node *type_show_begin_node = nullptr;
log_printf(LOG_INFO, "Solved compound type details:");
// 循环处理文件链表
while (target_file_node != nullptr)
{
FILE *target_file = nullptr;
target_file = fopen(target_file_node->file_name_str, "rb");
char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'};
// 循环按行解析
while (true)
{
// 类型链表指针
static type_node *target_type_node = nullptr;
// 跳过注释和空白后
f_seek_skip_comments_and_blanks(target_file);
if (f_getline(target_file, segment_buff, sizeof(segment_buff)) == 0)
break;
// 检测到类型定义起始
if (strstr(segment_buff, "typedef"))
{
char *p_typedef = (strstr(segment_buff, "typedef"));
// 过滤非独立的typedef
if (isalnum(*(p_typedef - 1)) || *(p_typedef - 1) == '_' || *(p_typedef + strlen("typedef")) != ' ')
break;
// 过滤处在字符串中的typedef
if (strstr(segment_buff, "\""))
{
bool pre_quote = false;
for (const char *p_str = p_typedef; p_str != segment_buff; p_str--)
if (*p_str == '\"')
pre_quote = true;
bool end_quote = false;
for (const char *p_str = p_typedef; p_str != segment_buff + strlen(segment_buff); p_str++)
if (*p_str == '\"')
end_quote = true;
if (pre_quote && end_quote)
break;
}
// 回退到typedef之后重新读取
fseek(target_file, -(strlen(p_typedef + strlen("typedef"))), SEEK_CUR);
f_seek_skip_comments_and_blanks(target_file);
if (f_getline(target_file, segment_buff, sizeof(segment_buff)) == 0)
break;
// 检查是否是支持的类型
if (strstr(segment_buff, "struct") != segment_buff)
{
while (fgetc(target_file) != '}')
;
continue;
}
// 分配空间,类型链表头为空时初始化类型链表头
if (type_list_head == nullptr)
{
type_list_head = (type_node *)malloc(sizeof(type_node));
target_type_node = type_list_head;
type_show_begin_node = type_list_head;
}
else
{
// 扩展到下一张链表
target_type_node->p_next = (type_node *)malloc(sizeof(type_node));
target_type_node = target_type_node->p_next;
if (type_show_begin_node == nullptr)
type_show_begin_node = target_type_node;
}
// 节点初始化
target_type_node->p_next = nullptr;
target_type_node->type = TYPE_UNKNOWN;
target_type_node->element_list_head = nullptr;
memset(target_type_node->type_name_str, '\0', sizeof(target_type_node->type_name_str));
// 检测到结构体类型
if (strstr(segment_buff, "struct"))
{
// 非法子成员记录
bool illegal_sub_element = false;
target_type_node->type = STRUCTURE;
// 回退到struct后重新读取
fseek(target_file, -(strlen(segment_buff) - strlen("struct")), SEEK_CUR);
f_seek_skip_comments_and_blanks(target_file);
// 获取直接类型名称
f_getword(target_file, segment_buff, sizeof(segment_buff));
if (segment_buff[0] != '\0')
sprintf(target_type_node->type_name_str, segment_buff);
// 跳转到类型定义内
while (fgetc(target_file) != '{')
;
// 新建第一个子元素节点
sub_element_node *target_element_node = nullptr;
// 循环读取类型定义
while (true)
{
if (f_get_codeline(target_file, segment_buff, sizeof(segment_buff)) == 0)
break;
if (segment_buff[0] == '}')
{
// 回退到结束末尾
fseek(target_file, -(strlen(segment_buff) - 1), SEEK_CUR);
break;
}
// 分配空间及初始化
if (target_element_node == nullptr)
{
target_type_node->element_list_head = (sub_element_node *)malloc(sizeof(sub_element_node));
target_element_node = target_type_node->element_list_head;
}
else
{
target_element_node->p_next = (sub_element_node *)malloc(sizeof(sub_element_node));
target_element_node = target_element_node->p_next;
}
target_element_node->p_next = nullptr;
target_element_node->element_info = solve_variable_info(segment_buff);
// 非法子成员检查
if (target_element_node->element_info.element_count == 0)
{
illegal_sub_element = true;
break;
}
if (target_element_node->element_info.type == TYPE_UNKNOWN)
{
illegal_sub_element = true;
break;
}
if (target_element_node->element_info.type == STRUCTURE)
{
illegal_sub_element = true;
break;
}
}
// 存在成员非法
if (illegal_sub_element)
{
// 释放子元素列表
while (target_type_node->element_list_head != nullptr)
{
sub_element_node *p_element = target_type_node->element_list_head;
target_type_node->element_list_head = target_type_node->element_list_head->p_next;
free(p_element);
}
// 释放当前的类型节点
if (target_type_node == type_list_head)
{
free(type_list_head);
type_list_head = nullptr;
target_type_node = nullptr;
type_show_begin_node = nullptr;
}
else
{
if (type_show_begin_node == target_type_node)
type_show_begin_node = nullptr;
type_node *p_prev_type_node = type_list_head;
while (p_prev_type_node->p_next != target_type_node)
p_prev_type_node = p_prev_type_node->p_next;
free(target_type_node);
target_type_node = p_prev_type_node;
target_type_node->p_next = nullptr;
}
// 跳过剩余的声明部分
while (fgetc(target_file) != '}')
;
continue;
}
// 处理剩余部分的别名串
while (true)
{
f_seek_skip_blanks(target_file);
if (f_getword(target_file, segment_buff, sizeof(segment_buff)) == 0)
{
if (fgetc(target_file) == ';')
break;
continue;
}
// 已经有直接名串
if (target_type_node->type_name_str[0] != '\0')
{
// 扩展到下一张链表并记录信息
target_type_node->p_next = (type_node *)malloc(sizeof(type_node));
target_type_node->p_next->p_next = nullptr;
target_type_node->p_next->type = target_type_node->type;
target_type_node->p_next->element_list_head = target_type_node->element_list_head;
target_type_node = target_type_node->p_next;
memset(target_type_node->type_name_str, '\0', sizeof(target_type_node->type_name_str));
}
sprintf(target_type_node->type_name_str, segment_buff);
}
}
}
memset(segment_buff, '\0', sizeof(segment_buff));
}
fclose(target_file);
/**
* @todo
* 日志输出逻辑需要大改,现在这个写法太傻逼了,层级越多越傻逼(但是写起来是真的快~
*/
// 日志输出
{
if (target_file_node->p_next == nullptr)
{
printf(" └─%s\n", target_file_node->file_name_str);
printf(" ├─Structure:\n");
while (true)
{
if (type_show_begin_node == nullptr)
{
printf(" │ └─(NULL)\n");
printf(" └─Other:\n");
printf(" └─(NULL)\n");
break;
}
if (type_show_begin_node->p_next == nullptr)
{
printf(" │ └─%s\n", type_show_begin_node->type_name_str);
// 子成员打印
{
sub_element_node *p_element = type_show_begin_node->element_list_head;
while (p_element != nullptr)
{
variable_info *info = &p_element->element_info;
if (p_element->p_next != nullptr)
{
if (info->element_count == 1)
printf(" │ ├─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ ├─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
else
{
if (info->element_count == 1)
printf(" │ └─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ └─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
p_element = p_element->p_next;
}
}
printf(" └─Other:\n");
printf(" └─(NULL)\n");
type_show_begin_node = nullptr;
break;
}
printf(" │ ├─%s\n", type_show_begin_node->type_name_str);
// 子成员打印
{
sub_element_node *p_element = type_show_begin_node->element_list_head;
while (p_element != nullptr)
{
variable_info *info = &p_element->element_info;
if (p_element->p_next != nullptr)
{
if (info->element_count == 1)
printf(" │ │ ├─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ │ ├─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
else
{
if (info->element_count == 1)
printf(" │ │ └─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ │ └─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
p_element = p_element->p_next;
}
}
type_show_begin_node = type_show_begin_node->p_next;
}
}
else
{
printf(" ├─%s\n", target_file_node->file_name_str);
printf(" │ ├─Structure:\n");
while (true)
{
if (type_show_begin_node == nullptr)
{
printf(" │ │ └─(NULL)\n");
printf(" │ └─Other:\n");
printf(" │ └─(NULL)\n");
break;
}
if (type_show_begin_node->p_next == nullptr)
{
printf(" │ │ └─%s\n", type_show_begin_node->type_name_str);
// 子成员打印
{
sub_element_node *p_element = type_show_begin_node->element_list_head;
while (p_element != nullptr)
{
variable_info *info = &p_element->element_info;
if (p_element->p_next != nullptr)
{
if (info->element_count == 1)
printf(" │ │ ├─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ │ ├─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
else
{
if (info->element_count == 1)
printf(" │ │ └─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ │ └─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
p_element = p_element->p_next;
}
}
printf(" │ └─Other:\n");
printf(" │ └─(NULL)\n");
type_show_begin_node = nullptr;
break;
}
printf(" │ │ ├─%s\n", type_show_begin_node->type_name_str);
// 子成员打印
{
sub_element_node *p_element = type_show_begin_node->element_list_head;
while (p_element != nullptr)
{
variable_info *info = &p_element->element_info;
if (p_element->p_next != nullptr)
{
if (info->element_count == 1)
printf(" │ │ │ ├─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ │ │ ├─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
else
{
if (info->element_count == 1)
printf(" │ │ │ └─%-15s .%s\n", type_str[info->type], info->name_str);
else
printf(" │ │ │ └─%-15s .%s[%d]\n", type_str[info->type], info->name_str, info->element_count);
}
p_element = p_element->p_next;
}
}
type_show_begin_node = type_show_begin_node->p_next;
}
}
}
// 切换文件
target_file_node = target_file_node->p_next;
}
}
// 记录布局解析(标定量使用)
void solve_record_layout(void)
{
// 记录布局名串
const char *record_type[8] =
{
"Scalar_UBYTE",
"Scalar_UWORD",
"Scalar_ULONG",
"Scalar_SBYTE",
"Scalar_SWORD",
"Scalar_SLONG",
"Scalar_FLOAT32_IEEE",
"Scalar_FLOAT64_IEEE",
};
// 布局存在与否
bool find_flag[8] =
{
false,
false,
false,
false,
false,
false,
false,
false,
};
if (input_reference_A2L_file != nullptr)
{
// 回到文件起始
fseek(input_reference_A2L_file, 0, SEEK_SET);
// 段缓冲区
char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'};
// 从头到尾检查A2L中的RECORD_LAYOUT类型
while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) != 0)
{
// 当前行为 RECORD_LAYOUT
if (strstr(segment_buff, "RECORD_LAYOUT"))
{
// 指针跳转到RECORD_LAYOUT后第一个有效字符
char *p_record_str = strstr(segment_buff, "RECORD_LAYOUT") + strlen("RECORD_LAYOUT");
size_t segment_len = strlen(segment_buff);
while (*p_record_str != '\n' && p_record_str != segment_buff + segment_len)
{
if (isalpha(*p_record_str) || *p_record_str == '_')
break;
p_record_str++;
}
// 挨个检查
for (int count = 0; count < 8; count++)
{
if (find_flag[count])
continue;
if (strstr(p_record_str, record_type[count]))
find_flag[count] = true;
}
}
}
}
bool all_clear = true;
for (int count = 0; count < 8; count++)
if (!find_flag[count])
all_clear = false;
// 补全输出
if (!all_clear)
{
fprintf(output_middleware_file, "\r\n\r\n");
fprintf(output_middleware_file, "%s\r\n\r\n\r\n", START_OF_GENERATED_RECORD_LAYOUT_STR);
for (int count = 0; count < 8; count++)
{
if (find_flag[count])
continue;
log_printf(LOG_SUCCESS, "Add missing record layout \"%s\"", record_type[count]);
fprintf(output_middleware_file, "/begin RECORD_LAYOUT %s\r\n", record_type[count]);
fprintf(output_middleware_file, " FNC_VALUES 1 %s COLUMN_DIR DIRECT\r\n", record_type[count] + strlen("Scalar_"));
fprintf(output_middleware_file, "/end RECORD_LAYOUT\r\n\r\n");
}
fprintf(output_middleware_file, "\r\n");
fprintf(output_middleware_file, "%s\r\n", END_OF_GENERATED_RECORD_LAYOUT_STR);
}
}
// 处理标定量和观测量
void solve_calibrations_and_measurements(void)
{
// 抬头输出
bool head_output = false;
file_node *target_file_node = source_and_header_file_list_head;
// 循环处理输入文件
while (target_file_node != nullptr)
{
printf("\n\n");
log_printf(LOG_INFO, "Start solving file: \"%s\"\n", target_file_node->file_name_str);
FILE *target_file = fopen(target_file_node->file_name_str, "rb");
char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'};
// 循环获取输入文件行
while (f_getline(target_file, segment_buff, sizeof(segment_buff)) != 0)
{
// 检测到标定量起始行
if (strstr(segment_buff, START_OF_CALIBRATION_PATTERN_STR))
{
if (!head_output)
{
fprintf(output_middleware_file, "\r\n\r\n%s\r\n\r\n\r\n", START_OF_GENERATED_CALIBRATION_AND_MEASURMENT_STR);
head_output = true;
}
do
{
// 跳过空白部分
f_seek_skip_comments_and_blanks(target_file);
size_t read_count = f_getline(target_file, segment_buff, sizeof(segment_buff));
if (strstr(segment_buff, END_OF_CALIBRATION_PATTERN_STR))
break;
// 回退行并读取代码行
fseek(target_file, -read_count, SEEK_CUR);
f_get_codeline(target_file, segment_buff, sizeof(segment_buff));
variable_info v_info = solve_variable_info(segment_buff);
f_print_calibration(output_middleware_file, v_info);
} while (true);
}
// 观测量起始行
if (strstr(segment_buff, START_OF_MEASURMENT_PATTERN_STR))
{
if (!head_output)
{
fprintf(output_middleware_file, "\r\n\r\n%s\r\n\r\n", START_OF_GENERATED_CALIBRATION_AND_MEASURMENT_STR);
head_output = true;
}
do
{
// 跳过空白部分
f_seek_skip_comments_and_blanks(target_file);
size_t read_count = f_getline(target_file, segment_buff, sizeof(segment_buff));
if (strstr(segment_buff, END_OF_MEASURMENT_PATTERN_STR))
break;
// 回退行并读取代码行
fseek(target_file, -read_count, SEEK_CUR);
f_get_codeline(target_file, segment_buff, sizeof(segment_buff));
// log_printf(LOG_INFO, segment_buff);
f_print_measurement(output_middleware_file, solve_variable_info(segment_buff));
} while (true);
}
}
printf("\n");
log_printf(LOG_INFO, "File: \"%s\" solve finished.", target_file_node->file_name_str);
fclose(target_file);
target_file_node = target_file_node->p_next;
}
if (head_output)
fprintf(output_middleware_file, "\r\n\r\n%s\r\n\r\n", END_OF_GENERATED_CALIBRATION_AND_MEASURMENT_STR);
}
// 处理最终A2L合并输出
void solve_A2L_merge(void)
{
// 回到文件起始
fseek(input_reference_A2L_file, 0, SEEK_SET);
// 段缓冲区
char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'};
// 读取并复制参考文件直到 a2l MODULE 结尾
while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) != 0)
{
// 当前行为 a2l MODULE 结尾
if (strstr(segment_buff, A2L_INSERT_PATTERN_STR))
{
// 回退文件指针到上一行结尾
fseek(input_reference_A2L_file, -2, SEEK_CUR);
while (fgetc(input_reference_A2L_file) != '\n')
fseek(input_reference_A2L_file, -2, SEEK_CUR);
break;
}
// 输出行到文件
// fprintf(Output_Target, segment_buff); // 太大会段溢出,标准输入输出库存在的问题
for (int count = 0; count < SEGMENT_BUFF_LENGTH; count++) // 逐个输出
{
fputc(segment_buff[count], output_target_A2L_file);
if (segment_buff[count] == '\n')
break;
}
// 清空段缓冲区
memset(segment_buff, '\0', sizeof(segment_buff));
}
// 清空缓冲区并回退到文件起始位置
fseek(output_middleware_file, 0, SEEK_SET);
char ch = fgetc(output_middleware_file);
while (ch != EOF)
{
fputc(ch, output_target_A2L_file);
ch = fgetc(output_middleware_file);
}
// 输出参考文件的剩余部分
while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) != 0)
{
// 输出行到文件
fprintf(output_target_A2L_file, segment_buff);
// 清空段缓冲区
memset(segment_buff, '\0', sizeof(segment_buff));
}
}
// end