SNOOPerToCSV/Src/Main.cpp

483 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Tool_Functions.hpp"
#include "Global_Variables.hpp"
extern "C"
{
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdint.h"
#include "ctype.h"
}
int main(int argc, char *argv[])
{
// 处理指令输入
for (int count = 1; count < argc; count++)
{
// 处理时间戳
if (!strcmp(argv[count], "-t"))
{
// 参数不足
if ((count + 1) >= argc)
{
printf("Warning: missing timestamp parameter,set to default (0.00s).\n");
continue;
}
// 非法输入
if (!((argv[count + 1][0] == '-' && isdigit(argv[count + 1][1])) || (isdigit(argv[count + 1][0]))))
{
printf("Warning: invalid timestamp parameter \"%s\",set to default (0.00s).\n", argv[count + 1]);
count++;
continue;
}
// 读取时间戳起始
count++;
sscanf(argv[count], "%lf", &time_begin);
printf("Timestamp begin: %lf(s).\n", time_begin);
continue;
}
// 处理格式串指令
if (!strcmp(argv[count], "-f"))
{
// 参数不足
if ((count + 2) >= argc)
{
printf("Warning: missing format parameters,skip.\n");
continue;
}
// 非法输入参数1
if (argv[count + 1][0] == '-')
{
printf("Warning: invalid format parameters \"%s %s\",skip.\n", argv[count + 1], argv[count + 2]);
continue;
}
// 非法输入参数2
if (argv[count + 2][0] == '-')
{
printf("Warning: invalid format parameters \"%s %s\",skip.\n", argv[count + 1], argv[count + 2]);
count++;
continue;
}
// 非法的类型输入
if (!(!strcmp(argv[count + 2], "uint") ||
!strcmp(argv[count + 2], "ubyte") ||
!strcmp(argv[count + 2], "uint8_t") ||
!strcmp(argv[count + 2], "uint16_t") ||
!strcmp(argv[count + 2], "uint32_t") ||
!strcmp(argv[count + 2], "uint64_t") ||
!strcmp(argv[count + 2], "int") ||
!strcmp(argv[count + 2], "sbyte") ||
!strcmp(argv[count + 2], "int8_t") ||
!strcmp(argv[count + 2], "int16_t") ||
!strcmp(argv[count + 2], "int32_t") ||
!strcmp(argv[count + 2], "int64_t") ||
!strcmp(argv[count + 2], "float") ||
!strcmp(argv[count + 2], "double")))
{
printf("Warning: invalid format type \"%s\",skip.\n", argv[count + 2]);
count += 2;
continue;
}
// 添加到类型列表中
{
char *p_param = argv[count + 1];
int param_len = strlen(argv[count + 1]);
format_list_node *target_format_node = nullptr;
while (p_param - argv[count + 1] < param_len)
{
// 分配空间
if (format_list_head == nullptr)
{
format_list_head = (format_list_node *)malloc(sizeof(format_list_node));
format_list_head->p_next = nullptr;
format_list_head->target_numID = -1;
memset(format_list_head->target_value_name_str, '\0', sizeof(format_list_head->target_value_name_str));
format_list_head->value_type_str = DEFAULT_VALUE_TYPE;
target_format_node = format_list_head;
}
else
{
target_format_node->p_next = (format_list_node *)malloc(sizeof(format_list_node));
target_format_node = target_format_node->p_next;
target_format_node->p_next = nullptr;
target_format_node->target_numID = -1;
memset(target_format_node->target_value_name_str, '\0', sizeof(target_format_node->target_value_name_str));
target_format_node->value_type_str = DEFAULT_VALUE_TYPE;
}
char value_identification[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'};
size_t id_count = 0;
while (p_param - argv[count + 1] < param_len)
{
value_identification[id_count++] = *p_param;
if (p_param[1] == ',')
{
p_param += 2;
break;
}
p_param++;
}
// 判定名称orID顺序
if (is_full_num(value_identification))
target_format_node->target_numID = str_to_value(value_identification);
else
sprintf(target_format_node->target_value_name_str, value_identification);
target_format_node->value_type_str = argv[count + 2];
}
}
count += 2;
continue;
}
// 其余输入作为文件输入
{
// 判定文件是否可以打开
FILE *tempfile = fopen(argv[count], "rb");
if (tempfile != nullptr)
{
static file_node *target_node = nullptr;
if (file_list_head == nullptr)
{
file_list_head = (file_node *)malloc(sizeof(file_node));
file_list_head->file_name_str = nullptr;
file_list_head->p_next = nullptr;
target_node = file_list_head;
}
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;
}
target_node->file_name_str = argv[count];
printf("File: \"%s\" open succeed.\n", argv[count]);
}
else
printf("File: \"%s\" open failed.\n", argv[count]);
fclose(tempfile);
}
}
printf("\n\n");
// 遍历文件
file_node *target_file_node = file_list_head;
while (target_file_node != nullptr)
{
double timestamp = time_begin;
// 打开相关文件
FILE *input_file = nullptr;
FILE *output_file = nullptr;
input_file = fopen(target_file_node->file_name_str, "rb");
{
// 分配输出文件名空间
size_t buffer_len = strlen(target_file_node->file_name_str) + 10;
char *buffer = (char *)malloc(buffer_len);
memset(buffer, '\0', buffer_len);
// 处理输出名称
{
sprintf(buffer, "%s", target_file_node->file_name_str);
char *p_file_extension = buffer + strlen(buffer);
// 退格到文件扩展名后方
while (p_file_extension != buffer && *p_file_extension != '.')
p_file_extension--;
// 无扩展名文件
if (p_file_extension == buffer)
sprintf(buffer + strlen(buffer), ".csv");
else
sprintf(p_file_extension, ".csv");
}
// 打开输出文件并释放输出空间
output_file = fopen(buffer, "wb");
free(buffer);
}
if (input_file == nullptr || output_file == nullptr)
{
target_file_node = target_file_node->p_next;
continue;
}
printf("Solving file: \"%s\"\n", target_file_node->file_name_str);
printf("----------------------------------------------------------------\n");
printf("%-40s %-16s %s\n", "Value Name", "Out Type", "ID");
printf("----------------------------------------------------------------\n");
char segment_buffer[SEGMENT_BUFF_LENGTH] = {'\0'};
size_t total_line;
// 跳过非数据行
while (true)
{
f_getline(input_file, segment_buffer, sizeof(segment_buffer));
if (segment_buffer[0] == '-')
{
sscanf(segment_buffer + 1, "%zu", &total_line);
f_seek_pre_line_begin(input_file);
break;
}
}
// 处理首行数据
{
// 分配数值链表节点
value_list_head = (value_node *)malloc(sizeof(value_node));
value_list_head->p_next = nullptr;
value_list_head->value_type_str = DEFAULT_VALUE_TYPE;
value_list_head->raw_value = 0x0000000000000000;
memset(value_list_head->value_name_str, '\0', sizeof(value_list_head->value_name_str));
char value_name_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'};
char value_str[100] = {'\0'};
char time_str[100] = {'\0'};
f_getline(input_file, segment_buffer, sizeof(segment_buffer));
// -0000475879| 0| D:FE49E582 snoop 0000 .l\Dip_SignalGet_MotCurrent+0x2 66.903us
sscanf(segment_buffer, "%*s%*s%*s%*s%s%s%s", value_str, value_name_str, time_str);
// 记录首个节点信息
strcpy(value_list_head->value_name_str, value_name_str);
value_list_head->raw_value = hex_to_value(value_str);
}
// 处理第一个数值循环记录
{
value_node *target_value_node = value_list_head;
while (true)
{
char value_name_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'};
char value_str[100] = {'\0'};
char time_str[100] = {'\0'};
// 获取行
memset(segment_buffer, '\0', sizeof(segment_buffer));
f_getline(input_file, segment_buffer, sizeof(segment_buffer));
sscanf(segment_buffer, "%*s%*s%*s%*s%s%s%s", value_str, value_name_str, time_str);
// 完成回环
if (!strcmp(value_name_str, value_list_head->value_name_str))
{
// 回转到文件的数据行起始位置
memset(segment_buffer, '\0', sizeof(segment_buffer));
fseek(input_file, 0, SEEK_SET);
// 跳过非数据行
while (true)
{
f_getline(input_file, segment_buffer, sizeof(segment_buffer));
if (segment_buffer[0] == '-')
{
sscanf(segment_buffer + 1, "%zu", &total_line);
f_seek_pre_line_begin(input_file);
break;
}
}
break;
}
// 未完成回环,分配数值链表节点
target_value_node->p_next = (value_node *)malloc(sizeof(value_node));
target_value_node = target_value_node->p_next;
target_value_node->p_next = nullptr;
target_value_node->value_type_str = DEFAULT_VALUE_TYPE;
target_value_node->raw_value = 0x0000000000000000;
memset(target_value_node->value_name_str, '\0', sizeof(target_value_node->value_name_str));
// 记录节点信息
strcpy(target_value_node->value_name_str, value_name_str);
target_value_node->raw_value = hex_to_value(value_str);
}
}
// 展示数据类型输出及类型匹配
{
value_node *target_value_node = value_list_head;
int value_count = 0;
while (target_value_node != nullptr)
{
// 查找是否由对应的类型列表
{
format_list_node *target_format_node = format_list_head;
while (target_format_node != nullptr)
{
// 检查对应的名称(宽松匹配)
if ((target_format_node->target_value_name_str[0] != '\0') && (strstr(target_value_node->value_name_str, target_format_node->target_value_name_str) != nullptr))
{
target_value_node->value_type_str = target_format_node->value_type_str;
break;
}
else if (value_count == target_format_node->target_numID)
{
// 数字ID仅生效一次随后记录名称以适配批量处理文件时指定格式
sprintf(target_format_node->target_value_name_str, target_value_node->value_name_str);
target_format_node->target_numID = -1;
target_value_node->value_type_str = target_format_node->value_type_str;
break;
}
target_format_node = target_format_node->p_next;
}
// 一些预先标识的变量
if (strstr(target_value_node->value_name_str, "wmrmeasured_speed") ||
strstr(target_value_node->value_name_str, "wmrcontrol_signal") ||
strstr(target_value_node->value_name_str, "tagetSpeed") ||
strstr(target_value_node->value_name_str, "WinUp_PID") ||
strstr(target_value_node->value_name_str, "WinDw_PID"))
{
target_value_node->value_type_str = "float";
}
}
printf("%-40s %-16s [%02d]\n", target_value_node->value_name_str, target_value_node->value_type_str, value_count++);
target_value_node = target_value_node->p_next;
}
}
// 输出csv抬头部分
{
value_node *target_value_node = value_list_head;
fprintf(output_file, "time");
while (target_value_node != nullptr)
{
fprintf(output_file, ",%s", target_value_node->value_name_str);
target_value_node = target_value_node->p_next;
}
fprintf(output_file, "\n");
}
// 循环处理数据
{
printf("----------------------------------------------------------------\n");
memset(segment_buffer, '\0', sizeof(segment_buffer));
size_t line_count = -1;
while (f_getline(input_file, segment_buffer, sizeof(segment_buffer)) != 0)
{
char value_name_str[VARIABLE_NAME_STR_LENGTH_MAX] = {'\0'};
char value_str[100] = {'\0'};
char time_str[100] = {'\0'};
sscanf(segment_buffer, "%*s%*s%*s%*s%s%s%s", value_str, value_name_str, time_str);
// 处理时间戳
{
double time = 0.0;
sscanf(time_str, "%lf", &time);
// 处理时间戳
if (strstr(time_str, "us"))
timestamp += time / (1000 * 1000);
else if (strstr(time_str, "ms"))
timestamp += time / (1000);
else if (strstr(time_str, "s"))
timestamp += time;
}
// 此处不能太频繁打印,否则影响速度
line_count++;
if ((line_count % 10000) == 0)
progress_print(line_count, total_line, true);
// 处理数值链表
value_node *target_value_node = value_list_head;
fprintf(output_file, "%lf", timestamp);
while (target_value_node != nullptr)
{
// 更新对应的值
if (!strcmp(value_name_str, target_value_node->value_name_str))
target_value_node->raw_value = hex_to_value(value_str);
// 按类型输出值
{
// int8_t sbyte
if (!strcmp(target_value_node->value_type_str, "sbyte") ||
!strcmp(target_value_node->value_type_str, "int8_t"))
{
int8_t *value = (int8_t *)&(target_value_node->raw_value);
fprintf(output_file, ",%d", *value);
}
// int16_t
else if (!strcmp(target_value_node->value_type_str, "int16_t"))
{
int16_t *value = (int16_t *)&(target_value_node->raw_value);
fprintf(output_file, ",%d", *value);
}
// int32_t int
else if (!strcmp(target_value_node->value_type_str, "int32_t"))
{
int32_t *value = (int32_t *)&(target_value_node->raw_value);
fprintf(output_file, ",%d", *value);
}
// int64_t
else if (!strcmp(target_value_node->value_type_str, "int64_t"))
{
int64_t *value = (int64_t *)&(target_value_node->raw_value);
fprintf(output_file, ",%lld", *value);
}
// float 类型
else if (!strcmp(target_value_node->value_type_str, "float"))
{
float *value = (float *)&(target_value_node->raw_value);
fprintf(output_file, ",%f", *value);
}
// double 类型
else if (!strcmp(target_value_node->value_type_str, "float"))
{
double *value = (double *)&(target_value_node->raw_value);
fprintf(output_file, ",%lf", *value);
}
// 其它类型全部按照uint输出
else
fprintf(output_file, ",%llu", target_value_node->raw_value);
}
target_value_node = target_value_node->p_next;
}
fprintf(output_file, "\n");
// 清理缓冲区
memset(segment_buffer, '\0', sizeof(segment_buffer));
}
progress_print(line_count, total_line, true);
printf("\n\n\n");
}
// 清理数据列表
if (value_list_head != nullptr)
{
value_node *target_value_node = value_list_head;
while (target_value_node->p_next != nullptr)
{
value_node *to_be_free = target_value_node;
target_value_node = target_value_node->p_next;
free(to_be_free);
}
free(target_value_node);
}
target_file_node = target_file_node->p_next;
fclose(input_file);
fclose(output_file);
}
return 0;
}