提交 94ca8eb9 authored 作者: unknown's avatar unknown

exe支持load、unload、start、stop操作,解析并根据flow和setting的配置运行dll中指定函数

上级 f7ba0954
差异被折叠。
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>g-ide</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.config.gnu.mingw.exe.debug.885581900" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorMinGW" console="false" env-hash="478340448230037831" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings MinGW" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="cdt.managedbuild.config.gnu.mingw.exe.release.2092947396" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorMinGW" console="false" env-hash="478340448230037831" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings MinGW" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>
eclipse.preferences.version=1
indexer/indexerId=org.eclipse.cdt.core.nullindexer
eclipse.preferences.version=1
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/CPATH/delimiter=;
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/CPATH/operation=remove
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/CPLUS_INCLUDE_PATH/delimiter=;
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/CPLUS_INCLUDE_PATH/operation=append
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/CPLUS_INCLUDE_PATH/value=D\:\\BaiduNetdiskDownload\\develop\\eclipse\\gdriver\\include
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/C_INCLUDE_PATH/delimiter=;
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/C_INCLUDE_PATH/operation=remove
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/append=true
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/appendContributed=true
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/LIBRARY_PATH/delimiter=;
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/LIBRARY_PATH/operation=remove
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/append=true
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.885581900/appendContributed=true
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include utils/subdir.mk
-include src/subdir.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(CC_DEPS)),)
-include $(CC_DEPS)
endif
ifneq ($(strip $(C++_DEPS)),)
-include $(C++_DEPS)
endif
ifneq ($(strip $(C_UPPER_DEPS)),)
-include $(C_UPPER_DEPS)
endif
ifneq ($(strip $(CXX_DEPS)),)
-include $(CXX_DEPS)
endif
ifneq ($(strip $(CPP_DEPS)),)
-include $(CPP_DEPS)
endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: g-ide.exe
# Tool invocations
g-ide.exe: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: MinGW C++ Linker'
g++ -o "g-ide.exe" $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building target: $@'
@echo ' '
# Other Targets
clean:
-$(RM) $(CC_DEPS)$(C++_DEPS)$(EXECUTABLES)$(OBJS)$(C_UPPER_DEPS)$(CXX_DEPS)$(CPP_DEPS)$(C_DEPS) g-ide.exe
-@echo ' '
.PHONY: all clean dependents
-include ../makefile.targets
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS := -lstdc++fs
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
C_UPPER_SRCS :=
CXX_SRCS :=
C++_SRCS :=
OBJ_SRCS :=
CC_SRCS :=
ASM_SRCS :=
CPP_SRCS :=
C_SRCS :=
S_UPPER_SRCS :=
O_SRCS :=
CC_DEPS :=
C++_DEPS :=
EXECUTABLES :=
OBJS :=
C_UPPER_DEPS :=
CXX_DEPS :=
CPP_DEPS :=
C_DEPS :=
# Every subdirectory with source files must be described here
SUBDIRS := \
src \
utils \
src/CommandParser.o: ../src/CommandParser.cpp ../src/CommandParser.h \
../src/../utils/DriverCommon.h ../src/../utils/CommonStruct.h \
../src/../utils/json.hpp ../src/../utils/PrintHelper.cpp \
../src/../utils/ErrorType.h
../src/CommandParser.h:
../src/../utils/DriverCommon.h:
../src/../utils/CommonStruct.h:
../src/../utils/json.hpp:
../src/../utils/PrintHelper.cpp:
../src/../utils/ErrorType.h:
src/driver.o: ../src/driver.cpp ../src/driver.h ../src/../utils/json.hpp \
../src/CommandParser.h ../src/../utils/DriverCommon.h \
../src/../utils/CommonStruct.h ../src/../utils/json.hpp \
../src/../utils/PrintHelper.cpp ../src/../utils/ErrorType.h
../src/driver.h:
../src/../utils/json.hpp:
../src/CommandParser.h:
../src/../utils/DriverCommon.h:
../src/../utils/CommonStruct.h:
../src/../utils/json.hpp:
../src/../utils/PrintHelper.cpp:
../src/../utils/ErrorType.h:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
../src/CommandParser.cpp \
../src/driver.cpp
OBJS += \
./src/CommandParser.o \
./src/driver.o
CPP_DEPS += \
./src/CommandParser.d \
./src/driver.d
# Each subdirectory must supply rules for building sources it contributes
src/%.o: ../src/%.cpp
@echo 'Building file: $<'
@echo 'Invoking: GCC C++ Compiler'
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++17 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
utils/DriverCommon.o: ../utils/DriverCommon.cpp ../utils/DriverCommon.h \
../utils/CommonStruct.h ../utils/json.hpp
../utils/DriverCommon.h:
../utils/CommonStruct.h:
../utils/json.hpp:
utils/PrintHelper.o: ../utils/PrintHelper.cpp
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
../utils/DriverCommon.cpp \
../utils/PrintHelper.cpp
OBJS += \
./utils/DriverCommon.o \
./utils/PrintHelper.o
CPP_DEPS += \
./utils/DriverCommon.d \
./utils/PrintHelper.d
# Each subdirectory must supply rules for building sources it contributes
utils/%.o: ../utils/%.cpp
@echo 'Building file: $<'
@echo 'Invoking: GCC C++ Compiler'
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++17 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
/*
* CommandParser.cpp
*
* Created on: Mar 4, 2025
* Author: ZhangChundi
*/
#include "CommandParser.h"
#include <thread>
const std::string EMPTY = "";
// 初始化变量
HINSTANCE hLib = nullptr;
// 控制函数在运行的时候,如果用户点击了停止,则退出函数调用
bool exitFunc = false;
////////////////////初始化和定义命令///////////////////
CommandParser::CommandParser(DriverCommon common) :
common(common) {
// 注册合法命令(后续加新命令直接往这里append就行)
validCommands = { "gk -p load", "gk -p unload", "gk -p run", "gk -p stop" };
}
CommandType CommandParser::string2command(const std::string &cmd) {
if (cmd == validCommands[0])
return LOAD;
if (cmd == validCommands[1])
return UNLOAD;
if (cmd == validCommands[2])
return RUN;
if (cmd == validCommands[3])
return STOP;
return UNKNOWN;
}
///////////////////////解析命令/////////////////////
/**
* 解析用户输入的命令然后封装到ParsedCommand对象里面
*/
bool CommandParser::parse(const std::string &input,
ParsedCommand &result) const {
static const std::regex cmdRegex(R"(^\d+\^gk\s-\w+\s\w+(\s.*)?$)");
if (!std::regex_match(input, cmdRegex)) {
std::cerr << "Invalid command: " << input << std::endl;
return false;
}
// 分割序号和命令体
size_t splitPos = input.find('^');
if (splitPos == std::string::npos) {
return false;
}
result.number = input.substr(0, splitPos);
std::string commandPart = input.substr(splitPos + 1);
// 拆词
std::istringstream iss(commandPart);
std::vector<std::string> tokens;
std::string token;
while (iss >> token) {
tokens.push_back(token);
}
if (tokens.size() < 3) {
std::cerr << "Command format is error: " << commandPart << std::endl;
return false;
}
result.fullCommand = tokens[0] + " " + tokens[1] + " " + tokens[2];
for (size_t i = 3; i < tokens.size(); ++i) {
result.args.push_back(tokens[i]);
}
return true;
}
bool CommandParser::isValidCommand(const std::string &cmd) const {
if (std::find(validCommands.begin(), validCommands.end(), cmd)
!= validCommands.end()) {
// 找到了
return true;
} else {
return false;
}
}
/**
* 命令目前不对,加载、卸载、运行、停止几条
* 1.解析命令结构,管道返回命令序号
* 2.加载DLL
* 3.解析Flow文件然后调用函数、再把对象通过测试流程末尾函数传回
* @parameter command 客户端写入到管道的字符串解析生成的命令对象
*/
int CommandParser::handleCommand(ParsedCommand &command) {
int isSuccess = ErrorType::TYPE_SUCCESS;
std::string &commandHeader = command.fullCommand;
switch (string2command(commandHeader)) {
case LOAD:
isSuccess = loadDll(command.args);
break;
case UNLOAD:
//{
// PrjExit prjExit = (PrjExit) GetProcAddress(
// hLib, "prj_exit");
// if (!prjExit) {
// return ErrorType::LOSE_PRJ_EXIT_FUNCTION;
// }
// prjExit();
//}
// 释放DLL
FreeLibrary(hLib);
dllFilePath = EMPTY;
break;
case RUN:
// 运行函数的时候需要开启一个线程,如果用户发送停止命令则停止运行
isSuccess = runDll(command);
break;
case STOP:
// 如果用户发送停止命令则退出函数调用
isSuccess = stopDll();
break;
default:
break;
}
return isSuccess;
}
///////////////////////命令业务/////////////////////
/**
* 加载测试工程编译出的DLL文件
* TODO 可能还要传递一个Header和Execute Mode的信息
*/
int CommandParser::loadDll(const std::vector<std::string> args) {
// 两个参数,一个DLL路径,一个Flow文件路径
if (args.size() != 2) {
return ErrorType::TYPE_THE_COMMAND_PARAMETER_WAS_ERROR;
}
std::string dllName = args[0];
auto result = common.analysisFlowFile(args[1]);
if (!result) {
//printErr("Flow file not exist.");
return ErrorType::TYPE_FLOW_FILE_OR_FORMAT_EXIST_ERROR;
} else {
flowMessage = *result; // 取出真正的对象
}
// gk -p load D:/develop/eclipse/runtime-develop.ui.product/testc/build/testc.dll
// 1^gk -p load D:/develop/eclipse/runtime-develop.ui.product/gsignaldefine/Debug/libgsignaldefine.dll
dllFilePath = dllName;
if (dllFilePath == EMPTY) {
//printString("Please load G-Project first.");
return ErrorType::TYPE_PLEASE_LOAD_G_PROJECT_FIRST;
}
// 加载动态库并执行
hLib = LoadLibrary(dllFilePath.c_str());
if (hLib == NULL) {
DWORD err = GetLastError();
std::cout << err << std::endl;
//printString("LoadLibrary was failed.");
return ErrorType::TYPE_LOAD_LIBRARY_WAS_FAILED;
}
// 调用Prj_init函数
PrjInit prjInit = (PrjInit) GetProcAddress(
hLib, "prj_init");
if (!prjInit) {
return ErrorType::LOSE_PRJ_INIT_FUNCTION;
}
prjInit();
return ErrorType::TYPE_SUCCESS;
}
//////////////////////////////////////////
void CommandParser::executeAllFunc(const Configure& configure) {
// 有一个循环前先执行的函数,每次循环最先执行,固定函数名、返回值类型和参数
FlowMessage flowMessage = configure.flowMessage;
std::vector<TestItem> testItems = flowMessage.testItems;
for(TestItem testItem : testItems) {
// 如果没有勾选执行则跳过
if (!testItem.select) {
continue;
}
std::string funcName = testItem.funcName;
FunctionTypeStr sharedFunction = (FunctionTypeStr) GetProcAddress(
hLib, funcName.c_str());
if (!sharedFunction) {
std::cerr << "Failed to get function address" << std::endl;
continue;
}
bool result = sharedFunction(configure);
Setting setting = configure.setting;
ExecuteSetting executeSetting = setting.executeSetting;
if (executeSetting.failstop && !result) {
break;
}
}
}
// 每次接收到运行指令都将执行条件设置为false
void CommandParser::executeLoopAllFunc(const Configure& configure, const std::string number) {
exitFunc = false;
DUTSetting dutSetting = configure.setting.dutSetting;
ExecuteSetting executeSetting = configure.setting.executeSetting;
int loop = executeSetting.loopcount;
if (loop == 0) {
// 所有函数一直执行,知道用户点击了Stop
while(!exitFunc) {
bool isOk = callFuncs(configure, dutSetting);
if (!isOk) {
break;
}
}
} else {
int loop = executeSetting.loopcount;
for (int i = 0; i < loop; i++) {
if (exitFunc) {
break;
}
bool isOk = callFuncs(configure, dutSetting);
if (!isOk) {
break;
}
}
// 有一个循环前后执行的函数,每次循环最后执行,固定函数名、返回值类型和参数
}
// TODO 函数执行结束,告诉调用者
printString(number, '^', "execute done");
}
/**
* 运行测试工程中的函数
*/
int CommandParser::runDll(ParsedCommand &command) {
const std::vector<std::string> args = command.args;
if (args.size() != 1) {
return ErrorType::TYPE_THE_COMMAND_PARAMETER_WAS_ERROR;
}
// 解析运行条件
auto settingOptional = common.analysisSettingFile(args[0]);
if (!settingOptional) {
//printErr("Setting file not exist.");
return ErrorType::TYPE_SETTING_FILE_OR_FORMAT_EXIST_ERROR;
} else {
setting = *settingOptional; // 取出真正的对象
}
// 拿到所有函数,目前函数返回值类型都是boolean,参数只有一个FlowMessage类型
// 有一个最先执行的函数,只执行一次,固定函数名、返回值类型和参数
std::string commandNumber = command.number;
std::thread([this, commandNumber]() {
Configure configure(flowMessage, this->setting);
this->executeLoopAllFunc(configure, commandNumber);
}).detach();
std::cout << "executeLoop execute" << std::endl;
// 有一个最后执行的函数,只执行一次,固定函数名、返回值类型和参数
return ErrorType::TYPE_SUCCESS;
}
int CommandParser::stopDll() {
// 只有在退出条件是false的情况下才修改为true
exitFunc = true;
return ErrorType::TYPE_SUCCESS;
}
int CommandParser::testStart(const DUTSetting &dutSetting) {
TestStart start = (TestStart) GetProcAddress(
hLib, "test_start");
if (!start) {
return ErrorType::LOSE_TEST_START_FUNCTION;
}
start(dutSetting);
return ErrorType::TYPE_SUCCESS;
}
int CommandParser::testEnd() {
TestEnd end = (TestEnd) GetProcAddress(
hLib, "test_end");
if (!end) {
return ErrorType::LOSE_TEST_END_FUNCTION;
}
end();
return ErrorType::TYPE_SUCCESS;
}
bool CommandParser::callFuncs(const Configure& configure, const DUTSetting &dutSetting) {
int errorCode = testStart(dutSetting);
if (errorCode != ErrorType::TYPE_SUCCESS){
return false;
}
executeAllFunc(configure);
errorCode = testEnd();
if (errorCode != ErrorType::TYPE_SUCCESS){
return false;
}
return true;
}
//////////////////////命令业务结束////////////////////
/*
* CommandParser.h
*
* Created on: Mar 4, 2025
* Author: ZhangChundi
*/
#ifndef COMMANDPARSER_H_
#define COMMANDPARSER_H_
#include <string>
#include <vector>
#include <unordered_set>
#include <regex>
#include <iostream>
#include "../utils/DriverCommon.h"
#include "../utils/PrintHelper.cpp"
#include "../utils/ErrorType.h"
#include <windows.h>
// IDE发来的命令解析后的结果
struct ParsedCommand {
std::string number;
std::string fullCommand;
std::vector<std::string> args;
};
enum CommandType { LOAD, UNLOAD, RUN, STOP, UNKNOWN };
/** 动态调用测试工程中的测试项函数 */
typedef bool (*FunctionTypeStr)(const Configure);
/** 测试工程加载调用 */
typedef bool (*PrjInit)(void);
/** 测试工程卸载调用 */
//typedef bool (*PrjExit)(void);
/** 测试工程所有测试项每次被调用前调用 */
typedef bool (*TestStart)(const DUTSetting);
/** 测试工程所有测试项每次被调用结束后调用 */
typedef bool (*TestEnd)(void);
// 命令解析器
class CommandParser {
private:
// Parameter
DriverCommon common;
FlowMessage flowMessage;
Setting setting;
std::string dllFilePath;
std::vector<std::string> validCommands;
bool callFuncs(const Configure& configure, const DUTSetting &dutSetting);
void executeLoopAllFunc(const Configure& configure, const std::string number);
void executeAllFunc(const Configure& configure);
int runDll(ParsedCommand &command);
int stopDll();
int loadDll(const std::vector<std::string> args);
CommandType string2command(const std::string& cmd);
int testStart(const DUTSetting &dutSetting);
int testEnd();
public:
// Method
CommandParser(DriverCommon common);
bool parse(const std::string& input, ParsedCommand& result) const;
bool isValidCommand(const std::string& cmd) const;
int handleCommand(ParsedCommand& command);
};
#endif /* COMMANDPARSER_H_ */
//============================================================================
// Name : driver.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C, Ansi-style
//============================================================================
// driver.h (exe project)
#include "driver.h"
#include "../utils/json.hpp"
#include "CommandParser.h"
// 常量字符串
const char COMMAND_MARK = '^';
const string EXIT_MARK = "exit";
const string SUCCESS_STR = "done";
const string FAIL_STR = "error";
DriverCommon common;
CommandParser parser(common);
int main(){
int process = 0;
while(true) {
Sleep(100);
process += 10;
cout << "[process:" << process << "]" <<endl;
if (process == 100){
break;
}
}
cout << "input 'exit' exit process." << endl;
string input;
// 1^gk -p load <parameter>
while (true) {
// 读取整行输入,包括空格
std::getline(std::cin, input);
// 检查退出条件
if (input == EXIT_MARK) {
break;
}
if (input == "") {
continue;
}
// 认为是命令,处理命令并反馈结果
ParsedCommand cmd;
if (parser.parse(input, cmd)) {
if (!parser.isValidCommand(cmd.fullCommand)) {
std::cerr << "Unknown command: " << cmd.fullCommand << std::endl;
continue;
}
int isSuccess = parser.handleCommand(cmd);
// 反馈结果
if (isSuccess == 0) {
printString(cmd.number, COMMAND_MARK, SUCCESS_STR);
} else {
printString(cmd.number, COMMAND_MARK, FAIL_STR,
",", "error info=", std::to_string(isSuccess));
}
} else {
// 命令输入错误
std::cerr << "Command format is error." << std::endl;
}
}
return 0;
}
/*
* driver.h
*/
#ifdef BUILD_driver
#define driverAPI __declspec(dllexport)
#else
#define driverAPI __declspec(dllimport)
#endif
// 打开这个,才会真正打印
#define ENABLE_CONTAINER_PRINT
#include <thread>
#include <iostream>
#include <string>
#include <windows.h>
#include <iostream>
using namespace std;
/*
* CommonStruct.h
*
* Created on: Mar 6, 2025
* Author: ZhangChundi
*/
#ifndef COMMONSTRUCT_H_
#define COMMONSTRUCT_H_
#include "json.hpp"
// 解析flow文件,flow文件是json格式
struct Level {
std::string clampHi;
std::string clampLow;
std::string iOH;
std::string iOL;
std::string vIH;
std::string vIL;
std::string vOH;
std::string vOL;
std::string vT;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Level, clampHi, clampLow, iOH, iOL, vIH, vIL,
vOH, vOL, vT)
struct Result {
std::string max;
std::string min;
int paramId;
std::string paramName;
std::string unit;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Result, max, min, paramId, paramName, unit)
struct TestItem {
std::string failJump;
std::string flag;
std::string funcDesc;
int funcId;
std::string funcName;
int hbin;
Level level;
int loop;
std::string passJump;
std::string pattern;
std::vector<Result> results;
int sbin;
bool select;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TestItem, failJump, flag, funcDesc, funcId,
funcName, hbin, level, loop, passJump, pattern, results, sbin, select)
struct FlowMessage {
std::vector<TestItem> testItems;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(FlowMessage, testItems)
// 解析设置文件,通常在测试工程的.setting/目录下
struct ExecuteSetting {
bool failstop = false;
int loopcount = 1;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ExecuteSetting, failstop, loopcount);
struct DUTSetting {
std::vector<std::string> selectDUT;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(DUTSetting, selectDUT);
struct Setting {
ExecuteSetting executeSetting;
DUTSetting dutSetting;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Setting, executeSetting, dutSetting);
struct Configure {
FlowMessage flowMessage;
Setting setting;
Configure(FlowMessage& flowMessage, Setting& setting)
: flowMessage(flowMessage), setting(setting) {}
};
class CommonStruct {
public:
CommonStruct();
virtual ~CommonStruct();
};
#endif /* COMMONSTRUCT_H_ */
/*
* DriverCommon.cpp
*
* Created on: 2024年11月1日
* Author: ZhangChundi
*/
#include "DriverCommon.h"
DriverCommon::DriverCommon() {
// TODO Auto-generated constructor stub
}
DriverCommon::~DriverCommon() {
// TODO Auto-generated destructor stub
}
std::vector<std::string> DriverCommon::split(const std::string &str,
char delimiter) {
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while (std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
// 如果字符串以分隔符结尾,则最后一个空字符串会被添加到tokens中,需要去除
if (!tokens.empty() && tokens.back().empty()) {
tokens.pop_back();
}
return tokens;
}
std::optional<FlowMessage> DriverCommon::analysisFlowFile(std::string filePath) {
if (!fileExists(filePath)){
return std::nullopt;
}
std::ifstream file(filePath);
if (!file.is_open()) {
std::cerr << "Failed to open file!" << std::endl;
std::runtime_error("Failed to open file: " + filePath);
}
nlohmann::json j;
file >> j;
FlowMessage config = j.get<FlowMessage>();
// 简单打印测试
for (const auto& item : config.testItems) {
std::cout << "FuncName: " << item.funcName << ", FuncId: " << item.funcId << std::endl;
for (const auto& result : item.results) {
std::cout << " Result Param: " << result.paramName << ", Max: " << result.max << std::endl;
}
}
return config;
}
std::optional<Setting> DriverCommon::analysisSettingFile(std::string filePath) {
if (!fileExists(filePath)){
return std::nullopt;
}
std::ifstream file(filePath);
if (!file.is_open()) {
std::cerr << "Failed to open file!" << std::endl;
std::runtime_error("Failed to open file: " + filePath);
}
nlohmann::json j;
file >> j;
Setting config = j.get<Setting>();
return config;
}
bool DriverCommon::fileExists(const std::string& path) {
return std::filesystem::exists(path);
}
/*
* DriverCommon.h
*
* Created on: 2024年11月1日
* Author: ZhangChundi
*/
#ifndef SRC_DRIVERCOMMON_H_
#define SRC_DRIVERCOMMON_H_
#include <iostream>
#include <sstream>
#include <fstream>
#include <filesystem>
#include <string>
#include <vector>
#include "CommonStruct.h"
/**
* 通用函数,文件解析,字符串处理
*/
class DriverCommon {
public:
DriverCommon();
std::vector<std::string> split(const std::string& str, char delimiter);
std::optional<FlowMessage> analysisFlowFile(std::string filePath);
std::optional<Setting> analysisSettingFile(std::string filePath);
bool fileExists(const std::string& path);
virtual ~DriverCommon();
};
#endif /* SRC_DRIVERCOMMON_H_ */
/*
* ErrorType.h
*
* Created on: Mar 26, 2025
* Author: admin
*/
#ifndef ERRORTPYE_H_
#define ERRORTPYE_H_
enum ErrorType {
// common error
TYPE_SUCCESS=0x00000000, // 成功时返回
TYPE_THE_COMMAND_PARAMETER_WAS_ERROR=0x00000001, // 命令参数错误
TYPE_PLEASE_LOAD_G_PROJECT_FIRST=0x00000002, // 没有加载测试工程提示
TYPE_LOAD_LIBRARY_WAS_FAILED=0x00000003, // 加载dll失败
LOSE_PRJ_INIT_FUNCTION=0x00000004, // 丢失prj_init函数
LOSE_PRJ_EXIT_FUNCTION=0x00000005, // 丢失pro_exit函数
LOSE_TEST_START_FUNCTION=0x00000006, // 丢失test_start函数
LOSE_TEST_END_FUNCTION=0x00000007, // 丢失test_stop函数
// file not found
TYPE_FLOW_FILE_OR_FORMAT_EXIST_ERROR=0x00001001, // 参数是Flow文件,但是路径错误
TYPE_SETTING_FILE_OR_FORMAT_EXIST_ERROR=0x00001002, // 参数是Setting文件,但是路径错误
};
#endif /* ERRORTPYE_H_ */
/*
* PrintHelper.cpp
*
* Created on: Mar 4, 2025
* Author: ZhangChundi
*/
#include <iostream>
#include <sstream>
#include <vector>
#include <array>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <list>
#include <deque>
// 控制开关,DEBUG模式下打开,RELEASE模式下关闭
#ifdef ENABLE_CONTAINER_PRINT
#define PRINT_CONTAINER(container) printContainer(container)
#define PRINT_MAP(map) printMap(map)
#else
#define PRINT_CONTAINER(container)
#define PRINT_MAP(map)
#endif
template<typename... Args>
void printString(Args&&... args) {
std::ostringstream oss;
//(oss << ... << args); // C++17折叠表达式,把参数一个个拼起来
int dummy[] = {0, (oss << args, 0)...}; // 用逗号表达式展开参数
(void)dummy; // 避免未使用变量的警告
std::cout << oss.str() << std::endl;
};
template<typename... ArgsErr>
void printErr(ArgsErr&&... args) {
std::ostringstream oss;
//(oss << ... << args); // C++17折叠表达式,把参数一个个拼起来
int dummy[] = {0, (oss << args, 0)...}; // 用逗号表达式展开参数
(void)dummy; // 避免未使用变量的警告
std::cerr << oss.str() << std::endl;
};
// 通用容器打印,适合vector/array/set/list/deque
template<typename Container>
void printContainer(const Container& container, const std::string& name = "container") {
std::cout << name << " = [";
bool first = true;
for (const auto& item : container) {
if (!first) std::cout << ", ";
std::cout << item;
first = false;
}
std::cout << "]" << std::endl;
}
// 专门打印map和unordered_map
template<typename MapType>
void printMap(const MapType& m, const std::string& name = "map") {
std::cout << name << " = {" << std::endl;
for (const auto& pair : m) {
std::cout << " " << pair.first << ": " << pair.second << "," << std::endl;
}
std::cout << "}" << std::endl;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论