diff --git a/Inc/Config.hpp b/Inc/Config.hpp index 05d5bdc..8ad0bab 100644 --- a/Inc/Config.hpp +++ b/Inc/Config.hpp @@ -1,34 +1,33 @@ #ifndef __CONFIG_HPP__ #define __CONFIG_HPP__ -#define VARIABLE_NAME_LENGTH_MAX 100 -#define ELEMENT_NAME_LENGTH_MAX 100 -#define TYPE_NAME_LENGTH_MAX 100 +#define ADDR_ALIGNMENT_SIZE 4 // 地址对齐方式 -#define A2L_TYPE_STR_LENGTH_MAX 100 -#define A2L_LIMIT_STR_LENGTH_MAX 100 +#define VARIABLE_NAME_STR_LENGTH_MAX 100 // 名称字符串最大长度 -#define SEGMENT_BUFF_LENGTH 5000 +#define A2L_TYPE_STR_LENGTH_MAX 100 // A2L类型字符串最大长度 +#define A2L_LIMIT_STR_LENGTH_MAX 100 // A2L限制字符串最大长度 + +#define SEGMENT_BUFF_LENGTH 5000 // 段缓冲区长度 // 输出文件默认前缀 -#define OUTPUT_A2L_DEFAULT_PREFIX "[NEW]" +#define OUTPUT_A2L_PREFIX "[NEW]" // 中间件尾缀 #define OUTPUT_MIDDLEWARE_SUFFIX ".middleware.txt" +// 中间件默认名称 +#define OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME "Middleware.txt" // 相关识别串 -const char measurement_begin[] = "/*Start_Measurements*/"; -const char measurement_end[] = "/*End_Measurements*/"; -const char calibration_begin[] = "/*Start_Calibration*/"; -const char calibration_end[] = "/*End_Calibration*/"; -const char typedef_begin[] = "/*Start_TypeDef*/"; -const char typedef_end[] = "/*End_TypeDef*/"; +#define START_OF_MEASURMENT_PATTERN_STR "/*start_of_measurements*/" +#define END_OF_MEASURMENT_PATTERN_STR "/*end_of_measurements*/" +#define START_OF_CALIBRATION_PATTERN_STR "/*start_of_calibrations*/" +#define END_OF_CALIBRATION_PATTERN_STR "/*end_of_calibrations*/" -const char a2l_module_end[] = "/end MODULE"; +// A2L 插入识别串 +#define A2L_INSERT_PATTERN_STR "/end MODULE" // 段输出标识串 -const char auto_generated_measurement_start[] = "\r\n/*********** Start of auto generated measurement blocks ***********/\r\n\r\n"; -const char auto_generated_measurement_end[] = "\r\n/*********** End of auto generated measurement blocks ***********/\r\n\r\n"; -const char auto_generated_calibration_start[] = "\r\n/*********** Start of auto generated calibration blocks ***********/\r\n\r\n"; -const char auto_generated_calibration_end[] = "\r\n/*********** End of auto generated calibration blocks ***********/\r\n\r\n"; +#define START_OF_GENERATED_PATTERN_STR "/*********** start of SrcToA2L generated blocks ***********/" +#define END_OF_GENERATED_PATTERN_STR "/*********** end of SrcToA2L generated blocks ***********/" #endif \ No newline at end of file diff --git a/Inc/Global_Variables.hpp b/Inc/Global_Variables.hpp index 8823c38..200b5d1 100644 --- a/Inc/Global_Variables.hpp +++ b/Inc/Global_Variables.hpp @@ -13,8 +13,8 @@ extern type_node *type_list_head; // 宏定义列表 extern define_node *define_list_head; -// 源文件列表 -extern file_node *source_file_list_head; +// 源文件及头文件列表 +extern file_node *source_and_header_file_list_head; // 文件指针 extern FILE *input_reference_A2L_file; diff --git a/Inc/Tool_Functions.hpp b/Inc/Tool_Functions.hpp index bcfc720..f0452a2 100644 --- a/Inc/Tool_Functions.hpp +++ b/Inc/Tool_Functions.hpp @@ -9,34 +9,43 @@ extern "C" #include "Type_Descriptions.hpp" -// 读取文件一行行 -error_type_enum f_getline(FILE *file, char *buffer, const size_t buffer_len, size_t *seek_len = nullptr); +// 读取文件一行 +size_t f_getline(FILE *file, char *buffer, const size_t buffer_len); // 读取下一个有效词组 -error_type_enum f_getword(FILE *file, char *buffer, const size_t buffer_len, size_t *seek_len = nullptr); +size_t f_getword(FILE *file, char *buffer, const size_t buffer_len); // 获取文件代码行(以;为分界的代码逻辑行,忽略中途的注释) -error_type_enum f_get_codeline(FILE *file, char *buffer, const size_t buffer_len, size_t *seek_len = nullptr); +size_t f_get_codeline(FILE *file, char *buffer, const size_t buffer_len); // 前进到下一行 size_t f_seek_nextline(FILE *file); // 跳转到下一个非空字符 -size_t f_seek_skip_blank(FILE *file); +size_t f_seek_skip_blanks(FILE *file); -// 基础变量类型解析 -variable_type_enum get_variable_base_type(const char *str); - -// 基础变量解析 -variable_info solve_base_variable(const char *str); +// 跳过注释和空白内容(不跳过识别段) +size_t f_seek_skip_comments_and_blanks(FILE *file); // 解析变量类型 -variable_type_enum get_variable_type(const char *str); +variable_type_enum solve_variable_type(const char *type_str); // 变量解析 -variable_info solve_variable(const char *str); +variable_info solve_variable_info(const char *code_line_str); + +// 获取变量地址 +uint32_t get_variable_addr32(const char *v_name_str); + +// 输出标定量 +void f_print_calibration(FILE *file, variable_info v_info); + +// 输出观测量 +void f_print_measurement(FILE *file, variable_info v_info); // 日志输出 -void print_log(log_type_enum log_type, const char *p_format_str, ...); +void log_printf(log_type_enum log_type, const char *p_format_str, ...); + +// 清理和退出 +void clean_and_exit(int exit_code); #endif \ No newline at end of file diff --git a/Inc/Type_Descriptions.hpp b/Inc/Type_Descriptions.hpp index 815d909..08ff07b 100644 --- a/Inc/Type_Descriptions.hpp +++ b/Inc/Type_Descriptions.hpp @@ -9,83 +9,67 @@ extern "C" #include "Config.hpp" // 宏定义链表 -typedef struct define_node_struct +typedef struct define_list_node_struct { - char define_str[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; // define 名串 - char context_str[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; // define 内容串 - define_node_struct *p_next = nullptr; + char define_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'}; // define 名串 + unsigned int value = 0; + define_list_node_struct *p_next = nullptr; } define_node; // 文件链表 -typedef struct file_node_struct +typedef struct file_list_node_struct { char *file_name_str = nullptr; - file_node_struct *p_next = nullptr; + file_list_node_struct *p_next = nullptr; } file_node; -// 错误类型枚举 -typedef enum -{ - ERROR_NONE, // 无错误 - ERROR_OUT_OF_LENGTH, // 超出长度 - ERROR_ILLEGAL_POINTER, // 非法指针 - ERROR_ILLEGAL_WORD_SECTION, // 非法词段 - ERROR_END_OF_FILE, // 文件结尾 -} error_type_enum; - // 变量类型枚举 typedef enum { - TYPE_UNKNOWN, // 未知类型 - TYPE_NOT_SUPPORTED, // 不支持的类型 - STRUCTURE, // 结构体类型 - UBYTE, // uint8_t,bool - UWORD, // uint16_t - ULONG, // uint32_t - SBYTE, // int8_t - SWORD, // int16_t - SLONG, // int32_t - FLOAT32, // float - FLOAT64, // double + TYPE_UNKNOWN, // 未知类型或不支持类型 + STRUCTURE, // 结构体类型 + UBYTE, // uint8_t,bool + UWORD, // uint16_t + ULONG, // uint32_t + SBYTE, // int8_t + SWORD, // int16_t + SLONG, // int32_t + FLOAT32, // float + FLOAT64, // double } variable_type_enum; // 变量信息结构体 typedef struct { - char name_str[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; // 变量名 - const char *type_name_str = nullptr; // 变量类型字符串 - size_t element_count = 0; // 子元素计数(仅数组>1,单个变量该值为1) - size_t single_element_size = 0; // 单个子元素大小(单位字节) - uint32_t start_addr_32 = 0x00000000; // 变量起始地址(32位地址,4字节) - variable_type_enum type = TYPE_NOT_SUPPORTED; // 变量类型 - char A2L_type_str[A2L_TYPE_STR_LENGTH_MAX] = {'\0'}; // 类型字符串 - char A2L_max_limit_str[A2L_LIMIT_STR_LENGTH_MAX] = {'\0'}; // 上限字符串 - char A2L_min_limit_str[A2L_LIMIT_STR_LENGTH_MAX] = {'\0'}; // 下限字符串 + char name_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'}; // 变量名 + char type_name_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'}; // 类型名串 + size_t element_count = 0; // 子元素计数(仅数组>1,单个变量该值为1,未解析或解析失败为0) + variable_type_enum type = TYPE_UNKNOWN; // 变量类型 } variable_info; // 元素信息记录链表 -typedef struct sub_element_node_struct +typedef struct sub_element_list_node_struct { - variable_info element_info; // 元素信息 - struct sub_element_node_struct *p_next = nullptr; // 链表指针 + variable_info element_info; // 元素信息 + struct sub_element_list_node_struct *p_next = nullptr; // 链表指针 } sub_element_node; // 复合类型记录链表 -typedef struct type_node_struct +typedef struct type_list_node_struct { - char type_name_str[TYPE_NAME_LENGTH_MAX] = {'\0'}; // 类型名 - sub_element_node *element_list_head = nullptr; // 子成员链表 - variable_type_enum type = TYPE_UNKNOWN; // 类型标记 - struct type_node_struct *p_next = nullptr; // 链表指针 + char type_name_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'}; // 类型名 + sub_element_node *element_list_head = nullptr; // 子成员链表 + variable_type_enum type = TYPE_UNKNOWN; // 类型标记 + struct type_list_node_struct *p_next = nullptr; // 链表指针 } type_node; // 日志类型记录 typedef enum { - LOG_NORMAL, // 常规类型 - LOG_SUCCESS, // 成功类型 - LOG_FAILURE, // 失败类型 - LOG_ERROR, // 错误类型 - LOG_WARN, // 警告类型 + LOG_INFO, // 常规信息类型 + LOG_SYS_INFO, // 系统消息类型 + LOG_SUCCESS, // 成功类型 + LOG_FAILURE, // 失败类型 + LOG_WARN, // 警告类型 } log_type_enum; #endif \ No newline at end of file diff --git a/Src/Core_Functions.cpp b/Src/Core_Functions.cpp index f41a73b..f026493 100644 --- a/Src/Core_Functions.cpp +++ b/Src/Core_Functions.cpp @@ -1,965 +1,862 @@ +#include "Config.hpp" #include "Core_Functions.hpp" #include "Tool_Functions.hpp" -#include "Config.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 *reference_A2L_name_str = nullptr; // 参考文件名 - const char *output_name = nullptr; // 输出文件名 + // 文件名指针记录 + const char *p_reference_file_name = nullptr; + const char *p_map_file_name = nullptr; - // 循环处理指令 - for (int count = 1; count < argc; count++) + // 遍历命令参数 + for (int count = 1; count < argc; count++) + { + // 是指令行 + if (argv[count][0] == '-') { - // 匹配到参考a2l文件 + + // -r 参考A2L输入 if (!strcmp(argv[count], "-r")) { - if (count + 1 >= argc) - { - print_log(LOG_FAILURE, "No reference .a2l file input.\n"); + // 错误输入处理 + 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) - { - print_log(LOG_FAILURE, "Input reference .a2l file <%s> open failed.\n", argv[count + 1]); - break; - } - - // 获取参考文件文件名 - reference_A2L_name_str = argv[count + 1]; - - print_log(LOG_SUCCESS, "%-31s %s\n", "Input reference .a2l file:", argv[count + 1]); - count++; - continue; - } - - // 匹配到链接map文件 - else if (!strcmp(argv[count], "-l")) - { - if (count + 1 >= argc) - break; - input_map_file = fopen(argv[count + 1], "rb"); - if (input_map_file == nullptr) - { - print_log(LOG_FAILURE, "Input link file <%s> open failed.\n", argv[count + 1]); - break; - } - - print_log(LOG_SUCCESS, "%-31s %s\n", "Input link .map file:", argv[count + 1]); - count++; - continue; - } - - // 匹配到自定义输出文件名 - else if (!strcmp(argv[count], "-o")) - { - if (count + 1 >= argc) - break; - output_name = argv[count + 1]; - print_log(LOG_SUCCESS, "%-31s %s\n", "Set output filename:", argv[count + 1]); - count++; - continue; - } - - // 其它输入作为源文件输入 - print_log(LOG_SUCCESS, "%-31s %s\n", "Input source filename:", argv[count]); - - // 处理源文件链表 - { - static file_node *target_node = nullptr; - if (source_file_list_head == nullptr) - { - source_file_list_head = (file_node *)malloc(sizeof(file_node)); - source_file_list_head->file_name_str = nullptr; - source_file_list_head->p_next = nullptr; - target_node = source_file_list_head; - } + log_printf(LOG_FAILURE, "Reference file \"%s\" open failed.", argv[count + 1]); else { - target_node->p_next = (file_node *)malloc(sizeof(file_node)); - target_node = target_node->p_next; - target_node->file_name_str = nullptr; - target_node->p_next = nullptr; + log_printf(LOG_SUCCESS, "Reference file \"%s\" open succeed.", argv[count + 1]); + p_reference_file_name = argv[count + 1]; } - - // 记录文件名 - target_node->file_name_str = argv[count]; + 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; } - // 检查文件列表状态 - if (source_file_list_head == nullptr) + // 其余的作为源文件输入 { - print_log(LOG_FAILURE, "No source file input.\n"); - free(source_file_list_head); - fcloseall(); - exit(0); + // 排查重复文件 + 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(" ├─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; } - // 检查参考文件输入文件状态 - if (input_reference_A2L_file == nullptr) - { - fcloseall(); - exit(0); - } + printf(" ├─Reference file:\n"); + if (p_reference_file_name == nullptr) + printf(" │ └─(NULL)\n"); + else + printf(" │ └─%s\n", p_reference_file_name); - // 处理输出文件名称 - if (output_name != nullptr) + 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_name, "wb+"); - char *buff = (char *)malloc(strlen(output_name) + strlen(OUTPUT_MIDDLEWARE_SUFFIX) + 1); - sprintf(buff, "%s%s", output_name, OUTPUT_MIDDLEWARE_SUFFIX); + // 打开合并输出文件 + 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 if (reference_A2L_name_str != nullptr) + // 不存在时打开默认的中间件输出 + else { - // 拼接默认的输出文件名 - const char *prefix = OUTPUT_A2L_DEFAULT_PREFIX; - char *buffer = (char *)malloc(strlen(reference_A2L_name_str) + strlen(prefix) + strlen(OUTPUT_MIDDLEWARE_SUFFIX) + 1); + output_middleware_file = fopen(OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME, "wb"); - // 获取路径部分长度和不带路径的文件名起始位置 - int path_length = strlen(reference_A2L_name_str); - const char *file_name_no_dir = reference_A2L_name_str + path_length - 1; - - // 遍历指针没有回到起始位置且没有遇到正反斜杠 - while (file_name_no_dir + 1 != reference_A2L_name_str && *file_name_no_dir != '\\' && *file_name_no_dir != '/') + if (output_middleware_file == nullptr) { - path_length--; - file_name_no_dir--; + log_printf(LOG_FAILURE, "Middleware output file \"%s\" create failed.", OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME); + clean_and_exit(-1); } - file_name_no_dir++; - - // 开始拼接 - for (int count = 0; count < path_length; count++) - buffer[count] = reference_A2L_name_str[count]; - sprintf(buffer + path_length, "%s%s", prefix, file_name_no_dir); - - print_log(LOG_NORMAL, "%-31s %s\n", "Default output filename:", buffer); - - // 打开输出文件 - output_target_A2L_file = fopen(buffer, "wb+"); - - // 打开中间件文件 - sprintf(buffer + path_length + strlen(prefix) + strlen(file_name_no_dir), OUTPUT_MIDDLEWARE_SUFFIX); - output_middleware_file = fopen(buffer, "wb+"); - - // 释放临时指针 - free(buffer); + else + log_printf(LOG_SUCCESS, "Middleware output file \"%s\" create succeed.", OUTPUT_DEFAULT_MIDDLEWARE_FILE_NAME); } - // 检查map链接文件文件状态 - if (input_map_file == nullptr) - print_log(LOG_WARN, "%-31s %s\n", "No link .map file input.", "Address will be set to 0x00000000"); } } // 解析宏定义 void solve_defines(void) { - file_node *target_node = source_file_list_head; - + file_node *target_file_node = source_and_header_file_list_head; + define_node *define_show_begin_node = nullptr; // 循环处理文件链表 - while (target_node != nullptr) + + log_printf(LOG_INFO, "Solved definition details:"); + + while (target_file_node != nullptr) { FILE *target_file = nullptr; - target_file = fopen(target_node->file_name_str, "rb"); - // 处理无效的文件输入 - if (target_file == nullptr) - { - print_log(LOG_FAILURE, "Source file \"%s\" open failed.\n", target_node->file_name_str); - target_node = target_node->p_next; - continue; - } - - // 成功打开文件 - print_log(LOG_NORMAL, "%-31s %s\n\n", "Start define solving:", target_node->file_name_str); + target_file = fopen(target_file_node->file_name_str, "rb"); char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'}; // 循环按行解析 while (true) { - error_type_enum err = f_getline(target_file, segment_buff, sizeof(segment_buff)); - if (err != ERROR_NONE) + // 跳过空白读行 + f_seek_skip_blanks(target_file); + if (f_getline(target_file, segment_buff, sizeof(segment_buff)) == 0) break; // 查找到define - if (strstr(segment_buff, "#define")) + if (strstr(segment_buff, "#define") == segment_buff) { - printf("#define%s", segment_buff + strlen("#define")); + // 检查是否为数值类型的#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_node; + static define_node *target_define_node; if (define_list_head == nullptr) { define_list_head = (define_node *)malloc(sizeof(define_node)); - target_node = define_list_head; - memset(target_node->define_str, '\0', sizeof(target_node->define_str)); - memset(target_node->context_str, '\0', sizeof(target_node->context_str)); - target_node->p_next = nullptr; + target_define_node = define_list_head; + define_show_begin_node = define_list_head; } else { - target_node->p_next = (define_node *)malloc(sizeof(define_node)); - target_node = target_node->p_next; - memset(target_node->define_str, '\0', sizeof(target_node->define_str)); - memset(target_node->context_str, '\0', sizeof(target_node->context_str)); - target_node->p_next = nullptr; + 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%s", target_node->define_str, target_node->context_str); + sscanf(segment_buff, "%*s%s%u", target_define_node->define_str, &target_define_node->value); } } + // 关闭文件 fclose(target_file); - target_node = target_node->p_next; + + // 日志输出 + 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) { - file_node *target_node = source_file_list_head; + // 类型名称 + 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_node != nullptr) + while (target_file_node != nullptr) { FILE *target_file = nullptr; - target_file = fopen(target_node->file_name_str, "rb"); - // 处理无效的文件输入 - if (target_file == nullptr) - { - print_log(LOG_FAILURE, "Source file \"%s\" open failed.\n", target_node->file_name_str); - target_node = target_node->p_next; - continue; - } - - // 成功打开文件 - print_log(LOG_NORMAL, "%-31s %s\n\n", "Start type solving:", target_node->file_name_str); + target_file = fopen(target_file_node->file_name_str, "rb"); char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'}; // 循环按行解析 while (true) { - error_type_enum err = f_getline(target_file, segment_buff, sizeof(segment_buff)); - if (err != ERROR_NONE) + // 类型链表指针 + 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_begin)) + if (strstr(segment_buff, "typedef")) { - printf("\n%s\n\n", typedef_begin); + // 回退到typedef之后重新读取 + fseek(target_file, -(strlen(segment_buff) - strlen("typedef") - (strstr(segment_buff, "typedef") - segment_buff)), SEEK_CUR); + f_seek_skip_comments_and_blanks(target_file); + if (f_getline(target_file, segment_buff, sizeof(segment_buff)) == 0) + break; - // 循环处理 - while (true) + // 检查是否是支持的类型 + if (!strstr(segment_buff, "struct")) { - size_t seek_len = 0; - error_type_enum err = f_getline(target_file, segment_buff, sizeof(segment_buff), &seek_len); - if (err != ERROR_NONE) - break; + while (fgetc(target_file) != '}') + ; + continue; + } - // 类型定义结束行 - if (strstr(segment_buff, typedef_end)) + // 分配空间,类型链表头为空时初始化类型链表头 + 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) { - printf("\n%s\n\n", typedef_end); - break; - } - - // 检测到typedef - if (strstr(segment_buff, "typedef")) - { - static type_node *target_type_node; - - // 类型链表头为空时初始化类型链表头 - if (type_list_head == nullptr) + if (f_get_codeline(target_file, segment_buff, sizeof(segment_buff)) == 0) + break; + if (segment_buff[0] == '}') { - type_list_head = (type_node *)malloc(sizeof(type_node)); - type_list_head->element_list_head = nullptr; - type_list_head->p_next = nullptr; - memset(type_list_head->type_name_str, '\0', sizeof(type_list_head->type_name_str)); - target_type_node = type_list_head; + // 回退到结束末尾 + 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 { - // 扩展到下一张链表 - type_node *temp_node = (type_node *)malloc(sizeof(type_node)); - target_type_node->p_next = temp_node; - target_type_node = temp_node; + 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); - // 回退文件指针到typedef结尾 - fseek(target_file, -(seek_len - ((strstr(segment_buff, "typedef") - segment_buff) + strlen("typedef"))), SEEK_CUR); - - // 读取下一个有效词组 - f_getword(target_file, segment_buff, sizeof(segment_buff), &seek_len); - // 表示struct起始 - if (!strcmp(segment_buff, "struct")) + // 非法子成员检查 + if (target_element_node->element_info.element_count == 0) { - target_type_node->type = STRUCTURE; - // 直接结构体类型名 - if (f_getword(target_file, segment_buff, sizeof(segment_buff), &seek_len) == ERROR_NONE) - sprintf(target_type_node->type_name_str, segment_buff); + illegal_sub_element = true; + break; } - // 跳转到定义内 - while (fgetc(target_file) != '{') + 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; + } - // 新建第一个子元素节点 - sub_element_node *element_node = (sub_element_node *)malloc(sizeof(sub_element_node)); - element_node->p_next = nullptr; - target_type_node->element_list_head = element_node; - - // 复合类型解析 - while (true) + // 处理剩余部分的别名串 + while (true) + { + f_seek_skip_blanks(target_file); + if (f_getword(target_file, segment_buff, sizeof(segment_buff)) == 0) { - f_seek_skip_blank(target_file); - f_get_codeline(target_file, segment_buff, sizeof(segment_buff), &seek_len); - - // 解析成员类型 - element_node->element_info = solve_base_variable(segment_buff); - - /** - * @todo - * 去掉临时输出,改用制表符输出 - */ - if (element_node->element_info.element_count == 1) - printf(".%s\n", element_node->element_info.name_str); - else - printf(".%s[%d]\n", element_node->element_info.name_str, element_node->element_info.element_count); - - f_seek_skip_blank(target_file); - if (fgetc(target_file) == '}') + if (fgetc(target_file) == ';') break; - else - { - fseek(target_file, -1, SEEK_CUR); - element_node->p_next = (sub_element_node *)malloc(sizeof(sub_element_node)); - element_node = element_node->p_next; - element_node->p_next = nullptr; - } + continue; } - // 处理类型别名(一个或多个) - while (true) + // 已经有直接名串 + if (target_type_node->type_name_str[0] != '\0') { - if (f_getword(target_file, segment_buff, sizeof(segment_buff), &seek_len) == ERROR_NONE) + // 扩展到下一张链表并记录信息 + 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) { - // 当前还没有类型名 - if (target_type_node->type_name_str[0] == '\0') + variable_info *info = &p_element->element_info; + if (p_element->p_next != nullptr) { - sprintf(target_type_node->type_name_str, segment_buff); + 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 { - target_type_node->p_next = (type_node *)malloc(sizeof(type_node)); - memset(target_type_node->p_next->type_name_str, '\0', sizeof(target_type_node->type_name_str)); - target_type_node->p_next->element_list_head = target_type_node->element_list_head; - target_type_node->p_next->type = target_type_node->type; - target_type_node->p_next->p_next = nullptr; - sprintf(target_type_node->p_next->type_name_str, segment_buff); - target_type_node = target_type_node->p_next; + 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; } - f_seek_skip_blank(target_file); - if (fgetc(target_file) == ';') - break; + } + + 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; } } } - fclose(target_file); - target_node = target_node->p_next; + // 切换文件 + target_file_node = target_file_node->p_next; } } // 处理中间件 void solve_middleware(void) { - file_node *target_node = source_file_list_head; + fprintf(output_middleware_file, "\r\n\r\n%s\r\n\r\n", START_OF_GENERATED_PATTERN_STR); + file_node *target_file_node = source_and_header_file_list_head; - // 循环处理输入文件链表 - while (target_node != nullptr) + // 循环处理输入文件 + while (target_file_node != nullptr) { - FILE *target_file = nullptr; - target_file = fopen(target_node->file_name_str, "rb"); - if (target_file == nullptr) - { - print_log(LOG_FAILURE, "Source file \"%s\" load failed.\n", target_node->file_name_str); - target_node = target_node->p_next; - continue; - } - - print_log(LOG_NORMAL, "%-31s %s\n\n", "Start variable solving:", target_node->file_name_str); + 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)) == ERROR_NONE) + while (f_getline(target_file, segment_buff, sizeof(segment_buff)) != 0) { - // 当前行为观测量起始位行 - if (strstr(segment_buff, measurement_begin)) + // 检测到标定量起始行 + if (strstr(segment_buff, START_OF_CALIBRATION_PATTERN_STR)) { - printf("\n%s\n\n", measurement_begin); - fprintf(output_middleware_file, auto_generated_measurement_start); - - // 清空段缓冲区 - memset(segment_buff, '\0', sizeof(segment_buff)); - - while (true) + do { - // 获取下一行 - size_t seek_len = 0; - f_getline(target_file, segment_buff, sizeof(segment_buff), &seek_len); - - // 观测量结束行 - if (strstr(segment_buff, measurement_end)) - { - printf("\n%s\n\n", measurement_end); - fprintf(output_middleware_file, auto_generated_measurement_end); + // 跳过空白部分 + 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, -seek_len, SEEK_CUR); - f_seek_skip_blank(target_file); - memset(segment_buff, '\0', sizeof(segment_buff)); - f_get_codeline(target_file, segment_buff, sizeof(segment_buff), &seek_len); + // 回退行并读取代码行 + fseek(target_file, -read_count, SEEK_CUR); + f_get_codeline(target_file, segment_buff, sizeof(segment_buff)); - // 解析元素变量信息 - { - variable_info info = solve_variable(segment_buff); + variable_info v_info = solve_variable_info(segment_buff); - // 成功解析 - if (info.type != TYPE_NOT_SUPPORTED) - { - // 结构体解析 - if (info.type == STRUCTURE) - { - // 匹配类型描述链表位置 - type_node *target_type = type_list_head; - while (target_type != nullptr) - { - if (!strcmp(target_type->type_name_str, info.type_name_str)) - { - info.type_name_str = target_type->type_name_str; - break; - } - target_type = target_type->p_next; - } - - sub_element_node *sub_element_list = target_type->element_list_head; - - // 获取地址 - // info = get_element_addr(info, Input_Map); - - // 调试信息 - if (info.start_addr_32 != 0) - { - if (info.element_count == 1) - print_log(LOG_SUCCESS, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_SUCCESS, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - else - { - if (info.element_count == 1) - print_log(LOG_WARN, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_WARN, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - - // 单变量 - if (info.element_count == 1) - { - int addr_offset = 0; - while (sub_element_list != nullptr) - { - // 计算地址偏移 - if (addr_offset % sub_element_list->element_info.single_element_size != 0) - addr_offset += sub_element_list->element_info.single_element_size - (addr_offset % sub_element_list->element_info.single_element_size); - - // 子元素非数组 - if (sub_element_list->element_info.element_count == 1) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin MEASUREMENT"); // 观测量头 - - fprintf(output_middleware_file, " %s.%s\r\n", info.name_str, sub_element_list->element_info.name_str); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", "0"); // 分辨率 - fprintf(output_middleware_file, " %s\r\n", "0"); // 精度误差 - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_max_limit_str); // 上限 - fprintf(output_middleware_file, " %s 0x%08x\r\n\r\n", "ECU_ADDRESS", info.start_addr_32 + addr_offset); // ECU 地址 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 - - addr_offset += sub_element_list->element_info.single_element_size; - } - // 子元素是数组 - else - { - // 计算地址偏移 - if (addr_offset % sub_element_list->element_info.single_element_size != 0) - addr_offset += sub_element_list->element_info.single_element_size - (addr_offset % sub_element_list->element_info.single_element_size); - - for (size_t count = 0; count < sub_element_list->element_info.element_count; count++) - { - - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin MEASUREMENT"); // 观测量头 - - fprintf(output_middleware_file, " %s.%s[%d]\r\n", info.name_str, sub_element_list->element_info.name_str, count); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", "0"); // 分辨率 - fprintf(output_middleware_file, " %s\r\n", "0"); // 精度误差 - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_max_limit_str); // 上限 - fprintf(output_middleware_file, " %s 0x%08x\r\n\r\n", "ECU_ADDRESS", info.start_addr_32 + addr_offset + count * sub_element_list->element_info.single_element_size); // ECU 地址 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 - } - addr_offset += sub_element_list->element_info.element_count * sub_element_list->element_info.single_element_size; - } - - sub_element_list = sub_element_list->p_next; - } - } - // 类型是数组 - else - { - int addr_offset = 0; - - for (size_t outter_count = 0; outter_count < info.element_count; outter_count++) - { - sub_element_node *list = sub_element_list; - while (list != nullptr) - { - // 计算地址偏移 - if (addr_offset % list->element_info.single_element_size != 0) - addr_offset += list->element_info.single_element_size - (addr_offset % list->element_info.single_element_size); - - // 子元素非数组 - if (list->element_info.element_count == 1) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin MEASUREMENT"); // 观测量头 - - fprintf(output_middleware_file, " %s[%d].%s\r\n", info.name_str, outter_count, list->element_info.name_str); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", "0"); // 分辨率 - fprintf(output_middleware_file, " %s\r\n", "0"); // 精度误差 - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_max_limit_str); // 上限 - fprintf(output_middleware_file, " %s 0x%08x\r\n\r\n", "ECU_ADDRESS", info.start_addr_32 + addr_offset); // ECU 地址 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 - - addr_offset += list->element_info.single_element_size; - } - // 子元素是数组 - else - { - // 计算地址偏移 - if (addr_offset % list->element_info.single_element_size != 0) - addr_offset += list->element_info.single_element_size - (addr_offset % list->element_info.single_element_size); - - for (size_t count = 0; count < list->element_info.element_count; count++) - { - - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin MEASUREMENT"); // 观测量头 - - fprintf(output_middleware_file, " %s[%d].%s[%d]\r\n", info.name_str, outter_count, list->element_info.name_str, count); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", "0"); // 分辨率 - fprintf(output_middleware_file, " %s\r\n", "0"); // 精度误差 - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_max_limit_str); // 上限 - fprintf(output_middleware_file, " %s 0x%08x\r\n\r\n", "ECU_ADDRESS", info.start_addr_32 + addr_offset + count * list->element_info.single_element_size); // ECU 地址 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 - } - addr_offset += list->element_info.element_count * list->element_info.single_element_size; - } - - list = list->p_next; - } - } - } - } - else - { - // 获取地址 - // info = get_element_addr(info, Input_Map); - - // 调试信息 - if (info.start_addr_32 != 0) - { - if (info.element_count == 1) - print_log(LOG_SUCCESS, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_SUCCESS, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - else - { - if (info.element_count == 1) - print_log(LOG_WARN, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_WARN, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - - // 单变量 - if (info.element_count == 1) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin MEASUREMENT"); // 观测量头 - - fprintf(output_middleware_file, " %s\r\n", info.name_str); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", "0"); // 分辨率 - fprintf(output_middleware_file, " %s\r\n", "0"); // 精度误差 - fprintf(output_middleware_file, " %s\r\n", info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n", info.A2L_max_limit_str); // 上限 - fprintf(output_middleware_file, " %s 0x%08x\r\n\r\n", "ECU_ADDRESS", info.start_addr_32); // ECU 地址 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 - } - else - { - for (size_t count = 0; count < info.element_count; count++) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin MEASUREMENT"); // 观测量头 - - fprintf(output_middleware_file, " %s[%d]\r\n", info.name_str, count); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", "0"); // 分辨率 - fprintf(output_middleware_file, " %s\r\n", "0"); // 精度误差 - fprintf(output_middleware_file, " %s\r\n", info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n", info.A2L_max_limit_str); // 上限 - fprintf(output_middleware_file, " %s 0x%08x\r\n\r\n", "ECU_ADDRESS", info.start_addr_32 + count * info.single_element_size); // ECU 地址 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 - } - } - } - } - else if (info.name_str[0] != '\0') // 解析失败且变量名不为空 - { - if (info.element_count == 1) - print_log(LOG_FAILURE, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_FAILURE, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - } - - // 先跳行,防止段尾位注释引起异常 - f_seek_nextline(target_file); - // 跳过空白段 - f_seek_skip_blank(target_file); - // 清空段缓冲区 - memset(segment_buff, '\0', sizeof(segment_buff)); - } + f_print_calibration(output_middleware_file, v_info); + } while (true); } - // 当前行为标定量起始位行 - if (strstr(segment_buff, calibration_begin)) + // 观测量起始行 + if (strstr(segment_buff, START_OF_MEASURMENT_PATTERN_STR)) { - printf("\n%s\n\n", calibration_begin); - fprintf(output_middleware_file, auto_generated_calibration_start); - - // 清空段缓冲区 - memset(segment_buff, '\0', sizeof(segment_buff)); - - while (true) + do { - // 获取下一行 - size_t seek_len = 0; - f_getline(target_file, segment_buff, sizeof(segment_buff), &seek_len); - - // 标定量结束行 - if (strstr(segment_buff, calibration_end)) - { - printf("\n%s\n\n", calibration_end); - fprintf(output_middleware_file, auto_generated_calibration_end); + // 跳过空白部分 + 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, -seek_len, SEEK_CUR); - f_seek_skip_blank(target_file); - memset(segment_buff, '\0', sizeof(segment_buff)); - f_get_codeline(target_file, segment_buff, sizeof(segment_buff), &seek_len); - - // 解析元素变量信息 - { - variable_info info = solve_variable(segment_buff); - - // 成功解析 - if (info.type != TYPE_NOT_SUPPORTED) - { - - if (info.type == STRUCTURE) - { - // 匹配类型描述链表位置 - type_node *target_type = type_list_head; - while (target_type != nullptr) - { - if (!strcmp(target_type->type_name_str, info.type_name_str)) - { - info.type_name_str = target_type->type_name_str; - break; - } - target_type = target_type->p_next; - } - - sub_element_node *sub_element_list = target_type->element_list_head; - - // 获取地址 - // info = get_element_addr(info, Input_Map); - - // 调试信息 - if (info.start_addr_32 != 0) - { - if (info.element_count == 1) - print_log(LOG_SUCCESS, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_SUCCESS, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - else - { - if (info.element_count == 1) - print_log(LOG_WARN, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_WARN, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - - // 单变量 - if (info.element_count == 1) - { - int addr_offset = 0; - while (sub_element_list != nullptr) - { - // 计算地址偏移 - if (addr_offset % sub_element_list->element_info.single_element_size != 0) - addr_offset += sub_element_list->element_info.single_element_size - (addr_offset % sub_element_list->element_info.single_element_size); - - // 子元素非数组 - if (sub_element_list->element_info.element_count == 1) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin CHARACTERISTIC"); // 标定量头 - - fprintf(output_middleware_file, " %s.%s\r\n", info.name_str, sub_element_list->element_info.name_str); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) - fprintf(output_middleware_file, " 0x%08x\r\n", info.start_addr_32 + addr_offset); // ECU 地址 - fprintf(output_middleware_file, " Scalar_%s\r\n", sub_element_list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "0"); // 允许最大差分 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n\r\n", sub_element_list->element_info.A2L_max_limit_str); // 上限 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 - - addr_offset += sub_element_list->element_info.single_element_size; - } - // 子元素是数组 - else - { - // 计算地址偏移 - if (addr_offset % sub_element_list->element_info.single_element_size != 0) - addr_offset += sub_element_list->element_info.single_element_size - (addr_offset % sub_element_list->element_info.single_element_size); - - for (size_t count = 0; count < sub_element_list->element_info.element_count; count++) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin CHARACTERISTIC"); // 标定量头 - - fprintf(output_middleware_file, " %s.%s[%d]\r\n", info.name_str, sub_element_list->element_info.name_str, count); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) - fprintf(output_middleware_file, " 0x%08x\r\n", info.start_addr_32 + addr_offset + count * sub_element_list->element_info.single_element_size); // ECU 地址 - fprintf(output_middleware_file, " Scalar_%s\r\n", sub_element_list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "0"); // 允许最大差分 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", sub_element_list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n\r\n", sub_element_list->element_info.A2L_max_limit_str); // 上限 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 - } - addr_offset += sub_element_list->element_info.element_count * sub_element_list->element_info.single_element_size; - } - - sub_element_list = sub_element_list->p_next; - } - } - // 类型是数组 - else - { - int addr_offset = 0; - - for (size_t outter_count = 0; outter_count < info.element_count; outter_count++) - { - sub_element_node *list = sub_element_list; - while (list != nullptr) - { - // 计算地址偏移 - if (addr_offset % list->element_info.single_element_size != 0) - addr_offset += list->element_info.single_element_size - (addr_offset % list->element_info.single_element_size); - - // 子元素非数组 - if (list->element_info.element_count == 1) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin CHARACTERISTIC"); // 标定量头 - - fprintf(output_middleware_file, " %s[%d].%s\r\n", info.name_str, outter_count, list->element_info.name_str); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) - fprintf(output_middleware_file, " 0x%08x\r\n", info.start_addr_32 + addr_offset); // ECU 地址 - fprintf(output_middleware_file, " Scalar_%s\r\n", list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "0"); // 允许最大差分 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n\r\n", list->element_info.A2L_max_limit_str); // 上限 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 - - addr_offset += list->element_info.single_element_size; - } - // 子元素是数组 - else - { - // 计算地址偏移 - if (addr_offset % list->element_info.single_element_size != 0) - addr_offset += list->element_info.single_element_size - (addr_offset % list->element_info.single_element_size); - - for (size_t count = 0; count < list->element_info.element_count; count++) - { - - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin CHARACTERISTIC"); // 标定量头 - - fprintf(output_middleware_file, " %s[%d].%s[%d]\r\n", info.name_str, outter_count, list->element_info.name_str, count); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) - fprintf(output_middleware_file, " 0x%08x\r\n", info.start_addr_32 + addr_offset + count * list->element_info.single_element_size); // ECU 地址 - fprintf(output_middleware_file, " Scalar_%s\r\n", list->element_info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "0"); // 允许最大差分 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", list->element_info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n\r\n", list->element_info.A2L_max_limit_str); // 上限 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 - } - addr_offset += list->element_info.element_count * list->element_info.single_element_size; - } - - list = list->p_next; - } - } - } - } - else - { - // 获取地址 - // info = get_element_addr(info, Input_Map); - - // 调试信息 - if (info.start_addr_32 != 0) - { - if (info.element_count == 1) - print_log(LOG_SUCCESS, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_SUCCESS, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - else - { - if (info.element_count == 1) - print_log(LOG_WARN, "0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - print_log(LOG_WARN, "0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - - // 单变量 - if (info.element_count == 1) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin CHARACTERISTIC"); // 标定量头 - - fprintf(output_middleware_file, " %s\r\n", info.name_str); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) - fprintf(output_middleware_file, " 0x%08x\r\n", info.start_addr_32); // ECU 地址 - fprintf(output_middleware_file, " Scalar_%s\r\n", info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "0"); // 允许最大差分 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n\r\n", info.A2L_max_limit_str); // 上限 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 - } - else - { - for (size_t count = 0; count < info.element_count; count++) - { - fprintf(output_middleware_file, "%s\r\n\r\n", "/begin CHARACTERISTIC"); // 标定量头 - - fprintf(output_middleware_file, " %s[%d]\r\n", info.name_str, count); // 名称 - fprintf(output_middleware_file, " \"auto generated\"\r\n"); // 描述 - fprintf(output_middleware_file, " %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) - fprintf(output_middleware_file, " 0x%08x\r\n", info.start_addr_32 + count * info.single_element_size); // ECU 地址 - fprintf(output_middleware_file, " Scalar_%s\r\n", info.A2L_type_str); // 数据类型 - fprintf(output_middleware_file, " %s\r\n", "0"); // 允许最大差分 - fprintf(output_middleware_file, " %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) - fprintf(output_middleware_file, " %s\r\n", info.A2L_min_limit_str); // 下限 - fprintf(output_middleware_file, " %s\r\n\r\n", info.A2L_max_limit_str); // 上限 - - fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 - } - } - } - } - else if (info.name_str[0] != '\0') // 解析失败且变量名不为空 - { - if (info.element_count == 1) - printf("[< FAIL >] 0x%08x %-20s %s;\n", info.start_addr_32, info.A2L_type_str, info.name_str); - else - printf("[< FAIL >] 0x%08x %-20s %s[%d];\n", info.start_addr_32, info.A2L_type_str, info.name_str, info.element_count); - } - } - - // 先跳行,防止段尾位注释引起异常 - f_seek_nextline(target_file); - // 跳过空白段 - f_seek_skip_blank(target_file); - // 清空段缓冲区 - memset(segment_buff, '\0', sizeof(segment_buff)); - } + // 回退行并读取代码行 + 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_node = target_node->p_next; + target_file_node = target_file_node->p_next; } + + fprintf(output_middleware_file, "\r\n\r\n%s\r\n\r\n", END_OF_GENERATED_PATTERN_STR); } // 处理最终A2L输出 @@ -969,10 +866,10 @@ void solve_A2L_output(void) char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'}; // 读取并复制参考文件直到 a2l MODULE 结尾 - while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) == ERROR_NONE) + while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) != 0) { // 当前行为 a2l MODULE 结尾 - if (strstr(segment_buff, a2l_module_end)) + if (strstr(segment_buff, A2L_INSERT_PATTERN_STR)) { // 回退文件指针到上一行结尾 fseek(input_reference_A2L_file, -2, SEEK_CUR); @@ -982,7 +879,7 @@ void solve_A2L_output(void) } // 输出行到文件 - // fprintf(Output_Target, segment_buff); // 太大300会段溢出 + // fprintf(Output_Target, segment_buff); // 太大会段溢出,标准输入输出库存在的问题 for (int count = 0; count < SEGMENT_BUFF_LENGTH; count++) // 逐个输出 { fputc(segment_buff[count], output_target_A2L_file); @@ -993,6 +890,8 @@ void solve_A2L_output(void) // 清空段缓冲区 memset(segment_buff, '\0', sizeof(segment_buff)); } + + // 清空缓冲区并回退到文件起始位置 fseek(output_middleware_file, 0, SEEK_SET); char ch = fgetc(output_middleware_file); @@ -1003,7 +902,7 @@ void solve_A2L_output(void) } // 输出参考文件的剩余部分 - while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) == ERROR_NONE) + while (f_getline(input_reference_A2L_file, segment_buff, sizeof(segment_buff)) != 0) { // 输出行到文件 fprintf(output_target_A2L_file, segment_buff); @@ -1011,4 +910,5 @@ void solve_A2L_output(void) memset(segment_buff, '\0', sizeof(segment_buff)); } } + // end \ No newline at end of file diff --git a/Src/Global_Variables.cpp b/Src/Global_Variables.cpp index b78b97e..1168351 100644 --- a/Src/Global_Variables.cpp +++ b/Src/Global_Variables.cpp @@ -11,8 +11,8 @@ type_node *type_list_head = nullptr; // 宏定义列表 define_node *define_list_head = nullptr; -// 源文件列表 -file_node *source_file_list_head = nullptr; +// 源文件及头文件列表 +file_node *source_and_header_file_list_head = nullptr; // 文件列表 FILE *input_reference_A2L_file = nullptr; diff --git a/Src/Main.cpp b/Src/Main.cpp index e1827e8..839ac87 100644 --- a/Src/Main.cpp +++ b/Src/Main.cpp @@ -13,25 +13,42 @@ extern "C" int main(int argc, char *argv[]) { + printf("\n\n"); + log_printf(LOG_SYS_INFO, "SrcToA2L Ver1.0"); + log_printf(LOG_SYS_INFO, "Auther: LuChiChick"); + log_printf(LOG_SYS_INFO, "%s\n%s\n%s\n\n", "Open source links:", + " ├─Github: https://git.luchichick.cn/LuChiChick/SrcToA2L", + " └─Personal Git System: https://git.luchichick.cn/LuChiChick/SrcToA2L"); + + log_printf(LOG_SYS_INFO, "Start argument solve.\n\n"); + // 处理输入部分 solve_args(argc, argv); - printf("\n\n"); - // 进行宏定义解析 + printf("\n\n"); + log_printf(LOG_SYS_INFO, "Start constant value definition solve.\n\n"); solve_defines(); - printf("\n\n"); - // 进行类型解析 + printf("\n\n"); + log_printf(LOG_SYS_INFO, "Start compound type definition solve.\n\n"); solve_types(); // 处理中间件 + printf("\n\n"); + log_printf(LOG_SYS_INFO, "Start calibration and measurement solve.\n\n"); solve_middleware(); // 处理最终输出 - solve_A2L_output(); + if (input_reference_A2L_file != nullptr) + { + printf("\n\n"); + log_printf(LOG_SYS_INFO, "Start merging middleware into reference A2L file.\n\n"); + solve_A2L_output(); + } - print_log(LOG_SUCCESS, "Done.\nVer0.3"); + log_printf(LOG_SYS_INFO, "Done."); + clean_and_exit(0); return 0; -} \ No newline at end of file +} diff --git a/Src/Tool_Functions.cpp b/Src/Tool_Functions.cpp index a3f1d84..5f5a559 100644 --- a/Src/Tool_Functions.cpp +++ b/Src/Tool_Functions.cpp @@ -6,219 +6,138 @@ extern "C" #include "string.h" #include "ctype.h" #include "stdarg.h" +#include "time.h" +#include "stdlib.h" } -// 读取文件下一行 -error_type_enum f_getline(FILE *file, char *buffer, const size_t buffer_len, size_t *seek_len) +// 读取文件一行 +size_t f_getline(FILE *file, char *buffer, const size_t buffer_len) { if (buffer == nullptr || file == nullptr) - { - *seek_len = 0; - return ERROR_ILLEGAL_POINTER; - } + return 0; memset(buffer, '\0', buffer_len); size_t count = 0; + // 循环读取 while (true) { + // 超长判定 + if (count + 1 == buffer_len) + return buffer_len; + + // 正常读取 char ch = fgetc(file); - if (count >= buffer_len) // 超长 - { - fseek(file, -count, SEEK_CUR); - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_OUT_OF_LENGTH; - } + // 仅文件结尾时 + if (ch == EOF && count == 0) + return 0; - if (ch == EOF && count == 0) // 仅文件结尾时 - { - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_END_OF_FILE; - } - - if (ch == '\n' || ch == EOF) // 成功换行or文件结尾 + // 成功换行 + if (ch == '\n') { buffer[count] = '\n'; - if (seek_len != nullptr) - *seek_len = count + 1; - return ERROR_NONE; + return count + 1; } + // 没有换行但是遇到了文件结尾 + if (ch == EOF) + { + buffer[count] = '\n'; + return count; + } + + // 其它情况下正常复制 buffer[count] = ch; count++; } } -// 获取文件代码行(以;为分界的代码逻辑行,忽略中途的注释) -error_type_enum f_get_codeline(FILE *file, char *buffer, const size_t buffer_len, size_t *seek_len) +// 读取下一个有效词组 +size_t f_getword(FILE *file, char *buffer, const size_t buffer_len) { if (buffer == nullptr || file == nullptr) - { - *seek_len = 0; - return ERROR_ILLEGAL_POINTER; - } + return 0; + size_t read_count = 0; + // 过滤空白部分 + read_count = f_seek_skip_comments_and_blanks(file); memset(buffer, '\0', buffer_len); - size_t skip_count = 0; - - // 跳过空白内容和注释 - while (true) - { - skip_count += f_seek_skip_blank(file); - - // 忽略注释内容 - if (fgetc(file) == '/') - { - skip_count++; - // 是单行注释,连续遇到两个'/' - if (fgetc(file) == '/') - { - skip_count++; - skip_count += f_seek_nextline(file); - } - // 是多行注释,直接跳过中间内容直到遇到下一个'/' - else - { - while (fgetc(file) != '/') - skip_count++; - skip_count++; - } - } - else - { - fseek(file, -1, SEEK_CUR); - break; - } - } - - size_t code_line_count = 0; + size_t write_count = 0; while (true) { char ch = fgetc(file); - if (code_line_count >= buffer_len) // 超长 - { - fseek(file, -(skip_count + code_line_count), SEEK_CUR); - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_OUT_OF_LENGTH; - } - - if (ch == EOF && code_line_count == 0) // 仅文件结尾时 - { - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_END_OF_FILE; - } - - if (ch == ';') // 代码结尾 - { - buffer[code_line_count] = ';'; - if (seek_len != nullptr) - *seek_len = code_line_count + skip_count + 1; - return ERROR_NONE; - } - - if (ch == EOF) // 文件结尾 - { - buffer[code_line_count] = '\0'; - if (seek_len != nullptr) - *seek_len = code_line_count + skip_count; - return ERROR_NONE; - } - - buffer[code_line_count] = ch; - code_line_count++; - } -} - -// 读取下一个有效词组 -error_type_enum f_getword(FILE *file, char *buffer, const size_t buffer_len, size_t *seek_len) -{ - if (buffer == nullptr || file == nullptr) - { - *seek_len = 0; - return ERROR_ILLEGAL_POINTER; - } - - size_t read_count = 0; - // 过滤空白 - while (true) - { - char ch = fgetc(file); - if (read_count >= buffer_len) // 超长 + if (write_count >= buffer_len) // 超长 { fseek(file, -read_count, SEEK_CUR); - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_OUT_OF_LENGTH; + return 0; } if (ch == EOF && read_count == 0) // 仅文件结尾时 - { - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_END_OF_FILE; - } + return 0; - // 过滤空白 - if (ch == ' ' || ch == '\r' || ch == '\n') - { - read_count++; - continue; - } - - // 遇到非空格非换行的有效字符 - fseek(file, -1, SEEK_CUR); - break; - } - - size_t count = 0; - memset(buffer, '\0', buffer_len); - - while (true) - { - char ch = fgetc(file); - - if (read_count >= buffer_len) // 超长 - { - fseek(file, -read_count, SEEK_CUR); - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_OUT_OF_LENGTH; - } - - if (ch == EOF && count == 0) // 仅文件结尾时 - { - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_END_OF_FILE; - } - - if (!isalnum(ch) && ch != '_' && count == 0) // 遇到的第一个就是非有效字符 + if (!isalnum(ch) && ch != '_' && read_count == 0) // 遇到的第一个就是非有效字符 { fseek(file, -(read_count + 1), SEEK_CUR); - if (seek_len != nullptr) - *seek_len = 0; - return ERROR_ILLEGAL_WORD_SECTION; + return 0; } if (!isalnum(ch) && ch != '_') // 非字符类 { // 回退指针后正常返回 fseek(file, -1, SEEK_CUR); - if (seek_len != nullptr) - *seek_len = read_count; - return ERROR_NONE; + return read_count; } - buffer[count] = ch; - count++; + buffer[write_count] = ch; + write_count++; + read_count++; + } +} + +// 获取文件代码行(以;为分界的代码逻辑行,忽略中途的注释) +size_t f_get_codeline(FILE *file, char *buffer, const size_t buffer_len) +{ + if (buffer == nullptr || file == nullptr) + return 0; + size_t read_count = 0; + + // 过滤空白和注释部分 + read_count = f_seek_skip_comments_and_blanks(file); + memset(buffer, '\0', buffer_len); + + size_t write_count = 0; + + while (true) + { + char ch = fgetc(file); + + if (write_count >= buffer_len) // 超长 + { + fseek(file, -(read_count), SEEK_CUR); + return 0; + } + + if (ch == EOF && read_count == 0) // 仅文件结尾时 + return 0; + + if (ch == ';') // 代码结尾 + { + buffer[write_count] = ';'; + return read_count + 1; + } + + if (ch == EOF) // 文件结尾 + { + buffer[write_count] = '\0'; + return read_count; + } + + buffer[write_count] = ch; + write_count++; read_count++; } } @@ -226,11 +145,20 @@ error_type_enum f_getword(FILE *file, char *buffer, const size_t buffer_len, siz // 前进到下一行 size_t f_seek_nextline(FILE *file) { + if (file == nullptr) + return 0; + size_t count = 0; while (true) { char ch = fgetc(file); - if (ch == '\n' || ch == EOF) + + if (ch == '\n') + { + count++; + break; + } + if (ch == EOF) break; count++; @@ -240,8 +168,11 @@ size_t f_seek_nextline(FILE *file) } // 跳转到下一个非空字符 -size_t f_seek_skip_blank(FILE *file) +size_t f_seek_skip_blanks(FILE *file) { + if (file == nullptr) + return 0; + size_t count = 0; while (true) { @@ -263,145 +194,184 @@ size_t f_seek_skip_blank(FILE *file) return count; } -// 基础变量类型解析 -variable_type_enum get_variable_base_type(const char *str) +// 跳过注释和空白内容(不跳过识别段) +size_t f_seek_skip_comments_and_blanks(FILE *file) { - if (!strcmp(str, "bool")) - return UBYTE; - if (!strcmp(str, "boolean_t")) - return UBYTE; + if (file == nullptr) + return 0; - if (!strcmp(str, "uint8_t")) - return UBYTE; - if (!strcmp(str, "uint16_t")) - return UWORD; - if (!strcmp(str, "uint32_t")) - return ULONG; + size_t count = 0; - if (!strcmp(str, "int8_t")) - return SBYTE; - if (!strcmp(str, "int16_t")) - return SWORD; - if (!strcmp(str, "int32_t")) - return SLONG; + bool find_pattern_section = false; - if (!strcmp(str, "float")) - return FLOAT32; - if (!strcmp(str, "double")) - return FLOAT64; + while (true) + { + // 跳转到下一个有效字符 + count += f_seek_skip_blanks(file); + char ch = fgetc(file); - return TYPE_NOT_SUPPORTED; + // 检测到注释内容 + if (ch == '/') + { + ch = fgetc(file); + + // 是单行注释,直接跳转行 + if (ch == '/') + { + fseek(file, -2, SEEK_CUR); + count += f_seek_nextline(file); + } + // 是多行注释,判断是不是识别段(识别段在一行内结束) + else + { + // 回退读行 + fseek(file, -2, SEEK_CUR); + char segment_buff[SEGMENT_BUFF_LENGTH] = "\0"; + size_t read_length = f_getline(file, segment_buff, sizeof(segment_buff)); + + // 目标段正匹配且在起始位置 + if (strstr(segment_buff, START_OF_MEASURMENT_PATTERN_STR) == segment_buff) + find_pattern_section = true; + if (strstr(segment_buff, END_OF_MEASURMENT_PATTERN_STR) == segment_buff) + find_pattern_section = true; + if (strstr(segment_buff, START_OF_CALIBRATION_PATTERN_STR) == segment_buff) + find_pattern_section = true; + if (strstr(segment_buff, END_OF_CALIBRATION_PATTERN_STR) == segment_buff) + find_pattern_section = true; + + // 发现匹配段 + if (find_pattern_section) + { + fseek(file, -read_length, SEEK_CUR); + break; + } + else + fseek(file, -(read_length - 2), SEEK_CUR); // 回退到第第二位,避免单行的多行注释引发的问题 + + // 读取到多行注释结束位置 + while (fgetc(file) != '/') + count++; + count++; + + // 继续下个处理循环 + continue; + } + } + // 文件结尾 + else if (ch == EOF) + break; + // 非注释内容 + else + { + // 回退指针并退出 + fseek(file, -1, SEEK_CUR); + break; + } + } + + return count; } -// 基础变量解析 -variable_info solve_base_variable(const char *str) +// 解析变量类型 +variable_type_enum solve_variable_type(const char *type_str) +{ + // 基础类型解析 + { + if (!strcmp(type_str, "bool")) + return UBYTE; + if (!strcmp(type_str, "boolean_t")) + return UBYTE; + + if (!strcmp(type_str, "uint8_t")) + return UBYTE; + + if (!strcmp(type_str, "uint16_t")) + return UWORD; + + if (!strcmp(type_str, "uint32_t")) + return ULONG; + + if (!strcmp(type_str, "int8_t")) + return SBYTE; + + if (!strcmp(type_str, "int16_t")) + return SWORD; + + if (!strcmp(type_str, "int")) + return SLONG; + if (!strcmp(type_str, "int32_t")) + return SLONG; + + if (!strcmp(type_str, "float")) + return FLOAT32; + if (!strcmp(type_str, "double")) + return FLOAT64; + } + + // 遍历复合类型 + type_node *target_node = type_list_head; + while (target_node != nullptr) + { + if (!strcmp(type_str, target_node->type_name_str)) + return target_node->type; + target_node = target_node->p_next; + } + + return TYPE_UNKNOWN; +} + +// 变量解析 +variable_info solve_variable_info(const char *code_line_str) { variable_info info; - // 读取前段内容并获取元素类型 - char buff[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; + char buff[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'}; size_t offset = 0; - // 跳过前方的修饰段 while (true) { - sscanf(str + offset, "%s", buff); + sscanf(code_line_str + offset, "%s", buff); // 不是下列任何的前置修饰符号时跳出 if (!(!strcmp("const", buff) || !strcmp("static", buff) || !strcmp("volatile", buff))) break; - // 是修饰段 - while (str[offset] != ' ' && str[offset] != '\0') // 跳过当前词组段 + // 跳过当前修饰词 + while (code_line_str[offset] != ' ' && code_line_str[offset] != '\0') offset++; - while (!isalnum(str[offset]) && str[offset] != '\0') // 前进到有效字符 + // 跳过修饰词后的空白字符,前进到有效字符(字母或下划线开头的变量名) + while (!(isalpha(code_line_str[offset]) || code_line_str[offset] == '_') && code_line_str[offset] != '\0') offset++; memset(buff, '\0', sizeof(buff)); } - info.type = get_variable_base_type(buff); - - // 更新字符串信息 - switch (info.type) - { - case UBYTE: - sprintf(info.A2L_type_str, "UBYTE"); - sprintf(info.A2L_min_limit_str, "0"); - sprintf(info.A2L_max_limit_str, "255"); - info.single_element_size = 1; - break; - case UWORD: - sprintf(info.A2L_type_str, "UWORD"); - sprintf(info.A2L_min_limit_str, "0"); - sprintf(info.A2L_max_limit_str, "65535"); - info.single_element_size = 2; - break; - case ULONG: - sprintf(info.A2L_type_str, "ULONG"); - sprintf(info.A2L_min_limit_str, "0"); - sprintf(info.A2L_max_limit_str, "4294967295"); - info.single_element_size = 4; - break; - case SBYTE: - sprintf(info.A2L_type_str, "SBYTE"); - sprintf(info.A2L_min_limit_str, "-128"); - sprintf(info.A2L_max_limit_str, "127"); - info.single_element_size = 1; - case SWORD: - sprintf(info.A2L_type_str, "SWORD"); - sprintf(info.A2L_min_limit_str, "-32768"); - sprintf(info.A2L_max_limit_str, "32767"); - info.single_element_size = 2; - break; - case SLONG: - sprintf(info.A2L_type_str, "SLONG"); - sprintf(info.A2L_min_limit_str, "-2147483648"); - sprintf(info.A2L_max_limit_str, "2147483647"); - info.single_element_size = 4; - break; - case FLOAT32: - sprintf(info.A2L_type_str, "FLOAT32_IEEE"); - sprintf(info.A2L_min_limit_str, "-3.4E+38"); - sprintf(info.A2L_max_limit_str, "3.4E+38"); - info.single_element_size = 4; - break; - case FLOAT64: - sprintf(info.A2L_type_str, "FLOAT64_IEEE"); - sprintf(info.A2L_min_limit_str, "-1.7E+308"); - sprintf(info.A2L_max_limit_str, "1.7E+308"); - info.single_element_size = 8; - break; - default: - sprintf(info.A2L_type_str, "UNSUPPORTED"); - sprintf(info.A2L_min_limit_str, "0"); - sprintf(info.A2L_max_limit_str, "0"); - info.single_element_size = 0; - } + // 读取前段内容并获取元素类型 + info.type = solve_variable_type(buff); + sprintf(info.type_name_str, buff); // 读取后段内容 - sscanf(str + offset + strlen(buff), "%s", buff); + sscanf(code_line_str + offset + strlen(buff), "%s", buff); // 获取名字和长度 - for (int count = 0; count < VARIABLE_NAME_LENGTH_MAX; count++) + for (int count = 0; count < VARIABLE_NAME_STR_LENGTH_MAX; count++) { if (buff[count] == '[') // 识别到数组 { - for (int n = count + 1; n < VARIABLE_NAME_LENGTH_MAX; n++) + for (int n = count + 1; n < VARIABLE_NAME_STR_LENGTH_MAX; n++) { + // 到达数组定义结尾 if (buff[n] == ']') break; if (isdigit(buff[n])) info.element_count = info.element_count * 10 + buff[n] - '0'; else { - /** - * @todo - * 添加宏定义识别,先暂时将不支持的量定义为1 - */ - // 处理宏定义常量 - char define_str[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; - for (int count = 0; count < VARIABLE_NAME_LENGTH_MAX; count++) + // 处理宏定义常量,暂时将不支持的量定义为1 + + // 提取宏字符串 + char define_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'}; + for (int count = 0; count < VARIABLE_NAME_STR_LENGTH_MAX; count++) if (buff[n + count] == ']') break; else @@ -414,20 +384,18 @@ variable_info solve_base_variable(const char *str) // 找到宏定义了 if (!strcmp(target_define_node->define_str, define_str)) { - int value = 1; - sscanf(target_define_node->context_str, "%d", &value); - info.element_count = value; + info.element_count = target_define_node->value; break; } target_define_node = target_define_node->p_next; } - // 完全匹配但没有找到 + // 遍历完成但没有找到 if (target_define_node == nullptr) { - printf("\n"); - print_log(LOG_WARN, "%s [%s -> 1]\n", "Unknown value context,set to default:", define_str); - printf("\n"); - info.element_count = 1; + // printf("\n"); + // log_printf(LOG_WARN, "%s [%s -> 1]\n", "Unknown value context,set to default:", define_str); + // printf("\n"); + info.element_count = 0; } break; } @@ -438,174 +406,107 @@ variable_info solve_base_variable(const char *str) if (buff[count] == ' ' || buff[count] == '=' || buff[count] == ';') // 是单个变量 { - if (info.element_count == 0) - info.element_count = 1; + info.element_count = 1; break; } info.name_str[count] = buff[count]; // 复制变量名 } + // 不支持类型直接回传 + if (info.type == TYPE_UNKNOWN) + info.element_count = 0; + return info; } -// 解析变量类型 -variable_type_enum get_variable_type(const char *str) +// 获取变量地址 +uint32_t get_variable_addr32(const char *v_name_str) { - variable_type_enum type = get_variable_base_type(str); - if (type != TYPE_NOT_SUPPORTED) - return type; - - // 遍历复合类型 - type_node *target_node = type_list_head; - while (target_node != nullptr) + uint32_t addr32 = 0; + // 查找地址 + if (input_map_file != nullptr) { - if (!strcmp(str, target_node->type_name_str)) - return target_node->type; - target_node = target_node->p_next; - } + // 回退到起始位置 + fseek(input_map_file, 0, SEEK_SET); + char segment_buff[SEGMENT_BUFF_LENGTH] = {'\0'}; - return TYPE_NOT_SUPPORTED; -} - -// 变量解析 -variable_info solve_variable(const char *str) -{ - variable_info info; - - char buff[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; - size_t offset = 0; - - // 跳过前方的修饰段 - while (true) - { - sscanf(str + offset, "%s", buff); - - // 不是下列任何的前置修饰符号时跳出 - if (!(!strcmp("const", buff) || !strcmp("static", buff) || !strcmp("volatile", buff))) - break; - - // 是修饰段 - while (str[offset] != ' ' && str[offset] != '\0') // 跳过当前词组段 - offset++; - while (!isalnum(str[offset]) && str[offset] != '\0') // 前进到有效字符 - offset++; - - memset(buff, '\0', sizeof(buff)); - } - - // 读取前段内容并获取元素类型 - info.type = get_variable_type(buff); - - // 判断是否为结构体类型 - if (info.type == STRUCTURE) - { - sprintf(info.A2L_type_str, "STRUCTURE"); - - // 匹配类型描述链表位置 - type_node *target_type = type_list_head; - while (target_type != nullptr) + bool find = false; + // 循环读行 + while (f_getline(input_map_file, segment_buff, sizeof(segment_buff)) != 0 && !find) { - if (!strcmp(target_type->type_name_str, buff)) + // 匹配到变量名称 + if (strstr(segment_buff, v_name_str)) { - info.type_name_str = target_type->type_name_str; - break; - } - target_type = target_type->p_next; - } + char *lpTarget = strstr(segment_buff, v_name_str); + size_t len = strlen(v_name_str); - // 读取后段内容 - sscanf(str + offset + strlen(buff), "%s", buff); + // 匹配到的名称是后段中的子段内容---> xxxxx[name]xx + if (lpTarget[len] != ' ' && lpTarget[len] != '\r' && lpTarget[len] != '\n') + continue; + // 匹配到的名称是前段中的字段内容---> xx[name]xxxxx + if (*(lpTarget - 1) != '_' && *(lpTarget - 1) != ' ' && *(lpTarget - 1) != '@') + continue; - // 获取名字和长度 - for (int count = 0; count < VARIABLE_NAME_LENGTH_MAX; count++) - { - if (buff[count] == '[') // 识别到数组 - { - for (int n = count + 1; n < VARIABLE_NAME_LENGTH_MAX; n++) + find = true; + + // 回退指针到地址串起始位置 + while (*(lpTarget - 1) != ' ') + lpTarget--; + while (*(lpTarget - 1) == ' ') + lpTarget--; + while (*(lpTarget - 1) != ' ') + lpTarget--; + + char addr_str[20]; + sscanf(lpTarget, "%s", addr_str); + + // 16进制转换 + for (int count = 0; count < 20; count++) { - if (buff[n] == ']') + if (!isalnum(addr_str[count])) break; - if (isdigit(buff[n])) - info.element_count = info.element_count * 10 + buff[n] - '0'; + + if (isalpha(addr_str[count])) + addr32 = addr32 * 16 + toupper(addr_str[count]) - 'A' + 10; else - { - - /** - * @todo - * 添加宏定义识别,先暂时将不支持的量定义为1 - */ - // 处理宏定义常量 - char define_str[VARIABLE_NAME_LENGTH_MAX] = {'\0'}; - for (int count = 0; count < VARIABLE_NAME_LENGTH_MAX; count++) - if (buff[n + count] == ']') - break; - else - define_str[count] = buff[n + count]; - - // 进行匹配 - define_node *target_define_node = define_list_head; - while (target_define_node != nullptr) - { - // 找到宏定义了 - if (!strcmp(target_define_node->define_str, define_str)) - { - int value = 1; - sscanf(target_define_node->context_str, "%d", &value); - info.element_count = value; - break; - } - target_define_node = target_define_node->p_next; - } - // 完全匹配但没有找到 - if (target_define_node == nullptr) - { - printf("\n"); - print_log(LOG_WARN, "%s [%s -> 1]\n", "Unknown value context,set to default:", define_str); - printf("\n"); - info.element_count = 1; - } - break; - } + addr32 = addr32 * 16 + addr_str[count] - '0'; } - - break; } - - if (buff[count] == ' ' || buff[count] == '=' || buff[count] == ';') // 是单个变量 - { - if (info.element_count == 0) - info.element_count = 1; - break; - } - - info.name_str[count] = buff[count]; // 复制变量名 } - - return info; } - return solve_base_variable(str); + + return addr32; } // 日志输出 -void print_log(log_type_enum log_type, const char *p_format_str, ...) +void log_printf(log_type_enum log_type, const char *p_format_str, ...) { + time_t timestamp; + time(×tamp); + struct tm *timeinfo; + timeinfo = localtime(×tamp); + + // 输出时间戳 + printf("[%02d:%02d:%02d]@", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + + // 输出日志类型 switch (log_type) { case LOG_SUCCESS: - printf("[- OK -] "); + printf("[- OK -] "); break; case LOG_WARN: - printf("[+ WARN +] "); + printf("[+ WARN +] "); break; case LOG_FAILURE: - printf("[< FAIL >] "); + printf("[< FAIL >] "); break; - case LOG_NORMAL: - printf("[ INFO ] "); + case LOG_INFO: + printf("[ INFO ] "); break; - case LOG_ERROR: - printf("[# ERRO #] "); + case LOG_SYS_INFO: + printf("[# SYS_INFO #] "); break; } @@ -613,4 +514,417 @@ void print_log(log_type_enum log_type, const char *p_format_str, ...) va_list args; va_start(args, p_format_str); vprintf(p_format_str, args); -} \ No newline at end of file + printf("\n"); +} + +// 清理和退出 +void clean_and_exit(int exit_code) +{ + // 关闭文件 + fclose(input_reference_A2L_file); + fclose(input_map_file); + fclose(output_target_A2L_file); + fclose(output_middleware_file); + + // 释放分配的全局内存 + { + type_node *p_type_node = type_list_head; + while (p_type_node != nullptr) + { + type_node *temp = p_type_node; + p_type_node = p_type_node->p_next; + free(temp); + } + + define_node *p_define_node = define_list_head; + while (p_define_node != nullptr) + { + define_node *temp = p_define_node; + p_define_node = p_define_node->p_next; + free(temp); + } + + file_node *p_file_node = source_and_header_file_list_head; + while (p_file_node != nullptr) + { + file_node *temp = p_file_node; + p_file_node = p_file_node->p_next; + free(temp); + } + } + + log_printf(LOG_SYS_INFO, "All resources cleaned.Now exit."); + exit(exit_code); +} + +// 输出标定量 +void f_print_calibration(FILE *file, variable_info v_info) +{ + // 类型名称 + const char *type_str[] = { + "TYPE_UNKNOWN", // 未知类型 + "STRUCTURE", // 结构体类型 + "UBYTE", // uint8_t,bool,boolean_t + "UWORD", // uint16_t + "ULONG", // uint32_t + "SBYTE", // int8_t + "SWORD", // int16_t + "SLONG", // int32_t + "FLOAT32_IEEE", // float + "FLOAT64_IEEE", // double + }; + + // 下限字符串 + const char *min_str[] = { + "0", // 未知类型 + "0", // 结构体类型 + "0", // uint8_t,bool,boolean_t + "0", // uint16_t + "0", // uint32_t + "-128", // int8_t + "-32768", // int16_t + "-2147483648", // int32_t + "-3.4E+38", // float + "-1.7E+308", // double + }; + + // 上限字符串 + const char *max_str[] = { + "0", // 未知类型 + "0", // 结构体类型 + "255", // uint8_t,bool,boolean_t + "65535", // uint16_t + "4294967295", // uint32_t + "127", // int8_t + "32767", // int16_t + "2147483647", // int32_t + "3.4E+38", // float + "1.7E+308", // double + }; + + // 类型长度 + const size_t type_size[] = { + 0, // 未知类型 + 0, // 结构体类型 + 1, // uint8_t,bool,boolean_t + 2, // uint16_t + 4, // uint32_t + 1, // int8_t + 2, // int16_t + 4, // int32_t + 4, // float + 8, // double + }; + + // 获取地址 + uint32_t start_addr_32 = get_variable_addr32(v_info.name_str); + uint32_t addr_offset = 0; // 地址偏移 + uint32_t alignment_max = 0; // 出现的最大对齐(用于结构体末尾补齐空位) + + // 遍历每个元素 + for (size_t count = 0; count < v_info.element_count; count++) + { + // 匹配类型描述链表位置 + type_node *target_type = type_list_head; + // 数组子元素列表 + sub_element_node *element_node = nullptr; + + // 结构体类型时查找类型链表 + if (v_info.type == STRUCTURE) + { + while (target_type != nullptr) + { + if (!strcmp(target_type->type_name_str, v_info.type_name_str)) + break; + target_type = target_type->p_next; + } + element_node = target_type->element_list_head; + } + + // 输出名称及类型 + char *out_name = nullptr; + variable_type_enum out_type = TYPE_UNKNOWN; + + do + { + size_t sub_element_count = 1; + // 分配名称空间 + if (v_info.type == STRUCTURE) + { + out_name = (char *)malloc(strlen(v_info.name_str) + strlen(element_node->element_info.name_str) + 10); + sub_element_count = element_node->element_info.element_count; + out_type = element_node->element_info.type; + } + else + { + out_name = (char *)malloc(strlen(v_info.name_str) + 10); + out_type = v_info.type; + } + + for (size_t sub_count = 0; sub_count < sub_element_count; sub_count++) + { + // 计算出现的最大对齐 + if (alignment_max < (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE)) + alignment_max = (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE); + + // 地址对齐 + if (addr_offset % (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE) != 0) + addr_offset += (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE) - (addr_offset % (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE)); + + // 拼接输出名称 + if (v_info.type == STRUCTURE) + { + if (v_info.element_count == 1) + { + if (sub_element_count == 1) + sprintf(out_name, "%s.%s", v_info.name_str, element_node->element_info.name_str); + else + sprintf(out_name, "%s.%s[%d]", v_info.name_str, element_node->element_info.name_str, sub_count); + } + else + { + if (sub_element_count == 1) + sprintf(out_name, "%s[%d].%s", v_info.name_str, count, element_node->element_info.name_str); + else + sprintf(out_name, "%s[%d].%s[%d]", v_info.name_str, count, element_node->element_info.name_str, sub_count); + } + } + else + { + if (v_info.element_count == 1) + sprintf(out_name, "%s", v_info.name_str); + else + sprintf(out_name, "%s[%d]", v_info.name_str, count); + } + + fprintf(output_middleware_file, "%s\r\n", "/begin CHARACTERISTIC"); // 标定量头 + fprintf(output_middleware_file, " /* Name */ %s\r\n", out_name); // 名称 + fprintf(output_middleware_file, " /* Long Identifier */ \"Auto generated by SrcToA2L\"\r\n"); // 描述 + fprintf(output_middleware_file, " /* Type */ %s\r\n", "VALUE"); // 值类型(数值、数组、曲线) + fprintf(output_middleware_file, " /* ECU Address */ 0x%08X\r\n", start_addr_32 + addr_offset); // ECU 地址 + fprintf(output_middleware_file, " /* Record Layout */ Scalar_%s\r\n", type_str[out_type]); // 数据类型 + fprintf(output_middleware_file, " /* Maximum Difference */ %s\r\n", "0"); // 允许最大差分 + fprintf(output_middleware_file, " /* Conversion Method */ %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) + fprintf(output_middleware_file, " /* Lower Limit */ %s\r\n", min_str[out_type]); // 下限 + fprintf(output_middleware_file, " /* Upper Limit */ %s\r\n", max_str[out_type]); // 上限 + fprintf(output_middleware_file, "%s\r\n\r\n", "/end CHARACTERISTIC"); // 标定量尾 + + // 递增地址偏移 + addr_offset += type_size[out_type]; + } + + free(out_name); + + if (element_node != nullptr) + element_node = element_node->p_next; + } while (element_node != nullptr); + + // 补齐结构体末尾的空余字节偏移 + if (v_info.type == STRUCTURE) + if (addr_offset % (alignment_max < ADDR_ALIGNMENT_SIZE ? alignment_max : ADDR_ALIGNMENT_SIZE) != 0) + addr_offset += (alignment_max < ADDR_ALIGNMENT_SIZE ? alignment_max : ADDR_ALIGNMENT_SIZE) - (addr_offset % (alignment_max < ADDR_ALIGNMENT_SIZE ? alignment_max : ADDR_ALIGNMENT_SIZE)); + } + + // 输出日志 + if (start_addr_32 != 0 || input_map_file == nullptr) + { + if (v_info.element_count > 1) + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_SUCCESS, "%-15s %-15s 0x%08X %s[%d]", "Calibration", type_str[v_info.type], start_addr_32, v_info.name_str, v_info.element_count); + else + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_SUCCESS, "%-15s %-15s 0x%08X %s", "Calibration", type_str[v_info.type], start_addr_32, v_info.name_str); + } + else + { + if (v_info.element_count > 1) + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_WARN, "%-15s %-15s 0x%08X %s[%d]", "Calibration", type_str[v_info.type], start_addr_32, v_info.name_str, v_info.element_count); + else + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_WARN, "%-15s %-15s 0x%08X %s", "Calibration", type_str[v_info.type], start_addr_32, v_info.name_str); + } +} + +// 输出观测量 +void f_print_measurement(FILE *file, variable_info v_info) +{ + // 类型名称 + const char *type_str[] = { + "TYPE_UNKNOWN", // 未知类型 + "STRUCTURE", // 结构体类型 + "UBYTE", // uint8_t,bool,boolean_t + "UWORD", // uint16_t + "ULONG", // uint32_t + "SBYTE", // int8_t + "SWORD", // int16_t + "SLONG", // int32_t + "FLOAT32_IEEE", // float + "FLOAT64_IEEE", // double + }; + + // 下限字符串 + const char *min_str[] = { + "0", // 未知类型 + "0", // 结构体类型 + "0", // uint8_t,bool,boolean_t + "0", // uint16_t + "0", // uint32_t + "-128", // int8_t + "-32768", // int16_t + "-2147483648", // int32_t + "-3.4E+38", // float + "-1.7E+308", // double + }; + + // 上限字符串 + const char *max_str[] = { + "0", // 未知类型 + "0", // 结构体类型 + "255", // uint8_t,bool,boolean_t + "65535", // uint16_t + "4294967295", // uint32_t + "127", // int8_t + "32767", // int16_t + "2147483647", // int32_t + "3.4E+38", // float + "1.7E+308", // double + }; + + // 类型长度 + const size_t type_size[] = { + 0, // 未知类型 + 0, // 结构体类型 + 1, // uint8_t,bool,boolean_t + 2, // uint16_t + 4, // uint32_t + 1, // int8_t + 2, // int16_t + 4, // int32_t + 4, // float + 8, // double + }; + + // 获取地址 + uint32_t start_addr_32 = get_variable_addr32(v_info.name_str); + uint32_t addr_offset = 0; // 地址偏移 + uint32_t alignment_max = 0; // 出现的最大对齐(用于结构体末尾补齐空位) + + // 遍历每个元素 + for (size_t count = 0; count < v_info.element_count; count++) + { + // 匹配类型描述链表位置 + type_node *target_type = type_list_head; + // 数组子元素列表 + sub_element_node *element_node = nullptr; + + // 结构体类型时查找类型链表 + if (v_info.type == STRUCTURE) + { + while (target_type != nullptr) + { + if (!strcmp(target_type->type_name_str, v_info.type_name_str)) + break; + target_type = target_type->p_next; + } + element_node = target_type->element_list_head; + } + + // 输出名称及类型 + char *out_name = nullptr; + variable_type_enum out_type = TYPE_UNKNOWN; + + do + { + size_t sub_element_count = 1; + // 分配名称空间 + if (v_info.type == STRUCTURE) + { + out_name = (char *)malloc(strlen(v_info.name_str) + strlen(element_node->element_info.name_str) + 10); + sub_element_count = element_node->element_info.element_count; + out_type = element_node->element_info.type; + } + else + { + out_name = (char *)malloc(strlen(v_info.name_str) + 10); + out_type = v_info.type; + } + + for (size_t sub_count = 0; sub_count < sub_element_count; sub_count++) + { + // 计算出现的最大对齐 + if (alignment_max < (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE)) + alignment_max = (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE); + + // 地址对齐 + if (addr_offset % (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE) != 0) + addr_offset += (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE) - (addr_offset % (type_size[out_type] < ADDR_ALIGNMENT_SIZE ? type_size[out_type] : ADDR_ALIGNMENT_SIZE)); + + // 拼接输出名称 + if (v_info.type == STRUCTURE) + { + if (v_info.element_count == 1) + { + if (sub_element_count == 1) + sprintf(out_name, "%s.%s", v_info.name_str, element_node->element_info.name_str); + else + sprintf(out_name, "%s.%s[%d]", v_info.name_str, element_node->element_info.name_str, sub_count); + } + else + { + if (sub_element_count == 1) + sprintf(out_name, "%s[%d].%s", v_info.name_str, count, element_node->element_info.name_str); + else + sprintf(out_name, "%s[%d].%s[%d]", v_info.name_str, count, element_node->element_info.name_str, sub_count); + } + } + else + { + if (v_info.element_count == 1) + sprintf(out_name, "%s", v_info.name_str); + else + sprintf(out_name, "%s[%d]", v_info.name_str, count); + } + + fprintf(output_middleware_file, "%s\r\n", "/begin MEASUREMENT"); // 观测量头 + fprintf(output_middleware_file, " /* Name */ %s\r\n", out_name); // 名称 + fprintf(output_middleware_file, " /* Long identifier */ \"Auto generated by SrcToA2L\"\r\n"); // 描述 + fprintf(output_middleware_file, " /* Data type */ %s\r\n", type_str[out_type]); // 数据类型 + fprintf(output_middleware_file, " /* Conversion method */ %s\r\n", "NO_COMPU_METHOD"); // 转换式(保留原始值) + fprintf(output_middleware_file, " /* Resolution (Not used) */ %s\r\n", "0"); // 分辨率 + fprintf(output_middleware_file, " /* Accuracy (Not used) */ %s\r\n", "0"); // 精度误差 + fprintf(output_middleware_file, " /* Lower limit */ %s\r\n", min_str[out_type]); // 下限 + fprintf(output_middleware_file, " /* Upper limit */ %s\r\n", max_str[out_type]); // 上限 + fprintf(output_middleware_file, " /* ECU Address */ %s 0x%08X\r\n", "ECU_ADDRESS", start_addr_32 + addr_offset); // ECU 地址 + fprintf(output_middleware_file, "%s\r\n\r\n", "/end MEASUREMENT"); // 观测量尾 + + // 递增地址偏移 + addr_offset += type_size[out_type]; + } + + free(out_name); + + if (element_node != nullptr) + element_node = element_node->p_next; + } while (element_node != nullptr); + + // 补齐结构体末尾的空余字节偏移 + if (v_info.type == STRUCTURE) + if (addr_offset % (alignment_max < ADDR_ALIGNMENT_SIZE ? alignment_max : ADDR_ALIGNMENT_SIZE) != 0) + addr_offset += (alignment_max < ADDR_ALIGNMENT_SIZE ? alignment_max : ADDR_ALIGNMENT_SIZE) - (addr_offset % (alignment_max < ADDR_ALIGNMENT_SIZE ? alignment_max : ADDR_ALIGNMENT_SIZE)); + } + + // 输出日志 + if (start_addr_32 != 0 || input_map_file == nullptr) + { + if (v_info.element_count > 1) + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_SUCCESS, "%-15s %-15s 0x%08X %s[%d]", "Measurement", type_str[v_info.type], start_addr_32, v_info.name_str, v_info.element_count); + else + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_SUCCESS, "%-15s %-15s 0x%08X %s", "Measurement", type_str[v_info.type], start_addr_32, v_info.name_str); + } + else + { + if (v_info.element_count > 1) + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_WARN, "%-15s %-15s 0x%08X %s[%d]", "Measurement", type_str[v_info.type], start_addr_32, v_info.name_str, v_info.element_count); + else + log_printf(v_info.type == TYPE_UNKNOWN ? LOG_FAILURE : LOG_WARN, "%-15s %-15s 0x%08X %s", "Measurement", type_str[v_info.type], start_addr_32, v_info.name_str); + } +} + +// End \ No newline at end of file